Как правильно реализовать перетаскивание объекта DrawingArea, встроенного в ScrolledWindow, с сохранением возможности обработки событий мыши?
Вот моя проблема.
у меня есть DrawingArea
вставлен в ScrolledWindow
. Эта область содержит настраиваемую графику, и я хочу, чтобы ее можно было масштабировать и перетаскивать. Я решил (вроде) масштабируемую часть. Чтобы решить перетаскиваемую часть, я реализовал этот код:
//how widgets are built
void buildWidgets(int spacing = 8) {
_scale = new Scale(Orientation.HORIZONTAL,0.1,2.0,0.01);
_scale.addOnValueChanged(&this.onScaleValueChanged);
_drawing = new DrawingArea();
_drawing.addOnDraw(&this.mainOnDrawEvent);
_scrolled = new ScrolledWindow(_drawing);
_scrolled.addOnButtonPress(&this.scrollingButtonPress);
_scrolled.addOnButtonRelease(&this.scrollingButtonRelease);
_scrolled.addOnMotionNotify(&this.scrollingMotionNotify);
this.packStart(_scale, false, false, spacing);
this.packStart(_scrolled, true, true, spacing);
}
//handle press
bool scrollingButtonPress(Event ev, Widget w) {
writefln ("Handling scroll event...");
if (ev.button.type == GdkEventType.BUTTON_PRESS && ev.button.button == BUTTON_PRIMARY) {
this.mouse_down = true;
this.prev_y = ev.button.y;
this.prev_pos_y = _scrolled.getVadjustment().getValue();
this.prev_x = ev.button.x;
this.prev_pos_x = _scrolled.getHadjustment().getValue();
}
return false;
}
//handle release
bool scrollingButtonRelease(Event ev, Widget w) {
this.mouse_down = false;
return false;
}
//handle drag
bool scrollingMotionNotify(Event ev, Widget w) {
if (this.mouse_down) {
immutable auto cur_y = ev.button.y;
immutable auto y_mov = this.prev_y - cur_y;
auto scroll_pos_y = this.prev_pos_y + y_mov;
_scrolled.getVadjustment().setValue(scroll_pos_y);
immutable auto cur_x = ev.button.x;
immutable auto x_mov = this.prev_x - cur_x;
auto scroll_pos_x = this.prev_pos_x + x_mov;
_scrolled.getHadjustment().setValue(scroll_pos_x);
}
return false;
}
Теперь, если я прикреплю эти события
_scrolled.addOnButtonPress(&this.scrollingButtonPress);
_scrolled.addOnButtonRelease(&this.scrollingButtonRelease);
_scrolled.addOnMotionNotify(&this.scrollingMotionNotify);
к ScrolledWindow
экземпляр все работает ок. Однако, если я прикреплюButtonPress
событие для _drawingArea
Я испортил механизм обработки событий и потерял возможность перетаскивания. Если я прикреплю события перетаскивания мыши к_drawing
DrawingArea вроде как работает, но все это нервно, а расстояние перетаскивания отличается от фактического расстояния мыши.
Как справиться с этой проблемой распространения событий?
Примеры даже на других языках (Python, Vala, C#, C) более чем приветствуются.