int ServerTree::handle(int e){ if(children() == 0) YYY_SetNoServer(); // Check that the last clicked item is still in the tree. bool still_exists = false; if(m_last_clicked != NULL){ for(Fl_Tree_Item *item = first(); item; item = next(item)){ if(item == m_last_clicked){ still_exists = true; break; } } } if(m_last_clicked == NULL || !still_exists){ m_last_clicked = first(); if(m_last_clicked == root()) m_last_clicked = next(m_last_clicked); select_only(m_last_clicked); } if(e == FL_PUSH){ puts("Push!"); if(Fl::event_button() == FL_RIGHT_MOUSE){ Fl_Tree_Item *const l_item = find_clicked(); if(l_item == NULL) return Fl_Tree::handle(e); const unsigned l_x = Fl::event_x(), l_y = Fl::event_y(); const Fl_Menu_Item *l_menu_item = s_right_click_menu->popup(l_x, l_y, NULL, 0, 0); if(l_menu_item == NULL) return Fl_Tree::handle(e); /* const unsigned l_index = std::distance(static_cast<const Fl_Menu_Item *>(s_right_click_menu), l_menu_item); */ return 1; } } // Update the m_last_clicked. m_last_clicked = first_selected_item(); if(m_last_clicked == root()) m_last_clicked = next(m_last_clicked); // Do the default handle const int ret = Fl_Tree::handle(e); // If we deselected everything, reselect the last item. if(first_selected_item() == NULL) select_only(m_last_clicked); return ret; }
int Desktop::handle(int event) { switch(event) { case FL_FOCUS: case FL_UNFOCUS: case FL_SHORTCUT: return 1; case FL_PUSH: { /* * First check where we clicked. If we do it on desktop unfocus any possible focused childs, and handle * specific clicks. Otherwise, do rest for childs. */ Fl_Widget* clicked = Fl::belowmouse(); if(NOT_SELECTABLE(clicked)) { //E_DEBUG(E_STRLOC ": DESKTOP CLICK !!!\n"); if(!selectionbuf.empty()) { /* * Only focused are in selectionbuf, so this is fine to do; also will prevent * full redraw when is clicked on desktop */ unfocus_all(); selectionbuf.clear(); } /* track position so moving can be deduced */ if(Fl::event_button() == 1) { selbox->x = Fl::event_x(); selbox->y = Fl::event_y(); } else if(Fl::event_button() == 3) { last_px = Fl::event_x(); last_py = Fl::event_y(); damage(EDE_DESKTOP_DAMAGE_OVERLAY); const edelib::MenuItem* item = dmenu->menu()->popup(Fl::event_x(), Fl::event_y()); dmenu->picked(item); } return 1; } /* from here, all events are managed for icons */ DesktopIcon* tmp_icon = (DesktopIcon*)clicked; /* do no use assertion on this, since fltk::belowmouse() can miss our icon */ if(!tmp_icon) return 1; if(SELECTION_MULTI) { Fl::event_is_click(0); select(tmp_icon); return 1; } else if(SELECTION_SINGLE) { if(!in_selection(tmp_icon)) { select_only(tmp_icon); } } else if(Fl::event_button() == 3) { select_only(tmp_icon); } /* * Let child handle the rest. * Also prevent click on other mouse buttons during move. */ if(!moving) tmp_icon->handle(FL_PUSH); //E_DEBUG(E_STRLOC ": FL_PUSH from desktop\n"); selection_x = Fl::event_x_root(); selection_y = Fl::event_y_root(); return 1; } case FL_DRAG: moving = true; if(!selectionbuf.empty()) { //E_DEBUG(E_STRLOC ": DRAG icon from desktop\n"); move_selection(Fl::event_x_root(), Fl::event_y_root(), false); } else { //E_DEBUG(E_STRLOC ": DRAG from desktop\n"); /* * Moving is started with pushed button. * From this point selection box is created and is rolled until release */ if(selbox->x != 0 || selbox->y != 0) { selbox->w = Fl::event_x() - selbox->x; selbox->h = Fl::event_y() - selbox->y; selbox->show = true; /* see if there some icons inside selection area */ select_in_area(); /* redraw selection box */ damage(EDE_DESKTOP_DAMAGE_OVERLAY); } } return 1; case FL_RELEASE: //E_DEBUG(E_STRLOC ": RELEASE from desktop\n"); //E_DEBUG(E_STRLOC ": clicks: %i\n", Fl::event_is_click()); if(selbox->show) { selbox->x = selbox->y = selbox->w = selbox->h = 0; selbox->show = false; damage(EDE_DESKTOP_DAMAGE_OVERLAY); /* * Now pickup those who are in is_focused() state. * * Possible flickers due overlay will be later removed when is called move_selection(), which * will in turn redraw icons again after position them. */ if(!selectionbuf.empty()) selectionbuf.clear(); DesktopIcon *o; for(int i = 0; i < children(); i++) { if(NOT_SELECTABLE(child(i))) continue; o = (DesktopIcon*)child(i); if(o->is_focused()) select(o, false); } return 1; } if(!selectionbuf.empty() && moving) move_selection(Fl::event_x_root(), Fl::event_y_root(), true); /* * Do not send FL_RELEASE during move * TODO: should be alowed FL_RELEASE to multiple icons? (aka. run command for all selected icons)? */ if(selectionbuf.size() == 1 && !moving) selectionbuf.front()->handle(FL_RELEASE); moving = false; return 1; case FL_DND_ENTER: case FL_DND_DRAG: case FL_DND_LEAVE: return 1; case FL_DND_RELEASE: { DesktopIcon* di = below_mouse(Fl::event_x(), Fl::event_y()); if(di) return di->handle(event); return 1; } case FL_PASTE: { DesktopIcon* di = below_mouse(Fl::event_x(), Fl::event_y()); if(di) return di->handle(event); return 1; } case FL_ENTER: case FL_LEAVE: case FL_MOVE: return EDE_DESKTOP_WINDOW::handle(event); default: break; } return 0; }