int GtkClickCounter::clickCountForGdkButtonEvent(GtkWidget* widget, GdkEventButton* buttonEvent) { gint doubleClickDistance = 250; gint doubleClickTime = 5; GtkSettings* settings = gtk_settings_get_for_screen(gtk_widget_get_screen(widget)); g_object_get(settings, "gtk-double-click-distance", &doubleClickDistance, "gtk-double-click-time", &doubleClickTime, NULL); // GTK+ only counts up to triple clicks, but WebCore wants to know about // quadruple clicks, quintuple clicks, ad infinitum. Here, we replicate the // GDK logic for counting clicks. GdkEvent* event(reinterpret_cast<GdkEvent*>(buttonEvent)); guint32 eventTime = getEventTime(event); if ((event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) || ((abs(buttonEvent->x - m_previousClickPoint.x()) < doubleClickDistance) && (abs(buttonEvent->y - m_previousClickPoint.y()) < doubleClickDistance) && (eventTime - m_previousClickTime < static_cast<guint>(doubleClickTime)) && (buttonEvent->button == m_previousClickButton))) m_currentClickCount++; else m_currentClickCount = 1; gdouble x, y; gdk_event_get_coords(event, &x, &y); m_previousClickPoint = IntPoint(x, y); m_previousClickButton = buttonEvent->button; m_previousClickTime = eventTime; return m_currentClickCount; }
/* Ignores (x, y) on input, translates event coordinates to * allocation relative (x, y) of the returned widget. */ static GtkWidget * find_topmost_widget_coords_from_event (GdkEvent *event, gint *x, gint *y) { gint tx, ty; gdouble dx, dy; GtkWidget *tmp; gdk_event_get_coords (event, &dx, &dy); tx = dx; ty = dy; /* Returns coordinates relative to tmp's allocation. */ tmp = find_widget_under_pointer (event->any.window, &tx, &ty); if (!tmp) return NULL; /* Make sure the pointer can actually be on the widget returned. */ if (tx < 0 || tx >= tmp->allocation.width || ty < 0 || ty >= tmp->allocation.height) return NULL; if (x) *x = tx; if (y) *y = ty; return tmp; }
WebMouseEvent WebEventFactory::createWebMouseEvent(const GdkEvent* event, int currentClickCount) { double x, y, xRoot, yRoot; gdk_event_get_coords(event, &x, &y); gdk_event_get_root_coords(event, &xRoot, &yRoot); WebEvent::Type type = static_cast<WebEvent::Type>(0); switch (event->type) { case GDK_MOTION_NOTIFY: type = WebEvent::MouseMove; break; case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: type = WebEvent::MouseDown; break; case GDK_BUTTON_RELEASE: type = WebEvent::MouseUp; break; default : ASSERT_NOT_REACHED(); } return WebMouseEvent(type, buttonForEvent(event), IntPoint(x, y), IntPoint(xRoot, yRoot), 0 /* deltaX */, 0 /* deltaY */, 0 /* deltaZ */, currentClickCount, modifiersForEvent(event), gdk_event_get_time(event)); }
static gboolean touch_release_in_button (GtkButton *button) { GtkButtonPrivate *priv; gint width, height; GdkEvent *event; gdouble x, y; priv = button->priv; event = gtk_get_current_event (); if (!event) return FALSE; if (event->type != GDK_TOUCH_END || event->touch.window != priv->event_window) { gdk_event_free (event); return FALSE; } gdk_event_get_coords (event, &x, &y); width = gdk_window_get_width (priv->event_window); height = gdk_window_get_height (priv->event_window); gdk_event_free (event); if (x >= 0 && x <= width && y >= 0 && y <= height) return TRUE; return FALSE; }
/** * anjuta_tabber_get_widget_coordinates: * @widget: widget for the coordinates * @event: event to get coordinates from * @x: return location for x coordinate * @y: return location for y coordinate * * Returns: %TRUE if coordinates were set, %FALSE otherwise */ static gboolean anjuta_tabber_get_widget_coordinates (GtkWidget *widget, GdkEvent *event, gint *x, gint *y) { GdkWindow *window = ((GdkEventAny *)event)->window; gdouble tx, ty; if (!gdk_event_get_coords (event, &tx, &ty)) return FALSE; while (window && window != gtk_widget_get_window (widget)) { gint window_x, window_y; gdk_window_get_position (window, &window_x, &window_y); tx += window_x; ty += window_y; window = gdk_window_get_parent (window); } if (window) { *x = tx; *y = ty; return TRUE; } else return FALSE; }
/* Ignores (x, y) on input, translates event coordinates to * allocation relative (x, y) of the returned widget. */ static GtkWidget * find_topmost_widget_coords_from_event (GdkEvent *event, gint *x, gint *y) { GtkAllocation allocation; gint tx, ty; gdouble dx, dy; GtkWidget *tmp; gdk_event_get_coords (event, &dx, &dy); /* Returns coordinates relative to tmp's allocation. */ tmp = _gtk_widget_find_at_coords (event->any.window, dx, dy, &tx, &ty); if (!tmp) return NULL; /* Make sure the pointer can actually be on the widget returned. */ gtk_widget_get_allocation (tmp, &allocation); if (tx < 0 || tx >= allocation.width || ty < 0 || ty >= allocation.height) return NULL; if (x) *x = tx; if (y) *y = ty; return tmp; }
static VALUE gdkevent_get_coords(VALUE self) { gdouble x_win, y_win; gboolean ret = gdk_event_get_coords(RVAL2GDKEVENT(self), &x_win, &y_win); return ret ? rb_ary_new3(2, rb_float_new(x_win), rb_float_new(y_win)) : Qnil; }
static gboolean in_map (GtkWidget *w, GdkEventCrossing *event, gpointer data) { ETzMap *tzmap; gdouble x_coord, y_coord; tzmap = (ETzMap *) data; gdk_event_get_coords ((GdkEvent *) event, &x_coord, &y_coord); update_hover_point (tzmap, x_coord, y_coord); return TRUE; }
WebWheelEvent WebEventFactory::createWebWheelEvent(const GdkEvent* event) { double x, y, xRoot, yRoot; gdk_event_get_coords(event, &x, &y); gdk_event_get_root_coords(event, &xRoot, &yRoot); FloatSize wheelTicks; switch (event->scroll.direction) { case GDK_SCROLL_UP: wheelTicks = FloatSize(0, 1); break; case GDK_SCROLL_DOWN: wheelTicks = FloatSize(0, -1); break; case GDK_SCROLL_LEFT: wheelTicks = FloatSize(1, 0); break; case GDK_SCROLL_RIGHT: wheelTicks = FloatSize(-1, 0); break; #if GTK_CHECK_VERSION(3, 3, 18) case GDK_SCROLL_SMOOTH: { double deltaX, deltaY; gdk_event_get_scroll_deltas(event, &deltaX, &deltaY); wheelTicks = FloatSize(-deltaX, -deltaY); } break; #endif default: ASSERT_NOT_REACHED(); } // FIXME: [GTK] Add a setting to change the pixels per line used for scrolling // https://bugs.webkit.org/show_bug.cgi?id=54826 float step = static_cast<float>(Scrollbar::pixelsPerLineStep()); FloatSize delta(wheelTicks.width() * step, wheelTicks.height() * step); return WebWheelEvent(WebEvent::Wheel, IntPoint(x, y), IntPoint(xRoot, yRoot), delta, wheelTicks, WebWheelEvent::ScrollByPixelWheelEvent, modifiersForEvent(event), gdk_event_get_time(event)); }
static gboolean list_button_release_event (GtkListBox *box, GdkEvent *event, GtkWidget *chooser) { gdouble x, y; GtkListBoxRow *row; gdk_event_get_coords (event, &x, &y); row = gtk_list_box_get_row_at_y (box, y); if (row && g_object_get_data (G_OBJECT (row), "back")) { g_signal_emit_by_name (row, "activate", NULL); return TRUE; } return FALSE; }
/* Ignores (x, y) on input, translates event coordinates to * allocation relative (x, y) of the returned widget. */ static GtkWidget * find_topmost_widget_coords_from_event (GdkEvent *event, gint *x, gint *y) { GtkAllocation allocation; gint tx, ty; gdouble dx, dy; GtkWidget *tmp; gdk_event_get_coords (event, &dx, &dy); /* Returns coordinates relative to tmp's allocation. */ tmp = _gtk_widget_find_at_coords (event->any.window, dx, dy, &tx, &ty); if (!tmp) return NULL; /* Make sure the pointer can actually be on the widget returned. */ gtk_widget_get_allocation (tmp, &allocation); allocation.x = 0; allocation.y = 0; if (GTK_IS_WINDOW (tmp)) { GtkBorder border; _gtk_window_get_shadow_width (GTK_WINDOW (tmp), &border); allocation.x = border.left; allocation.y = border.top; allocation.width -= border.left + border.right; allocation.height -= border.top + border.bottom; } if (tx < allocation.x || tx >= allocation.width || ty < allocation.y || ty >= allocation.height) return NULL; if (x) *x = tx; if (y) *y = ty; return tmp; }
static void move_item_cb (GtkAction *action, EggEditableToolbar *etoolbar) { GtkWidget *toolitem = gtk_widget_get_ancestor (egg_editable_toolbar_get_selected (etoolbar), GTK_TYPE_TOOL_ITEM); GtkTargetList *list = gtk_target_list_new (dest_drag_types, G_N_ELEMENTS (dest_drag_types)); GdkEvent *realevent = gtk_get_current_event(); GdkEventMotion event; event.type = GDK_MOTION_NOTIFY; event.window = realevent->any.window; event.send_event = FALSE; event.axes = NULL; event.time = gdk_event_get_time (realevent); gdk_event_get_state (realevent, &event.state); gdk_event_get_coords (realevent, &event.x, &event.y); gdk_event_get_root_coords (realevent, &event.x_root, &event.y_root); gtk_drag_begin (toolitem, list, GDK_ACTION_MOVE, 1, (GdkEvent *)&event); gtk_target_list_unref (list); }
static void helper_test_imagewidget_move_event(GtkWidget* widget, GdkEvent* event, gpointer user_data){ double x, y; char text_position[10]; char text_color[60]; GrfImageWidget* imagewidget = GRF_IMAGEWIDGET(widget); float * current_translation = grf_imagewidget_get_translation(imagewidget); GrfArray * image = (GrfArray*)user_data; gdk_event_get_coords(event, &x, &y); // Translation or brush if(pressed){ if(ctrl_pressed) grf_imagewidget_set_translation(imagewidget,current_translation[0]+(x-curx),current_translation[1]+(y-cury),TRUE); else{ GrfScalar2D centro = {x,y}; GrfScalar4D cor = grf_scalar4D_new (255,0,0,255); grf_array_draw_circle(image,centro,3,&cor,-1,GRF_NEIGHBOR_8,0); grf_imagewidget_set_image(imagewidget, image,TRUE); } } // Get current pixel color uint64_t pixel_index = ((int)y)*image->step[0]+((int)x)*image->step[1]; uint8_t * pixel = &image->data_uint8[pixel_index]; if(image->dim == 2 || image->size[2] == 1) sprintf(text_color,"(G = %03d)", pixel[0]); else sprintf(text_color,"(<span color=\"red\">R=%03d</span>, <span color=\"green\">G=%03d</span>, <span color=\"blue\">B=%03d</span>)", pixel[2],pixel[1],pixel[0]); gtk_label_set_markup(GTK_LABEL(lbl_color), ""); gtk_label_set_label(GTK_LABEL(lbl_color),text_color); // Get current position sprintf(text_position,"%d %d", (int)x,(int)y); gtk_statusbar_push(GTK_STATUSBAR(statusbar), context, text_position); curx = x; cury = y; }
bool _HYChartWindow::_ProcessOSEvent (Ptr vEvent) { static long lastH = -1, lastV = -1; if (!_HYTWindow::_ProcessOSEvent (vEvent)) { if (components.lLength == 0) { return false; } _HYPullDown *p1 = (_HYPullDown*)GetObject (4); if (p1&&(p1->GetSelection()>=8)&&(ySeries.lLength)) { _HY_GTK_UI_Message *theMessage = (_HY_GTK_UI_Message*)vEvent; gdouble xc, yc; gdk_event_get_coords (theMessage->theEvent,&xc,&yc); switch (theMessage->theEvent->type) { case GDK_BUTTON_PRESS: { if (((GdkEventButton*)theMessage->theEvent)->button != 1) { return false; } lastH = xc-theWindow->allocation.x-windowContent->allocation.x; lastV = yc-theWindow->allocation.y-windowContent->allocation.y; if (FindClickedCell(lastH, lastV)!=0) { // the chart lastH = -1; lastV = -1; } else { gdk_pointer_grab (theWindow->window,false, (GdkEventMask)(GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK), theWindow->window, NULL, ((GdkEventButton*)theMessage->theEvent)->time); return true; } break; } case GDK_BUTTON_RELEASE: { if (lastH>=0) { gdk_pointer_ungrab (((GdkEventButton*)theMessage->theEvent)->time); lastH = -1; lastV = -1; return true; } break; } case GDK_MOTION_NOTIFY: { if (lastH>=0) { long newH = xc-theWindow->allocation.x-windowContent->allocation.x, newV = yc-theWindow->allocation.y-windowContent->allocation.y; bool redraw = false; _Parameter stepper = pi_const/180.; if (abs(newH-lastH)>abs(newV-lastV)) { stepper *= 1+log (fabs(newH-lastH))/log(2.0); if (newH-lastH<0) { if (xyAngle>0.0) { xyAngle -= stepper; if (xyAngle<0) { xyAngle = 0; } redraw = true; } } else if (xyAngle<pi_const/2) { xyAngle += stepper; if (xyAngle>pi_const/2) { xyAngle = pi_const/2; } redraw = true; } } else { if (newV==lastV) { return false; } stepper *= 1+log (fabs(newV-lastV))/log(2.0); if (newV-lastV>0) { if (zAngle<pi_const/2) { zAngle += stepper; if (zAngle>pi_const/2) { zAngle = pi_const/2; } redraw = true; } } else if (zAngle>0.0) { zAngle -= stepper; if (zAngle<0) { zAngle = 0; } redraw = true; } } if (redraw) { ComputeProjectionSettings(); projectionMatrix = ComputeProjectionMatrix (); forceUpdateForScrolling = true; DrawChart(); forceUpdateForScrolling = false; } lastH = newH; lastV = newV; } break; } } } return false; } return true; }
static void helper_test_imagewidget_press_event(GtkWidget* widget, GdkEvent *event, gpointer user_data){ (void) widget; (void) user_data; printf("press\n"); pressed = 1; gdk_event_get_coords(event, &curx, &cury); }
static void gimp_pick_button_pick (GimpPickButton *button, GdkEvent *event) { GdkScreen *screen = gdk_event_get_screen (event); GimpColorProfile *monitor_profile; GdkMonitor *monitor; GimpRGB rgb; gint x_root; gint y_root; gdouble x_win; gdouble y_win; gdk_window_get_origin (gdk_event_get_window (event), &x_root, &y_root); gdk_event_get_coords (event, &x_win, &y_win); x_root += x_win; y_root += y_win; #ifdef G_OS_WIN32 { HDC hdc; RECT rect; COLORREF win32_color; /* For MS Windows, use native GDI functions to get the pixel, as * cairo does not handle the case where you have multiple monitors * with a monitor on the left or above the primary monitor. That * scenario create a cairo primary surface with negative extent, * which is not handled properly (bug 740634). */ hdc = GetDC (HWND_DESKTOP); GetClipBox (hdc, &rect); win32_color = GetPixel (hdc, x_root + rect.left, y_root + rect.top); ReleaseDC (HWND_DESKTOP, hdc); gimp_rgba_set_uchar (&rgb, GetRValue (win32_color), GetGValue (win32_color), GetBValue (win32_color), 255); } #else { GdkWindow *window; gint x_window; gint y_window; cairo_surface_t *image; cairo_t *cr; guchar *data; guchar color[3]; /* we try to pick from the local window under the cursor, and fall * back to picking from the root window if this fails (i.e., if * the cursor is not under a local window). on wayland, picking * from the root window is not supported, so this at least allows * us to pick from local windows. see bug #780375. */ window = gdk_device_get_window_at_position (gdk_event_get_device (event), &x_window, &y_window); if (! window) { window = gdk_screen_get_root_window (screen); x_window = x_root; y_window = y_root; } image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1); cr = cairo_create (image); gdk_cairo_set_source_window (cr, window, -x_window, -y_window); cairo_paint (cr); cairo_destroy (cr); data = cairo_image_surface_get_data (image); GIMP_CAIRO_RGB24_GET_PIXEL (data, color[0], color[1], color[2]); cairo_surface_destroy (image); gimp_rgba_set_uchar (&rgb, color[0], color[1], color[2], 255); } #endif monitor = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen), x_root, y_root); monitor_profile = gimp_monitor_get_color_profile (monitor); if (monitor_profile) { GimpColorProfile *srgb_profile; GimpColorTransform *transform; const Babl *format; GimpColorTransformFlags flags = 0; format = babl_format ("R'G'B'A double"); flags |= GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE; flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION; srgb_profile = gimp_color_profile_new_rgb_srgb (); transform = gimp_color_transform_new (monitor_profile, format, srgb_profile, format, GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL, flags); g_object_unref (srgb_profile); if (transform) { gimp_color_transform_process_pixels (transform, format, &rgb, format, &rgb, 1); gimp_rgb_clamp (&rgb); g_object_unref (transform); } } g_signal_emit_by_name (button, "color-picked", &rgb); }
bool _HYButtonBar::_ProcessOSEvent (Ptr vEvent) { if (buttons.lLength) { _HY_GTK_UI_Message *theMessage = (_HY_GTK_UI_Message*)vEvent; gdouble xc, yc; if (gdk_event_get_coords (theMessage->theEvent,&xc,&yc)) { switch (theMessage->theEvent->type) { case GDK_BUTTON_PRESS: { if (((GdkEventButton*)theMessage->theEvent)->button != 1) { return false; } _SmiteTooltip(); int h = _FindClickedButton (yc,xc); if ( h>=0 && enabledButtons.Find(h) >=0 ) { if (pullDownButtons.Find (h)>=0) { lastMouseDown = -1; SendButtonPush(h); } else { pushed = lastMouseDown = h; _MarkButtonForUpdate (h); } } return true; } case GDK_BUTTON_RELEASE: { if (lastMouseDown>=0 || pushed >= 0) { int h = _FindClickedButton (yc,xc); if (h==pushed && pushed >= 0) { SendButtonPush (h); } _MarkButtonForUpdate (pushed); _MarkButtonForUpdate (lastMouseDown); pushed = -1; lastMouseDown = -1; } return true; } case GDK_MOTION_NOTIFY : { _SmiteTooltip(); if (lastMouseDown>=0) { int h = _FindClickedButton (yc,xc); if (h!=lastMouseDown) { if (pushed>=0) { pushed = -1; _MarkButtonForUpdate (lastMouseDown); } } else { if (pushed==-1) { pushed = lastMouseDown; _MarkButtonForUpdate (lastMouseDown); } } } return true; } } } } return _HYPlatformComponent::_ProcessOSEvent (vEvent); }
void ImGui_ImplGtk3Cogl_HandleEvent(GdkEvent *event) { ImGuiIO& io = ImGui::GetIO(); GdkEventType type = gdk_event_get_event_type(event); switch (type) { case GDK_MOTION_NOTIFY: { gdouble x = 0.0f, y = 0.0f; if (gdk_event_get_coords(event, &x, &y)) g_MousePosition = ImVec2(x, y); break; } case GDK_BUTTON_PRESS: case GDK_BUTTON_RELEASE: { guint button = 0; if (gdk_event_get_button(event, &button) && button > 0 && button <= 5) { if (type == GDK_BUTTON_PRESS) g_MousePressed[button - 1] = true; } break; } case GDK_SCROLL: { gdouble x, y; if (gdk_event_get_scroll_deltas(event, &x, &y)) g_MouseWheel = -y; break; } case GDK_KEY_PRESS: case GDK_KEY_RELEASE: { GdkEventKey *e = (GdkEventKey *) event; static const struct { enum ImGuiKey_ imgui; guint gdk; } gdk_key_to_imgui_key[] = { { ImGuiKey_Tab, GDK_KEY_Tab }, { ImGuiKey_Tab, GDK_KEY_ISO_Left_Tab }, { ImGuiKey_LeftArrow, GDK_KEY_Left }, { ImGuiKey_RightArrow, GDK_KEY_Right }, { ImGuiKey_UpArrow, GDK_KEY_Up }, { ImGuiKey_DownArrow, GDK_KEY_Down }, { ImGuiKey_PageUp, GDK_KEY_Page_Up }, { ImGuiKey_PageDown, GDK_KEY_Page_Down }, { ImGuiKey_Home, GDK_KEY_Home }, { ImGuiKey_End, GDK_KEY_End }, { ImGuiKey_Delete, GDK_KEY_Delete }, { ImGuiKey_Backspace, GDK_KEY_BackSpace }, { ImGuiKey_Space, GDK_KEY_space }, { ImGuiKey_Enter, GDK_KEY_Return }, { ImGuiKey_Escape, GDK_KEY_Escape }, { ImGuiKey_A, GDK_KEY_a }, { ImGuiKey_C, GDK_KEY_c }, { ImGuiKey_V, GDK_KEY_v }, { ImGuiKey_X, GDK_KEY_x }, { ImGuiKey_Y, GDK_KEY_y }, { ImGuiKey_Z, GDK_KEY_z }, }; for (unsigned i = 0; i < ARRAY_SIZE(gdk_key_to_imgui_key); i++) { if (e->keyval == gdk_key_to_imgui_key[i].gdk) io.KeysDown[gdk_key_to_imgui_key[i].imgui] = type == GDK_KEY_PRESS; } gunichar c = gdk_keyval_to_unicode(e->keyval); if (g_unichar_isprint(c) && ImGuiKey_COUNT + c < ARRAY_SIZE(io.KeysDown)) io.KeysDown[ImGuiKey_COUNT + c] = type == GDK_KEY_PRESS; if (type == GDK_KEY_PRESS && e->string) io.AddInputCharactersUTF8(e->string); struct { bool *var; GdkModifierType modifier; guint keyvals[3]; } mods[] = { { &io.KeyCtrl, GDK_CONTROL_MASK, { GDK_KEY_Control_L, GDK_KEY_Control_R, 0 }, }, { &io.KeyShift, GDK_SHIFT_MASK, { GDK_KEY_Shift_L, GDK_KEY_Shift_R, 0 }, }, { &io.KeyAlt, GDK_MOD1_MASK, { GDK_KEY_Alt_L, GDK_KEY_Alt_R, 0 }, }, { &io.KeySuper, GDK_SUPER_MASK, { GDK_KEY_Super_L, GDK_KEY_Super_R, 0 }, } }; for (unsigned i = 0; i < ARRAY_SIZE(mods); i++) { *mods[i].var = (mods[i].modifier & e->state); bool match = false; for (int j = 0; mods[i].keyvals[j] != 0; j++) if (e->keyval == mods[i].keyvals[j]) match = true; if (match) *mods[i].var = type == GDK_KEY_PRESS; } break; } default: break; } // We trigger 2 subsequent redraws for each event because of the // way some ImGui widgets work. For example a Popup menu will only // appear a frame after a click happened. g_NumRedraws = 2; GdkFrameClock *clock = gdk_window_get_frame_clock(g_GdkWindow); gdk_frame_clock_request_phase(clock, GDK_FRAME_CLOCK_PHASE_PAINT); }
bool _HYSequencePane::_ProcessOSEvent (Ptr vEvent) { static bool amScrolling = false, vertical; static long localPt_x, localPt_y, originalStart, originalSpan, lastClick, firstClick; if (_HYPlatformComponent::_ProcessOSEvent (vEvent)) return true; _HY_GTK_UI_Message *theMessage = (_HY_GTK_UI_Message*)vEvent; if (active) { gdouble xc, yc; if (gdk_event_get_coords (theMessage->theEvent,&xc,&yc)) { switch (theMessage->theEvent->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: { GdkEventButton * bevent = (GdkEventButton*)theMessage->theEvent; long globalPt_x = xc, globalPt_y = yc; localPt_x = globalPt_x-rel.left-parentWindow->allocation.x; localPt_y = globalPt_y-rel.top-parentWindow->allocation.y; vertical = (localPt_x<headerWidth)&&(localPt_y>=(GetSlotHeight()+1)); if (((GdkEventButton*)bevent)->button == 1) { if (vertical) ProcessVSelectionChange (localPt_x,localPt_y,bevent->state & GDK_SHIFT_MASK,bevent->state & GDK_CONTROL_MASK, false, bevent->type == GDK_2BUTTON_PRESS); else ProcessSelectionChange (localPt_x,localPt_y,bevent->state & GDK_SHIFT_MASK,bevent->state & GDK_CONTROL_MASK); } else { if ((((GdkEventButton*)bevent)->button == 2 || ((GdkEventButton*)bevent)->button == 3 )&& (vertical&&vselection.lLength || !vertical &&selection.lLength)) { ProcessContextualPopUp (globalPt_x, globalPt_y); return true; } } } break; case GDK_BUTTON_RELEASE: case GDK_LEAVE_NOTIFY: { if (amScrolling) { if (messageRecipient) ((_HYTWindow*)messageRecipient)->trackMouseComponent = (Ptr)nil; /*gdk_pointer_ungrab (((GdkEventButton*)theMessage->theEvent)->time);*/ if (vertical) { _HYRect invalRectH = {parentWindow->allocation.x+rel.left, parentWindow->allocation.y+rel.top+(GetSlotHeight()+1)+1,rel.left+headerWidth,rel.bottom-HY_SCROLLER_WIDTH}; GdkRectangle irect = HYRect2GDKRect(invalRectH); irect.x+=parentWindow->allocation.x; irect.y+=parentWindow->allocation.y; gdk_window_invalidate_rect (parentWindow->window, &irect, false); if ( localPt_x<headerWidth && localPt_x>0 && lastClick>-2) MoveSpecies (firstClick+originalStart,lastClick+startRow); } amScrolling = false; } break; } case GDK_MOTION_NOTIFY: { GdkEventMotion * motEvent = (GdkEventMotion*)theMessage->theEvent; if (motEvent->state & GDK_BUTTON1_MASK) { if (amScrolling) { gint mousePt_x = motEvent->x - rel.left - parentWindow->allocation.x, mousePt_y = motEvent->y - rel.top - parentWindow->allocation.y; if (vertical) // vertical scrolling { long wHeight = rel.bottom-rel.top-HY_SCROLLER_WIDTH, slotHeight = GetSlotHeight(); if ( mousePt_y < GetSlotHeight()+1 || localPt_y != mousePt_y || mousePt_y>wHeight ) { localPt_x = mousePt_x; localPt_y = mousePt_y; if (mousePt_y>wHeight) { // scroll down if ((endRow<=speciesIndex.lLength)&&(vselection.lData[0]!=speciesIndex.lLength-1)) { if (endRow-startRow<originalSpan) break; startRow++; endRow++; _SetVScrollerPos(((double)MAX_CONTROL_VALUE*startRow)/ (speciesIndex.lLength-endRow+startRow+1)); BuildPane(); forceUpdateForScrolling = true; _MarkForUpdate(); forceUpdateForScrolling = false; lastClick = -2; } break; } else { mousePt_y-=(GetSlotHeight()+1); if (mousePt_y<=slotHeight) { if (mousePt_y>=0) { if (mousePt_y<slotHeight/2) mousePt_y = -1; else mousePt_y = 0; } else { // scroll up if (startRow>0) { startRow--; endRow--; _SetVScrollerPos(((double)MAX_CONTROL_VALUE*startRow)/(speciesIndex.lLength-endRow+startRow+1)); BuildPane(); forceUpdateForScrolling = true; _MarkForUpdate(); forceUpdateForScrolling = false; lastClick = -2; } break; } } else mousePt_y=(mousePt_y-(GetSlotHeight()+1))/slotHeight; } if ( mousePt_y<-1 || mousePt_y>= endRow-startRow ) break; if (mousePt_y!=lastClick) { GdkDrawable * tempDr = GDK_DRAWABLE(parentWindow->window); GdkGC * tempGC = gdk_gc_new (tempDr); GdkColor black = HYColorToGDKColor((_HYColor){0,0,0}); gdk_gc_set_foreground (theContext, &black); gdk_gc_set_function (tempGC, GDK_INVERT); gdk_gc_set_line_attributes (tempGC, 2, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER); if (lastClick>=-1) { lastClick = (GetSlotHeight()+1)+slotHeight*(lastClick+1)+rel.top+1; gdk_draw_line (tempDr,tempGC,parentWindow->allocation.x+rel.left+1,parentWindow->allocation.y+lastClick, parentWindow->allocation.x+rel.left+headerWidth-1,parentWindow->allocation.y+lastClick); } lastClick = mousePt_y; if (lastClick+startRow != firstClick+originalStart) { mousePt_y = (GetSlotHeight()+1)+slotHeight*(lastClick+1)+rel.top+1; gdk_draw_line (tempDr,tempGC,parentWindow->allocation.x+rel.left+1,parentWindow->allocation.y+mousePt_y, parentWindow->allocation.x+rel.left+headerWidth-1,parentWindow->allocation.y+mousePt_y); } g_object_unref (tempGC); } } return true; } else // horizontal scrolling { long rightWindowBound = _HYCanvas::GetMaxW()-HY_SCROLLER_WIDTH; guint32 serverTime = gdk_x11_get_server_time (parentWindow->window); if ( mousePt_x<headerWidth && startColumn>0 || localPt_x!=mousePt_x || mousePt_x> rightWindowBound) { forceUpdateForScrolling = true; if (mousePt_x<headerWidth && startColumn>0) { gint wx, wy; gdk_window_get_origin (parentWindow->window,&wx,&wy); wx += parentWindow->allocation.x+rel.left; wy += parentWindow->allocation.y+rel.top; do { guint32 serverTime2 = gdk_x11_get_server_time (parentWindow->window); if (serverTime2-serverTime < 100) ProcessSelectionChange (mousePt_x,mousePt_y,true,true,true); GdkModifierType keyDown; gdk_display_get_pointer (gdk_display_get_default(),NULL,&mousePt_x,&mousePt_y,&keyDown); mousePt_x -= wx; mousePt_y -= wy; serverTime = serverTime2; if ((keyDown & GDK_BUTTON1_MASK)==0) break; gtk_main_iteration_do(true); } while (mousePt_x<headerWidth && startColumn>0); } else { if (mousePt_x> rightWindowBound) { gint wx, wy; gdk_window_get_origin (parentWindow->window,&wx,&wy); wx += parentWindow->allocation.x; wy += parentWindow->allocation.y; do { guint32 serverTime2 = gdk_x11_get_server_time (parentWindow->window); if (serverTime2-serverTime < 100) ProcessSelectionChange (mousePt_x+HY_SCROLLER_WIDTH,mousePt_y,true,true,true); GdkModifierType keyDown; gdk_display_get_pointer (gdk_display_get_default(),NULL,&mousePt_x,&mousePt_y,&keyDown); mousePt_x -= wx; mousePt_y -= wy; serverTime = serverTime2; if ((keyDown & GDK_BUTTON1_MASK)==0) break; gtk_main_iteration_do(true); } while (mousePt_x> rightWindowBound && endColumn < columnStrings.lLength); } else if (serverTime-gdk_event_get_time(theMessage->theEvent) < 100) ProcessSelectionChange (mousePt_x,mousePt_y,true,true,true); } forceUpdateForScrolling = false; localPt_x = mousePt_x; localPt_y = mousePt_y; } return true; } } else { /*gdk_pointer_grab (parentWindow->window,false, GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK, NULL, NULL, (((GdkEventMotion*)theMessage->theEvent))->time);*/ if (messageRecipient) ((_HYTWindow*)messageRecipient)->trackMouseComponent = (Ptr)((_HYComponent*)this); amScrolling = true; originalStart = startRow, originalSpan = endRow-startRow; lastClick = -2; firstClick = (localPt_y-(GetSlotHeight()+1))/GetSlotHeight(); return true; } } break; } } } } return false; }
/* Links can also be activated by clicking. */ static gboolean textview_event_after (GtkTextView *textview, GdkEvent *event) { GtkTextIter start, end, iter; GtkTextBuffer *buffer; gint x, y; GdkModifierType mt = 0; guint event_button = 0; gdouble event_x_win = 0; gdouble event_y_win = 0; g_return_val_if_fail (GTK_IS_TEXT_VIEW (textview), FALSE); if (event->type == GDK_KEY_PRESS || event->type == GDK_KEY_RELEASE) { guint event_keyval = 0; gdk_event_get_keyval (event, &event_keyval); switch (event_keyval) { case GDK_KEY_Control_L: case GDK_KEY_Control_R: update_ctrl_state ( textview, event->type == GDK_KEY_PRESS); break; } return FALSE; } if (!gdk_event_get_state (event, &mt)) { GdkWindow *window; GdkDisplay *display; GdkDeviceManager *device_manager; GdkDevice *device; window = gtk_widget_get_parent_window (GTK_WIDGET (textview)); display = gdk_window_get_display (window); device_manager = gdk_display_get_device_manager (display); device = gdk_device_manager_get_client_pointer (device_manager); gdk_window_get_device_position (window, device, NULL, NULL, &mt); } update_ctrl_state (textview, (mt & GDK_CONTROL_MASK) != 0); if (event->type != GDK_BUTTON_RELEASE) return FALSE; gdk_event_get_button (event, &event_button); gdk_event_get_coords (event, &event_x_win, &event_y_win); if (event_button != 1 || (mt & GDK_CONTROL_MASK) == 0) return FALSE; buffer = gtk_text_view_get_buffer (textview); /* we shouldn't follow a link if the user has selected something */ gtk_text_buffer_get_selection_bounds (buffer, &start, &end); if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end)) return FALSE; gtk_text_view_window_to_buffer_coords ( textview, GTK_TEXT_WINDOW_WIDGET, event_x_win, event_y_win, &x, &y); gtk_text_view_get_iter_at_location (textview, &iter, x, y); invoke_link_if_present (buffer, &iter); update_mouse_cursor (textview, x, y); return FALSE; }