【问题标题】:FLTK: how to make widgets resizable by dragging?FLTK:如何通过拖动来调整小部件的大小?
【发布时间】:2017-08-30 21:48:42
【问题描述】:

在 FLTK 中,有没有办法让用户在运行时通过拖动小部件框的边框来调整小部件的大小?我的意思是,例如,调整 Fl_Text_Display 或 Fl_Box 或 Fl_Pack 的大小,就像我们通常在任何操作系统中调整窗口一样?

我浏览了 FLTK 附带的所有演示,并进行了大量搜索,但只找到了通过代码调整大小或用户通过单击按钮调整大小的示例。我找不到任何指向正确方向的东西,即如何使小部件的边框变得可拖动,以便通过拖动来调整小部件的大小。

【问题讨论】:

    标签: c++ resize drag fltk


    【解决方案1】:

    您可以探索 Fl_Group 和 Fl_Tile 调整大小的功能,也许将它们用作包装器。不幸的是,FLTK 不支持每个小部件的开箱即用,因此您必须自己制作。如果您只需要制作几个自定义小部件,下面的代码为您提供了开始的总体思路:

    #include <FL/Fl.H>
    #include <FL/Fl_Double_Window.H>
    #include <FL/Fl_Box.H>
    #include <FL/fl_draw.H>
    #include <cmath>
    
    class Resizeable : public Fl_Box
    {
    public:
        Resizeable(int X, int Y, int W, int H)
            : Fl_Box(X, Y, W, H, "Resize Me") {}
    
    private:
        bool can_resize;
        bool is_on_right_bottom_corner;
    
        void draw()
        {
            Fl_Box::draw();
            fl_rect(x(), y(), w(), h(), FL_RED);
            int bottom_right_x = w() + x();
            int bottom_right_y = h() + y();
            fl_polygon(bottom_right_x - 6, bottom_right_y - 1,
                    bottom_right_x - 1, bottom_right_y - 6,
                    bottom_right_x -1, bottom_right_y - 1);
        }
    
        int handle(int event)
        {
            switch (event) {
            case FL_PUSH: {
                can_resize = is_on_right_bottom_corner;
                return 1;
            }
            case FL_RELEASE:
                can_resize = false;
                return 1;
            case FL_DRAG: {
                if (can_resize) {
                    int X = Fl::event_x();
                    int Y = Fl::event_y();
                    int W = X > x() + 1 ? X - x() : w();
                    int H = Y > y() + 1 ? Y - y() : h();
                    size(W, H);
                    parent()->redraw();
                }
                return 1;
            }
            case FL_MOVE: {
                int dist_right_border  = std::abs(x() + w() - Fl::event_x());
                int dist_bottom_border = std::abs(y() + h() - Fl::event_y());
                is_on_right_bottom_corner = (dist_right_border < 10 && dist_bottom_border < 10);
                window()->cursor(is_on_right_bottom_corner ? FL_CURSOR_SE : FL_CURSOR_DEFAULT);
                return 1;
            }
            case FL_ENTER:
                return 1;
            case FL_LEAVE:
                window()->cursor(FL_CURSOR_DEFAULT);
                return 1;
            }
            return 0;
        }
    };
    
    int main()
    {
        Fl_Double_Window win(300, 300, "Resize Example");
        Resizeable res(50, 50, 100, 40);
        win.show();
        return Fl::run();
    }
    

    【讨论】:

    • 非常感谢您相当有帮助的回答。这确实是一个很好的起点!让我问你一个后续问题。您上面显示的唯一重要细节是如何使其仅在光标位于边框上方时才可调整大小 - 而不是在矩形内。你对这个细节有什么建议吗?
    • 我已经更新了代码示例,只允许在右下角调整大小。您可以扩展逻辑以调整其他角或沿整个边界的大小。
    • 好的,这是一个很棒且优雅的解决方案。非常感谢您的帮助。我能够在整个边界上完全实现它,并且我几乎在那里为所有小部件进行通用工作。我真的很感激! (PS:我没有投票,因为我没有足够的声誉)。
    猜你喜欢
    • 1970-01-01
    • 2016-09-08
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多