diff --git a/ede-panel/Panel.cpp b/ede-panel/Panel.cpp index 891690e..56e3cb3 100644 --- a/ede-panel/Panel.cpp +++ b/ede-panel/Panel.cpp @@ -503,6 +503,12 @@ int Panel::handle(int e) { /* are moving the panel; only vertical moving is supported */ cursor(FL_CURSOR_MOVE); + /* send drag events to children and do not drag panel in the mean time */ + if(clicked && clicked != this) { + clicked->handle(e); + return 0; + } + /* snap it to the top or bottom, depending on pressed mouse location */ if(Fl::event_y_root() <= screen_h_half && y() > screen_h_half) { position(x(), screen_y); @@ -549,6 +555,7 @@ void Panel::load_applets(const char *applets) { * (similar string is expected from configuration), fallback is plain string. */ static const char *fallback = +#ifndef EDE_PANEL_LOCAL_APPLETS "start_menu," "quick_launch," "pager," @@ -557,10 +564,25 @@ void Panel::load_applets(const char *applets) { "keyboard_layout," "battery_monitor," "cpu_monitor," -#ifdef __linux__ +# ifdef __linux__ "mem_monitor," -#endif - "system_tray"; +# endif + "system_tray" +#else /* EDE_PANEL_LOCAL_APPLETS */ + "./applets/start-menu/start_menu," + "./applets/quick-launch/quick_launch," + "./applets/pager/pager," + "./applets/clock/clock," + "./applets/taskbar/taskbar," + "./applets/keyboard-layout/keyboard_layout," + "./applets/battery-monitor/battery_monitor," + "./applets/cpu-monitor/cpu_monitor," +# ifdef __linux__ + "./applets/mem-monitor/mem_monitor," +# endif + "./applets/system-tray/system_tray" +#endif /* EDE_PANEL_LOCAL_APPLETS */ + ; String dir = Resource::find_data("panel-applets"); E_RETURN_IF_FAIL(!dir.empty()); @@ -576,7 +598,7 @@ void Panel::load_applets(const char *applets) { snprintf(path, sizeof(path), "%s" E_DIR_SEPARATOR_STR "%s" APPLET_EXTENSION, dir.c_str(), tok); #else /* only for testing, so path separator is hardcoded */ - snprintf(path, sizeof(path), "./applets/%s/%s" APPLET_EXTENSION, dir.c_str(), tok); + snprintf(path, sizeof(path), "%s" APPLET_EXTENSION, tok); #endif mgr.load(path); } diff --git a/ede-panel/applets/taskbar/TaskButton.cpp b/ede-panel/applets/taskbar/TaskButton.cpp index bb7e2e2..7d28319 100644 --- a/ede-panel/applets/taskbar/TaskButton.cpp +++ b/ede-panel/applets/taskbar/TaskButton.cpp @@ -104,9 +104,10 @@ static void maximize_cb(Fl_Widget*, void *b) { } TaskButton::TaskButton(int X, int Y, int W, int H, const char *l) : Fl_Button(X, Y, W, H, l), - xid(0), wspace(0), image_alloc(false), net_wm_icon(0) + xid(0), wspace(0), old_value(0), image_alloc(false), dragged(false), net_wm_icon(0) { box(FL_UP_BOX); + align(FL_ALIGN_INSIDE | FL_ALIGN_LEFT | FL_ALIGN_CLIP); if(IconLoader::inited()) { @@ -226,3 +227,30 @@ void TaskButton::update_image_from_xid(void) { image(img); image_alloc = true; } + +int TaskButton::handle(int e) { + switch(e) { + case FL_PUSH: + /* + * Remember old value, as value() result affect will box be drawn as FL_UP_BOX or FL_DOWN_BOX. + * This trick should return box to the old state in case of dragging. + */ + old_value = value(); + return Fl_Button::handle(e); + case FL_DRAG: + dragged = true; + return 1; + case FL_RELEASE: + if(dragged) { + Taskbar *taskbar = (Taskbar*)parent(); + taskbar->try_dnd(this, Fl::event_x(), Fl::event_y()); + dragged = false; + + value(old_value); + return 1; + } + /* fallthrough */ + } + + return Fl_Button::handle(e); +} diff --git a/ede-panel/applets/taskbar/TaskButton.h b/ede-panel/applets/taskbar/TaskButton.h index 14c5301..db9d8a1 100644 --- a/ede-panel/applets/taskbar/TaskButton.h +++ b/ede-panel/applets/taskbar/TaskButton.h @@ -29,7 +29,9 @@ private: /* window ID this button handles */ Window xid; int wspace; + char old_value; /* for storing value() as it affects boxtype */ bool image_alloc; + bool dragged; Atom net_wm_icon; void clear_image(void); @@ -48,6 +50,8 @@ public: void set_workspace(int s) { wspace = s; } int get_workspace(void) { return wspace; } + + int handle(int e); }; #endif diff --git a/ede-panel/applets/taskbar/Taskbar.cpp b/ede-panel/applets/taskbar/Taskbar.cpp index 7b95953..1ea2c4c 100644 --- a/ede-panel/applets/taskbar/Taskbar.cpp +++ b/ede-panel/applets/taskbar/Taskbar.cpp @@ -360,7 +360,7 @@ void Taskbar::update_child_icon(Window xid) { } void Taskbar::update_child_workspace(Window xid) { - if(children() < 0) return; + if(!children()) return; TaskButton *o; for(int i = 0; i < children(); i++) { @@ -382,6 +382,49 @@ void Taskbar::panel_redraw(void) { parent()->redraw(); } +void Taskbar::try_dnd(TaskButton *b, int xpos, int ypos) { + if(!children()) return; + + /* + * try to find position of incoming child, as the child, when is moved + * forward, has to go on 'target_pos + 1' instead only 'target_pos' + */ + int child_pos = find(b); + E_RETURN_IF_FAIL(child_pos != children()); + + TaskButton *o; + for(int i = 0; i < children(); i++) { + o = (TaskButton*)child(i); + if(o == b) continue; + + if((xpos > b->x() && xpos < b->x() + b->w()) && + (ypos > b->y() && ypos < b->y() + b->h())) + { + /* not moved outside child range */ + return; + } + + if((xpos > o->x() && xpos < o->x() + o->w()) && + (ypos > o->y() && ypos < o->y() + o->h())) + { + /* Try to find widget position in array. Widgets in array are not sorted in any order. */ + int pos = find(o); + if(pos == children()) { + /* not found, proceed with the search */ + continue; + } + + /* increase just in case target position is in front */ + pos += (pos > child_pos) ? 1 : 0; + insert(*b, pos); + break; + } + } + + layout_children(); + redraw(); +} + EDE_PANEL_APPLET_EXPORT ( Taskbar, EDE_PANEL_APPLET_OPTION_ALIGN_LEFT | EDE_PANEL_APPLET_OPTION_RESIZABLE_H, diff --git a/ede-panel/applets/taskbar/Taskbar.h b/ede-panel/applets/taskbar/Taskbar.h index 3a4e4f4..c8d82b0 100644 --- a/ede-panel/applets/taskbar/Taskbar.h +++ b/ede-panel/applets/taskbar/Taskbar.h @@ -58,6 +58,9 @@ public: void update_child_workspace(Window xid); void panel_redraw(void); + + /* try to move child on place of other child, but only if it falls within x,y range */ + void try_dnd(TaskButton *b, int x, int y); }; #endif