Ejemplo n.º 1
0
static gboolean lowlight_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_lowlight_gui_data_t *c = (dt_iop_lowlight_gui_data_t *)self->gui_data;
  dt_iop_lowlight_params_t *p = (dt_iop_lowlight_params_t *)self->params;
  const int inset = DT_IOP_LOWLIGHT_INSET;
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset;
  if(!c->dragging) c->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width;
  c->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height;
  if(c->dragging)
  {
    *p = c->drag_params;
    if(c->x_move >= 0)
    {
      const float mx = CLAMP(event->x - inset, 0, width) / (float)width;
      if(c->x_move > 0 && c->x_move < DT_IOP_LOWLIGHT_BANDS - 1)
      {
        const float minx = p->transition_x[c->x_move - 1] + 0.001f;
        const float maxx = p->transition_x[c->x_move + 1] - 0.001f;
        p->transition_x[c->x_move] = fminf(maxx, fmaxf(minx, mx));
      }
    }
    else
    {
      dt_iop_lowlight_get_params(p, c->mouse_x, c->mouse_y + c->mouse_pick, c->mouse_radius);
    }
    dt_dev_add_history_item(darktable.develop, self, TRUE);
  }
  else if(event->y > height)
  {
    c->x_move = 0;
    float dist = fabs(p->transition_x[0] - c->mouse_x);
    for(int k = 1; k < DT_IOP_LOWLIGHT_BANDS; k++)
    {
      float d2 = fabs(p->transition_x[k] - c->mouse_x);
      if(d2 < dist)
      {
        c->x_move = k;
        dist = d2;
      }
    }
  }
  else
  {
    c->x_move = -1;
  }
  gtk_widget_queue_draw(widget);
  gint x, y;
#if GTK_CHECK_VERSION(3, 20, 0)
  gdk_window_get_device_position(event->window,
      gdk_seat_get_pointer(gdk_display_get_default_seat(
          gdk_window_get_display(event->window))),
      &x, &y, 0);
#else
  gdk_window_get_device_position(event->window,
                                 gdk_device_manager_get_client_pointer(
                                     gdk_display_get_device_manager(gdk_window_get_display(event->window))),
                                 &x, &y, NULL);
#endif
  return TRUE;
}
Ejemplo n.º 2
0
    static gint
target_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    BalloonEval *beval = (BalloonEval *)data;

    switch (event->type)
    {
	case GDK_ENTER_NOTIFY:
	    pointer_event(beval, (int)event->crossing.x,
				 (int)event->crossing.y,
				 event->crossing.state);
	    break;
	case GDK_MOTION_NOTIFY:
	    if (event->motion.is_hint)
	    {
		int		x;
		int		y;
		GdkModifierType	state;
		/*
		 * GDK_POINTER_MOTION_HINT_MASK is set, thus we cannot obtain
		 * the coordinates from the GdkEventMotion struct directly.
		 */
# if GTK_CHECK_VERSION(3,0,0)
		{
		    GdkWindow * const win = gtk_widget_get_window(widget);
		    GdkDisplay * const dpy = gdk_window_get_display(win);
#  if GTK_CHECK_VERSION(3,20,0)
		    GdkSeat * const seat = gdk_display_get_default_seat(dpy);
		    GdkDevice * const dev = gdk_seat_get_pointer(seat);
#  else
		    GdkDeviceManager * const mngr = gdk_display_get_device_manager(dpy);
		    GdkDevice * const dev = gdk_device_manager_get_client_pointer(mngr);
#  endif
		    gdk_window_get_device_position(win, dev , &x, &y, &state);
		}
# else
		gdk_window_get_pointer(widget->window, &x, &y, &state);
# endif
		pointer_event(beval, x, y, (unsigned int)state);
	    }
	    else
	    {
		pointer_event(beval, (int)event->motion.x,
				     (int)event->motion.y,
				     event->motion.state);
	    }
	    break;
	case GDK_LEAVE_NOTIFY:
	    /*
	     * Ignore LeaveNotify events that are not "normal".
	     * Apparently we also get it when somebody else grabs focus.
	     */
	    if (event->crossing.mode == GDK_CROSSING_NORMAL)
		cancelBalloon(beval);
	    break;
	case GDK_BUTTON_PRESS:
	case GDK_SCROLL:
	    cancelBalloon(beval);
	    break;
	case GDK_KEY_PRESS:
	    key_event(beval, event->key.keyval, TRUE);
	    break;
	case GDK_KEY_RELEASE:
	    key_event(beval, event->key.keyval, FALSE);
	    break;
	default:
	    break;
    }

    return FALSE; /* continue emission */
}
Ejemplo n.º 3
0
void *dt_control_expose(void *voidptr)
{
  int width, height, pointerx, pointery;
  if(!darktable.gui->surface) return NULL;
  width = dt_cairo_image_surface_get_width(darktable.gui->surface);
  height = dt_cairo_image_surface_get_height(darktable.gui->surface);
  GtkWidget *widget = dt_ui_center(darktable.gui->ui);
#if GTK_CHECK_VERSION(3, 20, 0)
  gdk_window_get_device_position(gtk_widget_get_window(widget),
      gdk_seat_get_pointer(gdk_display_get_default_seat(gtk_widget_get_display(widget))),
      &pointerx, &pointery, NULL);
#else
  GdkDevice *device
      = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(widget)));
  gdk_window_get_device_position(gtk_widget_get_window(widget), device, &pointerx, &pointery, NULL);
