FLTK:如何将图形对象放在前台?

Posted

技术标签:

【中文标题】FLTK:如何将图形对象放在前台?【英文标题】:FLTK: how to put graphical object in foreground? 【发布时间】:2020-12-24 14:54:45 【问题描述】:

我在一个窗口中有两个可拖动对象:一个包含黑色方块的对象位于背景中,而包含红色方块的对象位于前景中。

这种布局是由于它们的绘制顺序。我想在前景中放置我当前正在拖动的那个:例如,如果我拖动带有黑色方块的框,我希望它在前景中。一旦我放下它,它应该保持在前台。如果我拖动红色的,我希望它在前景中,而黑色的在背景中。

我试图查看关于clipping 的 FLTK 1.3.5 的文档,但我没有发现任何有用的东西(至少,就我能理解的而言)。有什么方法可以实现我想要的吗?

代码(灵感来自here)如下所示。

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Pixmap.H>
#include <iostream>

static char *box1_xpm[] =                        // XPM
"20 20 2 1",
"  c #000000",
"# c None",
"####################",
"####################",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"####################",
"####################"
;

static char *box2_xpm[] =                        // XPM
"20 20 2 1",
"  c #FF0000",
"# c None",
"####################",
"####################",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"#                  #",
"####################",
"####################"
;

Fl_Double_Window *G_win    = NULL;
Fl_Scroll        *G_scroll = NULL;
static Fl_Pixmap  G_box1(box1_xpm);
static Fl_Pixmap  G_box2(box2_xpm);

#define BOXWIDTH  50
#define BOXHEIGHT 50

// A 'MOVABLE' BOX
class Box : public Fl_Box 
protected:
    int handle(int e) 
        static int offset[2] =  0, 0 ;
        int ret = Fl_Box::handle(e);
        switch ( e ) 
            case FL_PUSH:
                offset[0] = x() - Fl::event_x();    // save where user clicked for dragging
                offset[1] = y() - Fl::event_y();
                return(1);
            case FL_RELEASE:
                return(1);
            case FL_DRAG:
                position(offset[0]+Fl::event_x(), offset[1]+Fl::event_y());     // handle dragging
                G_win->redraw();
                return(1);
        
        return(ret);
    
public:
    Box(int X, int Y, int idx) : Fl_Box(X,Y,BOXWIDTH,BOXHEIGHT,0) 
        idx>0? image(G_box1):image(G_box2);
        box(FL_UP_BOX);
        color(FL_GRAY);
    
;

/// MAIN
int main() 
    G_win = new Fl_Double_Window(200,200);
    new Box(20,BOXHEIGHT,2);
    new Box(20+BOXWIDTH,BOXHEIGHT,0);
    G_win->resizable(G_win);
    G_win->show();
    return(Fl::run());

【问题讨论】:

【参考方案1】:

小部件按照它们出现在父级的 child() 列表中的顺序绘制。诀窍是确保被拖动的小部件是最后一个绘制的。改变push case如下

            case FL_PUSH:
                
                    offset[0] = x() - Fl::event_x();    // save where user clicked for dragging
                    offset[1] = y() - Fl::event_y();

                    // Do we need to rearrange?
                    int last_ix = G_win->children() - 1;
                    Box* last = (Box*)G_win->child(last_ix);
                    if (last != this)
                    
                        // Widgets get drawn in the order in which they were inserted.
                        // Remove this widget from the parent
                        G_win->remove(this);
                        // Re-add it at the bottom of the list
                        G_win->add(this);
                    
                
                return(1);

【讨论】:

它很有魅力,谢谢。如果有超过 2 个小部件,它也是完美的。 还有一个改进——偏移量不需要是静态的——它可以声明为成员变量。 谢谢,我没有仔细看剩下的代码,我专注于前台/后台问题。

以上是关于FLTK:如何将图形对象放在前台?的主要内容,如果未能解决你的问题,请参考以下文章

如何自动堆叠 FLTK 的 Fl_Input-objects 一个在另一个之下

如何让 Octave 默认使用“gnuplot”而不是“fltk”?

如何在 MinGW 中使用 FLTK 1.1 dll?

FLTK:绘制另一个图形时清除一个图形

asp.net mvc2.0中如何将datatable对象传到view的前台然后获取datatable中表字段得值?

FLTK C++ Callbakc 问题