Adding support for taskbuttons drag & drop. Also fixing child size check bug.

This commit is contained in:
Sanel Zukan 2014-11-19 12:40:42 +00:00
parent 0d0cc8d8b1
commit 002bd6b2e7
5 changed files with 106 additions and 6 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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,

View File

@ -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