#endif

  // create a gtk-independent surface to draw on
  cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);

  // TODO: control_expose: only redraw the part not overlapped by temporary control panel show!
  //
  float tb = 8; // fmaxf(10, width/100.0);
  darktable.control->tabborder = tb;
  darktable.control->width = width;
  darktable.control->height = height;

  GdkRGBA color;
  GtkStyleContext *context = gtk_widget_get_style_context(widget);
  gboolean color_found = gtk_style_context_lookup_color (context, "bg_color", &color);
  if(!color_found)
  {
    color.red = 1.0;
    color.green = 0.0;
    color.blue = 0.0;
    color.alpha = 1.0;
  }
  gdk_cairo_set_source_rgba(cr, &color);

  cairo_set_line_width(cr, tb);
  cairo_rectangle(cr, tb / 2., tb / 2., width - tb, height - tb);
  cairo_stroke(cr);
  cairo_set_line_width(cr, 1.5);
  color_found = gtk_style_context_lookup_color (context, "really_dark_bg_color", &color);
  if(!color_found)
  {
    color.red = 1.0;
    color.green = 0.0;
    color.blue = 0.0;
    color.alpha = 1.0;
  }
  gdk_cairo_set_source_rgba(cr, &color);
  cairo_rectangle(cr, tb, tb, width - 2 * tb, height - 2 * tb);
  cairo_stroke(cr);

  cairo_save(cr);
  cairo_translate(cr, tb, tb);
  cairo_rectangle(cr, 0, 0, width - 2 * tb, height - 2 * tb);
  cairo_clip(cr);
  cairo_new_path(cr);
  // draw view
  dt_view_manager_expose(darktable.view_manager, cr, width - 2 * tb, height - 2 * tb, pointerx - tb,
                         pointery - tb);
  cairo_restore(cr);

  // draw log message, if any
  dt_pthread_mutex_lock(&darktable.control->log_mutex);
  if(darktable.control->log_ack != darktable.control->log_pos)
  {
    PangoRectangle ink;
    PangoLayout *layout;
    PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc);
    const float fontsize = DT_PIXEL_APPLY_DPI(14);
    pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE);
    pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
    layout = pango_cairo_create_layout(cr);
    pango_layout_set_font_description(layout, desc);
    pango_layout_set_text(layout, darktable.control->log_message[darktable.control->log_ack], -1);
    pango_layout_get_pixel_extents(layout, &ink, NULL);
    const float pad = DT_PIXEL_APPLY_DPI(20.0f), xc = width / 2.0;
    const float yc = height * 0.85 + DT_PIXEL_APPLY_DPI(10), wd = pad + ink.width * .5f;
    float rad = DT_PIXEL_APPLY_DPI(14);
    cairo_set_line_width(cr, 1.);
    cairo_move_to(cr, xc - wd, yc + rad);
    for(int k = 0; k < 5; k++)
    {
      cairo_arc(cr, xc - wd, yc, rad, M_PI / 2.0, 3.0 / 2.0 * M_PI);
      cairo_line_to(cr, xc + wd, yc - rad);
      cairo_arc(cr, xc + wd, yc, rad, 3.0 * M_PI / 2.0, M_PI / 2.0);
      cairo_line_to(cr, xc - wd, yc + rad);
      if(k == 0)
      {
        color_found = gtk_style_context_lookup_color (context, "selected_bg_color", &color);
        if(!color_found)
        {
          color.red = 1.0;
          color.green = 0.0;
          color.blue = 0.0;
          color.alpha = 1.0;
        }
        gdk_cairo_set_source_rgba(cr, &color);
        cairo_fill_preserve(cr);
      }
      cairo_set_source_rgba(cr, 0., 0., 0., 1.0 / (1 + k));
      cairo_stroke(cr);
      rad += .5f;
    }
    color_found = gtk_style_context_lookup_color (context, "fg_color", &color);
    if(!color_found)
    {
      color.red = 1.0;
      color.green = 0.0;
      color.blue = 0.0;
      color.alpha = 1.0;
    }
    gdk_cairo_set_source_rgba(cr, &color);
    cairo_move_to(cr, xc - wd + .5f * pad, (yc + 1. / 3. * fontsize) - fontsize);
    pango_cairo_show_layout(cr, layout);
    pango_font_description_free(desc);
    g_object_unref(layout);
  }
  // draw busy indicator
  if(darktable.control->log_busy > 0)
  {
    PangoRectangle ink;
    PangoLayout *layout;
    PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc);
    const float fontsize = DT_PIXEL_APPLY_DPI(14);
    pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE);
    pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
    layout = pango_cairo_create_layout(cr);
    pango_layout_set_font_description(layout, desc);
    pango_layout_set_text(layout, _("working.."), -1);
    pango_layout_get_pixel_extents(layout, &ink, NULL);
    const float xc = width / 2.0, yc = height * 0.85 - DT_PIXEL_APPLY_DPI(30), wd = ink.width * .5f;
    cairo_move_to(cr, xc - wd, yc + 1. / 3. * fontsize - fontsize);
    pango_cairo_layout_path(cr, layout);
    cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
    cairo_fill_preserve(cr);
    cairo_set_line_width(cr, 0.7);
    cairo_set_source_rgb(cr, 0.3, 0.3, 0.3);
    cairo_stroke(cr);
    pango_font_description_free(desc);
    g_object_unref(layout);
  }
  dt_pthread_mutex_unlock(&darktable.control->log_mutex);

  cairo_destroy(cr);

  cairo_t *cr_pixmap = cairo_create(darktable.gui->surface);
  cairo_set_source_surface(cr_pixmap, cst, 0, 0);
  cairo_paint(cr_pixmap);
  cairo_destroy(cr_pixmap);

  cairo_surface_destroy(cst);
  return NULL;
}
Ejemplo n.º 4
0
/**
 * gimp_display_shell_scale_get_zoom_focus:
 * @shell:
 * @new_scale:
 * @x:
 * @y:
 *
 * Calculates the viewport coordinate to focus on when zooming
 * independently for each axis.
 **/
