ItemList::ItemList(QWidget *parent) : QTableView(parent) { // model PasspotPlugin *plugin = dynamic_cast<PasspotPlugin*>(get_plugin().pointer()); assert(NULL != plugin); QAbstractItemModel *model = new ItemListModel(plugin->get_datasource()->get_db(), parent); setModel(model); // actions init_actions(); // menus init_menus(); // 设置列宽 setMinimumWidth(40); setColumnWidth(ItemListModel::COLUMN_TITLE, 140); setColumnWidth(ItemListModel::COLUMN_USER_NAME, 110); setColumnWidth(ItemListModel::COLUMN_PASSWORD, 90); setColumnWidth(ItemListModel::COLUMN_URL, 150); setColumnWidth(ItemListModel::COLUMN_COMMENT, 200); #if QT_VERSION >= 0x050000 horizontalHeader()->setSectionResizeMode(ItemListModel::COLUMN_COMMENT, QHeaderView::Stretch); // 伸缩 #endif // 拖拽相关 setSelectionMode(QAbstractItemView::SingleSelection); // 单选 setSelectionBehavior(QAbstractItemView::SelectRows); setDragEnabled(true); // 允许"拖" setAcceptDrops(false); // 不允许"放" setDropIndicatorShown(true); // ? setDragDropMode(QAbstractItemView::DragDrop); // 如果仅内部使用则使用 QAbstractItemView::InternalMove // event connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_double_click(QModelIndex))); connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(on_item_activated(QModelIndex))); plugin->directory_activated.connect(this, &ItemList::on_directory_activated); }
bool NodeView::on_event(GdkEvent* event) { MachinaCanvas* canvas = dynamic_cast<MachinaCanvas*>(this->canvas()); Forge& forge = canvas->app()->forge(); if (event->type == GDK_BUTTON_PRESS) { if (event->button.state & GDK_CONTROL_MASK) { if (event->button.button == 1) { canvas->app()->controller()->set_property( _node->id(), URIs::instance().machina_selector, forge.make(!is(forge, URIs::instance().machina_selector))); return true; } } else { return _signal_clicked.emit(&event->button); } } else if (event->type == GDK_2BUTTON_PRESS) { return on_double_click(&event->button); } return false; }
/** Event handler to fire (higher level, abstracted) Item signals from Gtk events. */ bool Item::on_event(GdkEvent* event) { boost::shared_ptr<Canvas> canvas = _canvas.lock(); if (!canvas || !event) return false; static double x, y; static double drag_start_x, drag_start_y; static bool double_click = false; static bool dragging = false; double click_x, click_y; click_x = event->button.x; click_y = event->button.y; property_parent().get_value()->w2i(click_x, click_y); switch (event->type) { case GDK_2BUTTON_PRESS: if (dragging) { ungrab(event->button.time); dragging = false; } on_double_click(&event->button); double_click = true; break; case GDK_BUTTON_PRESS: if (!canvas->locked() && event->button.button == 1) { x = click_x; y = click_y; // Set these so we can tell on a button release if a drag actually // happened (if not, it's just a click) drag_start_x = x; drag_start_y = y; grab(GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK|GDK_BUTTON_PRESS_MASK, Gdk::Cursor(Gdk::FLEUR), event->button.time); dragging = true; } break; case GDK_MOTION_NOTIFY: if ((dragging && (event->motion.state & GDK_BUTTON1_MASK))) { double new_x = click_x; double new_y = click_y; if (event->motion.is_hint) { int t_x; int t_y; GdkModifierType state; gdk_window_get_pointer(event->motion.window, &t_x, &t_y, &state); new_x = t_x; new_y = t_y; } on_drag(new_x - x, new_y - y); x = new_x; y = new_y; } break; case GDK_BUTTON_RELEASE: if (dragging) { ungrab(event->button.time); dragging = false; if (click_x != drag_start_x || click_y != drag_start_y) { on_drop(); } else if (!double_click) { on_click(&event->button); } } else if (!double_click) { on_click(&event->button); } double_click = false; break; case GDK_ENTER_NOTIFY: canvas->signal_item_entered.emit(this); raise_to_top(); break; case GDK_LEAVE_NOTIFY: canvas->signal_item_left.emit(this); break; default: break; } // Never stop event propagation so derived classes have full access // to GTK events. return false; }
static void handle_mouse_event(MOUSE_EVENT_RECORD mer) { static DWORD lastclick = 0; static int clicks = 0; int onmode = FALSE; COORD current, first, latest; MARK lmbdn_mark; /* left mouse button down here */ int sel_pending = 0, state; DWORD thisclick; UINT clicktime = GetDoubleClickTime(); buttondown = FALSE; for_ever { current = mer.dwMousePosition; switch (mer.dwEventFlags) { case 0: state = mer.dwButtonState; if (state == 0) { /* button released */ thisclick = GetTickCount(); TRACE(("CLICK %d/%d\n", lastclick, thisclick)); if (thisclick - lastclick < clicktime) { clicks++; TRACE(("MOUSE CLICKS %d\n", clicks)); } else { clicks = 0; } lastclick = thisclick; switch (clicks) { case 1: on_double_click(); break; case 2: on_triple_click(); break; } if (buttondown) { int dummy; halt_autoscroll_thread(); /* Finalize cursor position. */ (void) MouseClickSetPos(¤t, &dummy); if (!(onmode || sel_pending)) sel_yank(0); } return; } if (state & FROM_LEFT_1ST_BUTTON_PRESSED) { if (MouseClickSetPos(¤t, &onmode)) { first = latest = current; lmbdn_mark = DOT; sel_pending = FALSE; mouse_wp = row2window(latest.Y); if (onmode) { buttondown = TRUE; sel_release(); update(TRUE); } else { HWND hwnd; (void) update(TRUE); /* possible wdw change */ buttondown = FALSE; /* until all inits are successful */ /* Capture mouse to console vile's window handle. */ hwnd = GetVileWindow(); (void) SetCapture(hwnd); /* Compute pixel height of each row on screen. */ (void) GetClientRect(hwnd, &client_rect); row_height = client_rect.bottom / term.rows; /* * Create mutex to ensure that main thread and worker * thread don't update display at the same time. */ if ((hAsMutex = CreateMutex(0, FALSE, 0)) == NULL) mlforce("[Can't create autoscroll mutex]"); else { /* * Setup a worker thread to act as a pseudo * timer that kicks off autoscroll when * necessary. */ if (_beginthread(autoscroll_thread, 0, NULL) == (unsigned long) -1) { (void) CloseHandle(hAsMutex); mlforce("[Can't create autoscroll thread]"); } else sel_pending = buttondown = TRUE; } if (!buttondown) (void) ReleaseCapture(); } } } else if (state & FROM_LEFT_2ND_BUTTON_PRESSED) { if (MouseClickSetPos(¤t, &onmode) && !onmode) { sel_yank(0); sel_release(); paste_selection(); (void) update(TRUE); } return; } else { if (MouseClickSetPos(¤t, &onmode) && onmode) { sel_release(); update(TRUE); } else { kbd_alarm(); } } break; case MOUSE_MOVED: if (!buttondown) return; if (onmode) { /* on mode line, resize window (if possible). */ if (!adjust_window(mouse_wp, ¤t, &latest)) { /* * left mouse button still down, but cursor moved off mode * line. Update latest to keep track of cursor in case * it wanders back on the mode line. */ latest = current; } } else { mousemove(&sel_pending, &first, ¤t, &lmbdn_mark, (mer.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) ); } break; #ifdef MOUSE_WHEELED case MOUSE_WHEELED: /* * Trial and error experimentation shows that dwButtonState * has its high bit set when the wheel moves back and not * set otherwise. */ mvupwind(TRUE, ((long) mer.dwButtonState < 0) ? -3 : 3); update(TRUE); return; #endif /* MOUSE_WHEELED */ } for_ever { INPUT_RECORD ir; DWORD nr; int key; if (!ReadConsoleInput(hConsoleInput, &ir, 1, &nr)) imdying(0); switch (ir.EventType) { case KEY_EVENT: key = decode_key_event(&ir); if (key == ESC) { if (buttondown) halt_autoscroll_thread(); sel_release(); (void) update(TRUE); return; } continue; case MOUSE_EVENT: mer = ir.Event.MouseEvent; break; } break; } } }