Как правильно реализовать перетаскивание объекта 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) более чем приветствуются.

0 ответов

Другие вопросы по тегам