static void
gimp_display_shell_scale_get_zoom_focus (GimpDisplayShell *shell,
                                         gdouble           new_scale,
                                         gdouble           current_scale,
                                         gdouble          *x,
                                         gdouble          *y,
                                         GimpZoomFocus     zoom_focus)
{
  GtkWidget *window = GTK_WIDGET (gimp_display_shell_get_window (shell));
  GdkEvent  *event;
  gint       image_center_x;
  gint       image_center_y;
  gint       other_x;
  gint       other_y;

  /* Calculate stops-to-fit focus point */
  gimp_display_shell_scale_get_image_center_viewport (shell,
                                                      &image_center_x,
                                                      &image_center_y);

  /* Calculate other focus point, default is the canvas center */
  other_x = shell->disp_width  / 2;
  other_y = shell->disp_height / 2;

  /*  Center on the mouse position instead of the display center if
   *  one of the following conditions are fulfilled and pointer is
   *  within the canvas:
   *
   *   (1) there's no current event (the action was triggered by an
   *       input controller)
   *   (2) the event originates from the canvas (a scroll event)
   *   (3) the event originates from the window (a key press event)
   *
   *  Basically the only situation where we don't want to center on
   *  mouse position is if the action is being called from a menu.
   */
  event = gtk_get_current_event ();

  if (! event ||
      gtk_get_event_widget (event) == shell->canvas ||
      gtk_get_event_widget (event) == window)
    {
      GdkPoint *point = g_queue_pop_head (shell->zoom_focus_pointer_queue);
      gint      canvas_pointer_x;
      gint      canvas_pointer_y;

      if (point)
        {
          canvas_pointer_x = point->x;
          canvas_pointer_y = point->y;

          g_slice_free (GdkPoint, point);
        }
      else
        {
          GdkDisplay *display = gtk_widget_get_display (shell->canvas);
          GdkSeat    *seat    = gdk_display_get_default_seat (display);

          gdk_window_get_device_position (gtk_widget_get_window (shell->canvas),
                                          gdk_seat_get_pointer (seat),
                                          &canvas_pointer_x,
                                          &canvas_pointer_y,
                                          NULL);
        }

      if (canvas_pointer_x >= 0 &&
          canvas_pointer_y >= 0 &&
          canvas_pointer_x <  shell->disp_width &&
          canvas_pointer_y <  shell->disp_height)
        {
          other_x = canvas_pointer_x;
          other_y = canvas_pointer_y;
        }
    }

  if (zoom_focus == GIMP_ZOOM_FOCUS_RETAIN_CENTERING_ELSE_BEST_GUESS)
    {
      if (gimp_display_shell_scale_viewport_coord_almost_centered (shell,
                                                                   image_center_x,
                                                                   image_center_y,
                                                                   NULL,
                                                                   NULL))
        {
          zoom_focus = GIMP_ZOOM_FOCUS_IMAGE_CENTER;
        }
      else
        {
          zoom_focus = GIMP_ZOOM_FOCUS_BEST_GUESS;
        }
    }

  switch (zoom_focus)
    {
    case GIMP_ZOOM_FOCUS_POINTER:
      *x = other_x;
      *y = other_y;
      break;

    case GIMP_ZOOM_FOCUS_IMAGE_CENTER:
      *x = image_center_x;
      *y = image_center_y;
      break;

    case GIMP_ZOOM_FOCUS_BEST_GUESS:
    default:
      {
        gboolean within_horizontally, within_vertically;
        gboolean stops_horizontally, stops_vertically;

        gimp_display_shell_scale_image_is_within_viewport (shell,
                                                           &within_horizontally,
                                                           &within_vertically);

        gimp_display_shell_scale_image_stops_to_fit (shell,
                                                     new_scale,
                                                     current_scale,
                                                     &stops_horizontally,
                                                     &stops_vertically);

        *x = within_horizontally && ! stops_horizontally ? image_center_x : other_x;
        *y = within_vertically   && ! stops_vertically   ? image_center_y : other_y;
      }
      break;
    }
}
Ejemplo n.º 5
0
static gboolean
gnc_reconcile_view_tooltip_cb (GNCQueryView *qview, gint x, gint y,
    gboolean keyboard_mode, GtkTooltip *tooltip, gpointer *user_data)
{
    GtkTreeModel* model;
    GtkTreeIter iter;

    // If the Description is longer than can be display, show it in a tooltip
    if (gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (qview), &x, &y, keyboard_mode, &model, NULL, &iter))
    {
        GtkTreeViewColumn *col;
        GList *cols;
        gint col_pos, col_width;
        gchar* desc_text = NULL;

        /* Are we in keyboard tooltip mode, displays tooltip below/above treeview CTRL+F1 */
        if (keyboard_mode == FALSE)
        {
            if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (qview), x, y, NULL, &col, NULL, NULL) == FALSE)
                return FALSE;
        }
        else
            gtk_tree_view_get_cursor (GTK_TREE_VIEW (qview), NULL, &col);

        cols = gtk_tree_view_get_columns (GTK_TREE_VIEW (qview));
        col_width = gtk_tree_view_column_get_width (col);
        col_pos = g_list_index (cols, col);
        g_list_free (cols);

        /* If column is not description, do not show tooltip */
        if (col_pos != (REC_DESC - 1)) // allow for the pointer model column at 0
            return FALSE;

        gtk_tree_model_get (model, &iter, REC_DESC, &desc_text, -1);

        if (desc_text)
        {
            PangoLayout* layout;
            gint text_width;
            gint root_x, root_y;
            gint cur_x, cur_y;

            layout = gtk_widget_create_pango_layout (GTK_WIDGET (qview), desc_text);
            pango_layout_get_pixel_size (layout, &text_width, NULL);
            g_object_unref (layout);

            /* If text_width + 10 <= column_width, do not show tooltip */
            if ((text_width + 10) <= col_width)
            {
                g_free (desc_text);
                return FALSE;
            }

            if (keyboard_mode == FALSE)
            {
#if GTK_CHECK_VERSION(3,20,0)
                GdkSeat *seat;
#else
                GdkDeviceManager *device_manager;
#endif
                GdkDevice *pointer;
                GtkWindow *tip_win = NULL;
                GdkWindow *parent_window;
                GList *win_list, *node;

                parent_window = gtk_widget_get_parent_window (GTK_WIDGET (qview));

#if GTK_CHECK_VERSION(3,20,0)
                seat = gdk_display_get_default_seat (gdk_window_get_display (parent_window));
                pointer = gdk_seat_get_pointer (seat);
#else
                device_manager = gdk_display_get_device_manager (gdk_window_get_display (parent_window));
                pointer = gdk_device_manager_get_client_pointer (device_manager);
#endif
                gdk_window_get_device_position (parent_window, pointer, &cur_x, &cur_y, NULL);

                gdk_window_get_origin (parent_window, &root_x, &root_y);

                 /* Get a list of toplevel windows */
                win_list = gtk_window_list_toplevels ();

                /* Look for the gtk-tooltip window, we do this as gtk_widget_get_tooltip_window
                   does not seem to work for the default tooltip window, custom yes */
                for (node = win_list;  node != NULL;  node = node->next)
                {
                    if (g_strcmp0 (gtk_widget_get_name (node->data), "gtk-tooltip") == 0)
                    tip_win = node->data;
                }
                g_list_free (win_list);

                gtk_tooltip_set_text (tooltip, desc_text);

                if (GTK_IS_WINDOW (tip_win))
                {
#if GTK_CHECK_VERSION(3,22,0)
                    GdkMonitor *mon;
#else
                    GdkScreen *screen;
                    gint monitor_num;
#endif
                    GdkRectangle monitor;
                    GtkRequisition requisition;
                    gint x, y;

                    gtk_widget_get_preferred_size (GTK_WIDGET (tip_win), &requisition, NULL);

                    x = root_x + cur_x + 10;
                    y = root_y + cur_y + 10;

#if GTK_CHECK_VERSION(3,22,0)
                    mon = gdk_display_get_monitor_at_point (gdk_display_get_default(), x, y);
                    gdk_monitor_get_geometry (mon, &monitor);
#else
                    screen = gtk_widget_get_screen (GTK_WIDGET (qview));
                    monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
                    gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
#endif
                    if (x + requisition.width > monitor.x + monitor.width)
                        x -= x - (monitor.x + monitor.width) + requisition.width;
                    else if (x < monitor.x)
                        x = monitor.x;

                    if (y + requisition.height > monitor.y + monitor.height)
                        y -= y - (monitor.y + monitor.height) + requisition.height;

                    gtk_window_move (tip_win, x, y);
                }
            }
            gtk_tooltip_set_text (tooltip, desc_text);
            g_free (desc_text);
            return TRUE;
        }
    }
    return FALSE;
}
Ejemplo n.º 6
0
void
mate_panel_applet_position_menu (GtkMenu   *menu,
			    int       *x,
			    int       *y,
			    gboolean  *push_in,
			    GtkWidget *applet)
{
	GtkAllocation   allocation;
	GtkRequisition  requisition;
	GdkDevice      *device;
	GdkScreen      *screen;
	GtkWidget      *parent;
	int             menu_x = 0;
	int             menu_y = 0;
	int             pointer_x;
	int             pointer_y;

	parent = gtk_widget_get_parent (applet);

	g_return_if_fail (PANEL_IS_WIDGET (parent));

	screen = gtk_widget_get_screen (applet);

	gtk_widget_get_preferred_size (GTK_WIDGET (menu), &requisition, NULL);

	gdk_window_get_origin (gtk_widget_get_window (applet), &menu_x, &menu_y);
#if GTK_CHECK_VERSION(3, 20, 0)
	device = gdk_seat_get_pointer (gdk_display_get_default_seat (gtk_widget_get_display (applet)));
	gdk_window_get_device_position (gtk_widget_get_window (applet), device, &pointer_x, &pointer_y, NULL);
#else
	device = gdk_device_manager_get_client_pointer (gdk_display_get_device_manager (gtk_widget_get_display (applet)));
	gdk_window_get_device_position (gtk_widget_get_window (applet), device, &pointer_x, &pointer_y, NULL);
#endif
	gtk_widget_get_allocation (applet, &allocation);

	if (!gtk_widget_get_has_window (applet)) {
		menu_x += allocation.x;
		menu_y += allocation.y;
	}

	if (PANEL_WIDGET (parent)->orient == GTK_ORIENTATION_HORIZONTAL) {
		if (gtk_widget_get_direction (GTK_WIDGET (menu)) != GTK_TEXT_DIR_RTL) {
			if (pointer_x < allocation.width &&
			    requisition.width < pointer_x)
				menu_x += MIN (pointer_x,
					       allocation.width - requisition.width);
		} else {
			menu_x += allocation.width - requisition.width;
			if (pointer_x > 0 && pointer_x < allocation.width &&
			    pointer_x < allocation.width - requisition.width) {
				menu_x -= MIN (allocation.width - pointer_x,
					       allocation.width - requisition.width);
			}
		}
		menu_x = MIN (menu_x, gdk_screen_get_width (screen) - requisition.width);

		if (menu_y > gdk_screen_get_height (screen) / 2)
			menu_y -= requisition.height;
		else
			menu_y += allocation.height;
	} else {
		if (pointer_y < allocation.height &&
		    requisition.height < pointer_y)
			menu_y += MIN (pointer_y, allocation.height - requisition.height);
		menu_y = MIN (menu_y, gdk_screen_get_height (screen) - requisition.height);

		if (menu_x > gdk_screen_get_width (screen) / 2)
			menu_x -= requisition.width;
		else
			menu_x += allocation.width;
	}

	*x = menu_x;
	*y = menu_y;
	*push_in = FALSE;
}
Ejemplo n.º 7
0
static gboolean _lib_histogram_motion_notify_callback(GtkWidget *widget, GdkEventMotion *event,
                                                      gpointer user_data)
{
  dt_lib_module_t *self = (dt_lib_module_t *)user_data;
  dt_lib_histogram_t *d = (dt_lib_histogram_t *)self->data;

  /* check if exposure hooks are available */
  gboolean hooks_available = dt_dev_exposure_hooks_available(darktable.develop);

  if(!hooks_available) return TRUE;

  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  if(d->dragging && d->highlight == 2)
  {
    float exposure = d->exposure + (event->x - d->button_down_x) * 4.0f / (float)allocation.width;
    dt_dev_exposure_set_exposure(darktable.develop, exposure);
  }
  else if(d->dragging && d->highlight == 1)
  {
    float black = d->black - (event->x - d->button_down_x) * .1f / (float)allocation.width;
    dt_dev_exposure_set_black(darktable.develop, black);
  }
  else
  {
    const float offs = 4 * DT_HIST_INSET;
    const float x = event->x - offs;
    const float y = event->y - DT_HIST_INSET;
    const float pos = x / (float)(allocation.width - 2 * offs);


    if(pos < 0 || pos > 1.0)
      ;
    else if(x > d->mode_x && x < d->mode_x + d->mode_w && y > d->button_y && y < d->button_y + d->button_h)
    {
      d->highlight = 3;
      switch(darktable.develop->histogram_type)
      {
        case DT_DEV_HISTOGRAM_LOGARITHMIC:
          gtk_widget_set_tooltip_text(widget, _("set histogram mode to linear"));
          break;
        case DT_DEV_HISTOGRAM_LINEAR:
          gtk_widget_set_tooltip_text(widget, _("set histogram mode to waveform"));
          break;
        case DT_DEV_HISTOGRAM_WAVEFORM:
          gtk_widget_set_tooltip_text(widget, _("set histogram mode to logarithmic"));
          break;
        case DT_DEV_HISTOGRAM_N:
          g_assert_not_reached();
      }
    }
    else if(x > d->red_x && x < d->red_x + d->color_w && y > d->button_y && y < d->button_y + d->button_h)
    {
      d->highlight = 4;
      gtk_widget_set_tooltip_text(widget, d->red ? _("click to hide red channel") : _("click to show red channel"));
    }
    else if(x > d->green_x && x < d->green_x + d->color_w && y > d->button_y && y < d->button_y + d->button_h)
    {
      d->highlight = 5;
      gtk_widget_set_tooltip_text(widget, d->red ? _("click to hide green channel")
                                                 : _("click to show green channel"));
    }
    else if(x > d->blue_x && x < d->blue_x + d->color_w && y > d->button_y && y < d->button_y + d->button_h)
    {
      d->highlight = 6;
      gtk_widget_set_tooltip_text(widget, d->red ? _("click to hide blue channel") : _("click to show blue channel"));
    }
    else if(pos < 0.2)
    {
      d->highlight = 1;
      gtk_widget_set_tooltip_text(widget, _("drag to change black point,\ndoubleclick resets"));
    }
    else
    {
      d->highlight = 2;
      gtk_widget_set_tooltip_text(widget, _("drag to change exposure,\ndoubleclick resets"));
    }
    gtk_widget_queue_draw(widget);
  }
  gint x, y; // notify gtk for motion_hint.
#if GTK_CHECK_VERSION(3, 20, 0)
  gdk_window_get_device_position(gtk_widget_get_window(widget),
      gdk_seat_get_pointer(gdk_display_get_default_seat(
          gdk_window_get_display(event->window))),
      &x, &y, 0);
#else
  gdk_window_get_device_position(event->window,
                                 gdk_device_manager_get_client_pointer(
                                     gdk_display_get_device_manager(gdk_window_get_display(event->window))),
                                 &x, &y, NULL);
#endif

  return TRUE;
}
Ejemplo n.º 8
0
bool wxPopupTransientWindow::Show( bool show )
{
#ifdef __WXGTK__
    if (!show)
    {
#ifdef __WXGTK3__
        GdkDisplay* display = gtk_widget_get_display(m_widget);
#ifdef __WXGTK4__
        gdk_seat_ungrab(gdk_display_get_default_seat(display));
#else
        wxGCC_WARNING_SUPPRESS(deprecated-declarations)
        GdkDeviceManager* manager = gdk_display_get_device_manager(display);
        GdkDevice* device = gdk_device_manager_get_client_pointer(manager);
        gdk_device_ungrab(device, unsigned(GDK_CURRENT_TIME));
        wxGCC_WARNING_RESTORE()
#endif
#else
        gdk_pointer_ungrab( (guint32)GDK_CURRENT_TIME );
#endif

        gtk_grab_remove( m_widget );
    }
#endif

#ifdef __WXX11__
    if (!show)
    {
        XUngrabPointer( wxGlobalDisplay(), CurrentTime );
    }
#endif

#if defined( __WXMSW__ ) || defined( __WXMAC__)
    if (!show && m_child && m_child->HasCapture())
    {
        m_child->ReleaseMouse();
    }
#endif

    bool ret = wxPopupWindow::Show( show );

#ifdef __WXGTK__
    if (show)
    {
        gtk_grab_add( m_widget );

        GdkWindow* window = gtk_widget_get_window(m_widget);
#ifdef __WXGTK4__
        GdkDisplay* display = gdk_window_get_display(window);
        GdkSeat* seat = gdk_display_get_default_seat(display);
        gdk_seat_grab(seat, window, GDK_SEAT_CAPABILITY_POINTER, false, NULL, NULL, NULL, 0);
#else
        const GdkEventMask mask = GdkEventMask(
            GDK_BUTTON_PRESS_MASK |
            GDK_BUTTON_RELEASE_MASK |
            GDK_POINTER_MOTION_HINT_MASK |
            GDK_POINTER_MOTION_MASK);
#ifdef __WXGTK3__
        GdkDisplay* display = gdk_window_get_display(window);
        wxGCC_WARNING_SUPPRESS(deprecated-declarations)
        GdkDeviceManager* manager = gdk_display_get_device_manager(display);
        GdkDevice* device = gdk_device_manager_get_client_pointer(manager);
        gdk_device_grab(device, window,
            GDK_OWNERSHIP_NONE, true, mask, NULL, unsigned(GDK_CURRENT_TIME));
        wxGCC_WARNING_RESTORE()
#else
        gdk_pointer_grab( window, true,
                          mask,
                          NULL,
                          NULL,
                          (guint32)GDK_CURRENT_TIME );
#endif
#endif // !__WXGTK4__
    }
#endif

#ifdef __WXX11__
    if (show)
    {
        Window xwindow = (Window) m_clientWindow;

        /* int res =*/ XGrabPointer(wxGlobalDisplay(), xwindow,
            True,
            ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask,
            GrabModeAsync,
            GrabModeAsync,
            None,
            None,
            CurrentTime );
    }
#endif

#if defined( __WXMSW__ ) || defined( __WXMAC__)
    if (show && m_child)
    {
        // Assume that the mouse is outside the popup to begin with
        m_child->CaptureMouse();
    }
#endif

    return ret;
}
Ejemplo n.º 9
0
/* This is a _horrible_ hack to have this here. This needs to be added to the
 * GTK+ menuing code in some manner.
 */
