|
|
Thank you for the responses. I am using "redraw".
Here is an example app:
#include <FL/Fl.H>
#include <FL/fl_draw.H>
class MainWindow: public Fl_Window {
public:
MainWindow(int width, int height, const char* title) : Fl_Window(width, height, title) {};
~MainWindow() {};
private:
int rectX = 0;
int rectY = 0;
int rectW = 1;
int rectH = 1;
protected:
void draw() {
// Clean screen
fl_rectf(0, 0, this->w(), this->h(), FL_BLACK);
// Draw box
fl_rectf(this->x() + this->rectX, this->y() + this->rectY, this->rectW, this->rectH, FL_WHITE);
}
int handle(int event) {
int x, y;
switch (event) {
case FL_PUSH:
x = Fl::event_x() - this->x();
y = Fl::event_y() - this->y();
this->rectX = x;
this->rectY = y;
this->rectW = 1;
this->rectH = 1;
this->redraw();
return 1;
case FL_DRAG:
x = Fl::event_x() - this->x();
y = Fl::event_y() - this->y();
this->rectW = x - this->rectX;
this->rectH = y - this->rectY;
this->redraw();
return 1;
default:
break;
}
return 0;
}
};
int main(int argc, char **argv) {
Fl::scheme("gtk+");
// Views
MainWindow *mainWindow = new MainWindow(Fl::w(), Fl::h(), "Test");
mainWindow->end();
mainWindow->show(argc, argv);
mainWindow->make_current();
return Fl::run();
}
On Tuesday, November 29, 2022 at 12:23:57 PM UTC+1 Matthias Melcher wrote:
tl;dr call "redraw()' in event handling and callback routines. Never call "draw()' directly. FLTK will call "draw()" for you when the time is right.
macOS can send a *lot* of DRAG and MOVE events. More than 60 events per second. It makes no sense to actually draw a widget every time an event occurs, and if the screen is sync locked, it generates a huge lag, because while the drawing code is waiting for the screen "flyback", more DRAG events are piling up. Then taking only the top DRAG event and waiting for the screen once more will increase the pile even more.
All MOVE and DRAG event, actually *all* events should be handled quickly. So for a DRAG event, all you do is fetch the coordinates and save them in the widget, and call "redraw()" on the widget, so the widget knows how to draw itself without referencing any events. "redraw()" is very fast. It tells FLTK, that some area wants to be redrawn, but doesn't draw anything at all. It pretty much just sets a flag.
So it doesn't really matter how many DRAG events you have piled up, "redraw()" only sets a flag over and over.
Now once the event queue is empty (simplified), FLTK checks which widgets want to be redrawn, and draws them all at once. Even though you may have handled 20 DRAG events during a single screen refresh, only the most recent event has an effect that will be drawn. That way, you can handle thousands of events per second without ever waiting for the screen, and without getting a lag.
Just for completeness, if you want to animate something, you do exactly the same. In the timer, all you do is call "redraw()". The widget must be able to draw itself based on the current time, not based on the timer event, because you never know how the slow the user's machine is. Events always run completely asynchronously from screen drawing.
Ian MacArthur schrieb am Dienstag, 29. November 2022 um 10:36:31 UTC+1:
On a related note, triggering a lot of redraws from within the handle method is unlikely to be "efficient" anyway, I suspect. But, as Matt says we might need to see a worked example of what you are actually doing here, to better illuminate the issues.
--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkgeneral/671f09bf-356d-42a7-b8c4-fa55193e60cdn%40googlegroups.com.
[ Direct Link to Message ] | |
|
| |