I'm developing a graphic software with GTK+ (gtkmm) and want to build a free hand drawing feature.
I connect to the signal_motion_notify_event
on a Gtk::EventBox
and set set_event_compression
to false
on the event box. I also set set_event_compression(false)
on the window containing the event box, but nothing seems to work. The program is not running so fluently that it would allow drawn trough lines, instead I get multiple single dots or short dashes.
I also tried using Gdk::Window::get_pointer(int,int,Gdk::ModifierType)
in an extra thread
, but this doesn't work either (no drawn through lines also).
Here is some example code to illustrate (I use Gtk::Image
-class to draw the a pixbuf):
Toolbox.cc
// eb means EventBox
Gtk::EventBox& eb = drawingWin->getEventBox();
eb.signal_motion_notify_event().connect(sigc::mem_fun(image, &Image::motionEvent));
DrawingWindow.cc
DrawingWindow::DrawingWindow(int x, int y) : area(x, y), background("/home/tux/Pictures/Arch_Linux_Wallpaper_by_james66.jpg")
{
// eb means EventBox
eb.get_window()->set_event_compression(false);
}
Image.cc
bool Image::motionEvent(_GdkEventMotion* event)
{
if(event)
{
mutex.lock();
//custom set_pixel function on Gdk::Pixbuf using guint8* Gdk::Pixbuf::get_pixels() const
this->set_pixel(event->x, event->y, 0x000000ff);
//updates the Gtk::Image by calling Gtk::Image::set(Glib::RefPtr<Gdk::Pixbuf>)
this->_udpate();
mutex.unlock();
}
}
In GIMP (the program GTK+ was originally written for) there are gaps between single points too, if the mouse is moved too quickly, which are filled with straight lines between the points.
In GTK+ and gtkmm there are Gdk::EventMask
s. These can be set with Gtk::Widget::set_events(Gdk::EventMask)
. One needs to make sure that POINTER_MOTION_MASK
is set (not POINTER_MOTION_HINT_MASK
).
One also needs to make sure, that event-compression is disabled. Until including GTK3 this could be done using Gdk::Window::set_event_compression(false)
In GTK4 event-compression is always turned on:
With GTK4 one needs to look at the event history between motion events to reconstruct the ones that where coalesced. In gtk4 event delivery rate is fixed to run by the frame clock (that is, 60hz).
get_motion_history()
(function name may have changed) will only return the motion coordinates that were accumulated during the handling of that frame.
Here are two examples:
All of these examples lack coherence (there are gaps between the lines).
It's not possible building choerent free hand drawing using GTK+ without interpolation!
There is also an example using Qt5, which is coherent: Qt5 Scribble
User contributions licensed under CC BY-SA 3.0