static void
drag_end_menu_cb (GtkWidget *widget, GdkDragContext     *context)
{
  GtkWidget *xgrab_shell;
  GtkWidget *parent;

  /* Find the last viewable ancestor, and make an X grab on it
   */
  parent = gtk_widget_get_parent (widget);
  xgrab_shell = NULL;

  /* FIXME: workaround for a possible gtk+ bug
   *    See bugs #92085(gtk+) and #91184(panel) for details.
   */
  g_object_set (widget, "has-tooltip", TRUE, NULL);

  while (parent)
    {
      gboolean viewable = TRUE;
      GtkWidget *tmp = parent;

      while (tmp)
	{
	  if (!gtk_widget_get_mapped (tmp))
	    {
	      viewable = FALSE;
	      break;
	    }
	  tmp = gtk_widget_get_parent (tmp);
	}

      if (viewable)
	xgrab_shell = parent;

#if GTK_CHECK_VERSION (3, 0, 0)
      parent = gtk_menu_shell_get_parent_shell (GTK_MENU_SHELL (parent));
#else
      parent = GTK_MENU_SHELL (parent)->parent_menu_shell;
#endif
    }

#if GTK_CHECK_VERSION (3, 0, 0)
  if (xgrab_shell)
#else
  if (xgrab_shell && !gtk_menu_get_tearoff_state (GTK_MENU(xgrab_shell)))
#endif
    {
#if GTK_CHECK_VERSION (3, 0, 0)
      gboolean status;
      GdkDisplay *display;
      GdkDevice *pointer;
      GdkDevice *keyboard;
#if GTK_CHECK_VERSION(3, 20, 0)
      GdkSeat *seat;
#else
      GdkDeviceManager *device_manager;
#endif
#endif
      GdkWindow *window = gtk_widget_get_window (xgrab_shell);
      GdkCursor *cursor = gdk_cursor_new_for_display (gdk_display_get_default (),
                                                      GDK_ARROW);

#if GTK_CHECK_VERSION (3, 0, 0)
      display = gdk_window_get_display (window);
#if GTK_CHECK_VERSION(3, 20, 0)
      seat = gdk_display_get_default_seat (display);
      pointer = gdk_seat_get_pointer (seat);
#else
      device_manager = gdk_display_get_device_manager (display);
      pointer = gdk_device_manager_get_client_pointer (device_manager);
#endif
      keyboard = gdk_device_get_associated_device (pointer);

      /* FIXMEgpoo: Not sure if report to GDK_OWNERSHIP_WINDOW
         or GDK_OWNERSHIP_APPLICATION Idem for the
         keyboard below */
      status = gdk_device_grab (pointer, window,
                                GDK_OWNERSHIP_WINDOW, TRUE,
                                GDK_BUTTON_PRESS_MASK
                                | GDK_BUTTON_RELEASE_MASK
                                | GDK_ENTER_NOTIFY_MASK
                                | GDK_LEAVE_NOTIFY_MASK
                                | GDK_POINTER_MOTION_MASK,
                                cursor, GDK_CURRENT_TIME);

      if (!status)
        {
	  if (gdk_device_grab (keyboard, window,
			       GDK_OWNERSHIP_WINDOW, TRUE,
			       GDK_KEY_PRESS | GDK_KEY_RELEASE,
			       NULL, GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS)
	    {
#else
      if ((gdk_pointer_grab (window, TRUE,
			     GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
			     GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
			     GDK_POINTER_MOTION_MASK,
			     NULL, cursor, GDK_CURRENT_TIME) == 0))
	{
	  if (gdk_keyboard_grab (window, TRUE,
				 GDK_CURRENT_TIME) == 0)
	    {
#endif
/* FIXME fix for GTK3 */
#if !GTK_CHECK_VERSION (3, 0, 0)
          GTK_MENU_SHELL (xgrab_shell)->have_xgrab = TRUE;
#endif
	    }
	  else
	    {
#if GTK_CHECK_VERSION (3, 0, 0)
	      gdk_device_ungrab (pointer, GDK_CURRENT_TIME);
	    }
	}

      g_object_unref (cursor);
#else
	      gdk_pointer_ungrab (GDK_CURRENT_TIME);
	    }
	}

      gdk_cursor_unref (cursor);
#endif
    }
}
Ejemplo n.º 10
0
static void
gtk_tooltip_show_tooltip (GdkDisplay *display)
{
  gint x, y;
  GdkScreen *screen;

  GdkWindow *window;
  GtkWidget *tooltip_widget;
  GtkTooltip *tooltip;
  gboolean return_value = FALSE;

  tooltip = g_object_get_qdata (G_OBJECT (display), quark_current_tooltip);

  if (tooltip->keyboard_mode_enabled)
    {
      x = y = -1;
      tooltip_widget = tooltip->keyboard_widget;
    }
  else
    {
      GdkDevice *device;
      gint tx, ty;

      window = tooltip->last_window;

      if (!GDK_IS_WINDOW (window))
        return;

      device = gdk_seat_get_pointer (gdk_display_get_default_seat (display));

      gdk_window_get_device_position (window, device, &x, &y, NULL);

      gdk_window_get_root_coords (window, x, y, &tx, &ty);
      tooltip->last_x = tx;
      tooltip->last_y = ty;

      tooltip_widget = _gtk_widget_find_at_coords (window, x, y, &x, &y);
    }

  if (!tooltip_widget)
    return;

  return_value = gtk_tooltip_run_requery (&tooltip_widget, tooltip, &x, &y);
  if (!return_value)
    return;

  if (!tooltip->current_window)
    {
      if (gtk_widget_get_tooltip_window (tooltip_widget))
        tooltip->current_window = gtk_widget_get_tooltip_window (tooltip_widget);
      else
        tooltip->current_window = GTK_WINDOW (GTK_TOOLTIP (tooltip)->window);
    }

  screen = gtk_widget_get_screen (tooltip_widget);

  /* FIXME: should use tooltip->current_window iso tooltip->window */
  if (screen != gtk_widget_get_screen (tooltip->window))
    {
      g_signal_handlers_disconnect_by_func (display,
                                            gtk_tooltip_display_closed,
                                            tooltip);

      gtk_window_set_screen (GTK_WINDOW (tooltip->window), screen);

      g_signal_connect (display, "closed",
                        G_CALLBACK (gtk_tooltip_display_closed), tooltip);
    }

  gtk_tooltip_position (tooltip, display, tooltip_widget);

  /* Now a tooltip is visible again on the display, make sure browse
   * mode is enabled.
   */
  tooltip->browse_mode_enabled = TRUE;
  if (tooltip->browse_mode_timeout_id)
    {
      g_source_remove (tooltip->browse_mode_timeout_id);
      tooltip->browse_mode_timeout_id = 0;
    }
}
static GtkCellEditable *
egg_cell_renderer_keys_start_editing (GtkCellRenderer      *cell,
				      GdkEvent             *event,
				      GtkWidget            *widget,
				      const gchar          *path,
				      const GdkRectangle   *background_area,
				      const GdkRectangle   *cell_area,
				      GtkCellRendererState  flags)
{
  GtkCellRendererText *celltext;
  EggCellRendererKeys *keys;
  GdkDisplay *display;
  GdkSeat *seat;
  GtkWidget *label;
  GtkWidget *eventbox;
  GValue celltext_editable = {0};

  celltext = GTK_CELL_RENDERER_TEXT (cell);
  keys = EGG_CELL_RENDERER_KEYS (cell);

  /* If the cell isn't editable we return NULL. */
  g_value_init (&celltext_editable, G_TYPE_BOOLEAN);
  g_object_get_property (G_OBJECT (celltext), "editable", &celltext_editable);
  if (g_value_get_boolean (&celltext_editable) == FALSE)
    return NULL;
  g_return_val_if_fail (gtk_widget_get_window (widget) != NULL, NULL);

  display = gtk_widget_get_display (widget);
  seat = gdk_display_get_default_seat (display);

  if (gdk_seat_grab (seat,
                     gtk_widget_get_window (widget),
                     GDK_SEAT_CAPABILITY_ALL,
                     FALSE,
                     NULL,
                     event,
                     NULL,
                     NULL) != GDK_GRAB_SUCCESS)
    return NULL;

  keys->grab_widget = widget;

  g_signal_connect (G_OBJECT (widget), "key_press_event",
                    G_CALLBACK (grab_key_callback),
                    keys);

  eventbox = g_object_new (pointless_eventbox_subclass_get_type (),
                           NULL);
  keys->edit_widget = eventbox;
  g_object_add_weak_pointer (G_OBJECT (keys->edit_widget),
                             (void**) &keys->edit_widget);

  label = gtk_label_new (NULL);
  gtk_label_set_xalign (GTK_LABEL (label), 0.0);

  gtk_widget_modify_bg (eventbox, GTK_STATE_NORMAL,
                        &gtk_widget_get_style (widget)->bg[GTK_STATE_SELECTED]);

  gtk_widget_modify_fg (label, GTK_STATE_NORMAL,
                        &gtk_widget_get_style (widget)->fg[GTK_STATE_SELECTED]);

  gtk_label_set_text (GTK_LABEL (label),
		  TOOLTIP_TEXT);

  gtk_container_add (GTK_CONTAINER (eventbox), label);

  g_object_set_data_full (G_OBJECT (keys->edit_widget), EGG_CELL_RENDERER_TEXT_PATH,
                          g_strdup (path), g_free);

  gtk_widget_show_all (keys->edit_widget);

  g_signal_connect (G_OBJECT (keys->edit_widget), "unrealize",
                    G_CALLBACK (ungrab_stuff), keys);

  keys->edit_key = keys->accel_key;

  return GTK_CELL_EDITABLE (keys->edit_widget);
}
static gboolean grab_key_callback(GtkWidget* widget, GdkEventKey* event, void* data)
{
	GdkModifierType accel_mods = 0;
	guint accel_keyval;
	EggCellRendererKeys *keys;
	char *path;
	gboolean edited;
	gboolean cleared;
	GdkModifierType consumed_modifiers;
	guint upper;
	GdkModifierType ignored_modifiers;
	GdkDisplay *display;
	GdkSeat *seat;

	keys = EGG_CELL_RENDERER_KEYS(data);

	if (is_modifier(event->hardware_keycode))
	{
		return TRUE;
	}

	edited = FALSE;
	cleared = FALSE;

	consumed_modifiers = 0;
	gdk_keymap_translate_keyboard_state (gdk_keymap_get_for_display (gdk_display_get_default ()),
		event->hardware_keycode,
		event->state,
		event->group,
		NULL, NULL, NULL, &consumed_modifiers);

	upper = event->keyval;
	accel_keyval = gdk_keyval_to_lower(upper);

	if (accel_keyval == GDK_KEY_ISO_Left_Tab)
	{
		accel_keyval = GDK_KEY_Tab;
	}

	/* Put shift back if it changed the case of the key, not otherwise. */
	if (upper != accel_keyval && (consumed_modifiers & GDK_SHIFT_MASK))
	{
		consumed_modifiers &= ~(GDK_SHIFT_MASK);
	}

	egg_keymap_resolve_virtual_modifiers (gdk_keymap_get_for_display (gdk_display_get_default ()),
		EGG_VIRTUAL_NUM_LOCK_MASK |
		EGG_VIRTUAL_SCROLL_LOCK_MASK |
		EGG_VIRTUAL_LOCK_MASK,
		&ignored_modifiers);

	/* http://bugzilla.gnome.org/show_bug.cgi?id=139605
	 * mouse keys should effect keybindings */
	ignored_modifiers |= GDK_BUTTON1_MASK |
		GDK_BUTTON2_MASK |
		GDK_BUTTON3_MASK |
		GDK_BUTTON4_MASK |
		GDK_BUTTON5_MASK;

	/* filter consumed/ignored modifiers */
	if (keys->accel_mode == EGG_CELL_RENDERER_KEYS_MODE_GTK)
	{
		accel_mods = event->state & GDK_MODIFIER_MASK & ~(consumed_modifiers | ignored_modifiers);
	}
	else if (keys->accel_mode == EGG_CELL_RENDERER_KEYS_MODE_X)
	{
		accel_mods = event->state & GDK_MODIFIER_MASK & ~(ignored_modifiers);
	}
	else
	{
		g_assert_not_reached();
	}

	if (accel_mods == 0 && accel_keyval == GDK_KEY_Escape)
	{
		goto out; /* cancel */
	}

	/* clear the accelerator on Backspace */
	if (accel_mods == 0 && accel_keyval == GDK_KEY_BackSpace)
	{
		cleared = TRUE;
		goto out;
	}

	if (keys->accel_mode == EGG_CELL_RENDERER_KEYS_MODE_GTK)
	{
		if (!gtk_accelerator_valid (accel_keyval, accel_mods))
		{
			accel_keyval = 0;
			accel_mods = 0;
		}
	}

	edited = TRUE;

	out:

	display = gtk_widget_get_display (widget);
	seat = gdk_display_get_default_seat (display);

	gdk_seat_ungrab (seat);

	path = g_strdup(g_object_get_data(G_OBJECT(keys->edit_widget), EGG_CELL_RENDERER_TEXT_PATH));

	gtk_cell_editable_editing_done(GTK_CELL_EDITABLE(keys->edit_widget));
	gtk_cell_editable_remove_widget(GTK_CELL_EDITABLE(keys->edit_widget));
	keys->edit_widget = NULL;
	keys->grab_widget = NULL;

	if (edited)
	{
		g_signal_emit_by_name(G_OBJECT(keys), "accel_edited", path, accel_keyval, accel_mods, event->hardware_keycode);
	}
	else if (cleared)
	{
		g_signal_emit_by_name(G_OBJECT(keys), "accel_cleared", path);
	}

	g_free (path);
	return TRUE;
}