示例#1
0
/*!
 \brief handles configure events when the chart gets created or resized.
 Takes care of creating/destroying graphics contexts, backing pixmaps (two 
 levels are used to split the rendering for speed reasons) colormaps are 
 also created here as well
 \param widget is the pointer to the chart object
 \param event is the pointer to the GdkEventConfigure structure that
 encodes important info like window dimensions and depth.
 \returns TRUE on success, FALSE otherwise
 */
gboolean mtx_stripchart_configure (GtkWidget *widget, GdkEventConfigure *event)
{
	MtxStripChart * chart = MTX_STRIPCHART(widget);
	MtxStripChartPrivate *priv = NULL;
	cairo_t *cr = NULL;
	GtkAllocation allocation;
	GdkWindow *window = gtk_widget_get_window(widget);

	g_return_val_if_fail(MTX_IS_STRIPCHART(widget),FALSE);
	gtk_widget_get_allocation(widget,&allocation);
	priv = MTX_STRIPCHART_GET_PRIVATE(chart);

	priv->w = allocation.width;
	priv->h = allocation.height;

	/* Backing pixmap (copy of window) */

	if (priv->bg_pixmap)
		g_object_unref(priv->bg_pixmap);
	priv->bg_pixmap=gdk_pixmap_new(window,
			priv->w,priv->h,
			gtk_widget_get_visual(widget)->depth);
	cr = gdk_cairo_create(priv->bg_pixmap);
	cairo_set_operator(cr,CAIRO_OPERATOR_DEST_OUT);
	cairo_paint(cr);
	cairo_destroy(cr);
	/* Trace pixmap */

	if (priv->trace_pixmap)
		g_object_unref(priv->trace_pixmap);
	priv->trace_pixmap=gdk_pixmap_new(window,
			priv->w,priv->h,
			gtk_widget_get_visual(widget)->depth);
	cr = gdk_cairo_create(priv->trace_pixmap);
	cairo_set_operator(cr,CAIRO_OPERATOR_DEST_OUT);
	cairo_paint(cr);
	cairo_destroy(cr);
	/* Grat pixmap */

	if (priv->grat_pixmap)
		g_object_unref(priv->grat_pixmap);
	priv->grat_pixmap=gdk_pixmap_new(window,
			priv->w,priv->h,
			gtk_widget_get_visual(widget)->depth);
	cr = gdk_cairo_create(priv->grat_pixmap);
	cairo_set_operator(cr,CAIRO_OPERATOR_DEST_OUT);
	cairo_paint(cr);
	cairo_destroy(cr);

	gdk_window_set_back_pixmap(window,priv->bg_pixmap,0);

	if (priv->font_options)
		cairo_font_options_destroy(priv->font_options);
	priv->font_options = cairo_font_options_create();
	cairo_font_options_set_antialias(priv->font_options,
			CAIRO_ANTIALIAS_GRAY);

	generate_stripchart_static_traces(chart);
	render_marker (chart);

	return TRUE;
}
示例#2
0
void
_ide_frame_transfer (IdeFrame *self,
                     IdeFrame *dest,
                     IdePage  *page)
{
  IdeFramePrivate *priv = ide_frame_get_instance_private (self);
  IdeFramePrivate *dest_priv = ide_frame_get_instance_private (dest);
  const GdkRGBA *fg;
  const GdkRGBA *bg;

  g_return_if_fail (IDE_IS_FRAME (self));
  g_return_if_fail (IDE_IS_FRAME (dest));
  g_return_if_fail (IDE_IS_PAGE (page));
  g_return_if_fail (GTK_WIDGET (priv->stack) == gtk_widget_get_parent (GTK_WIDGET (page)));

  /*
   * Inform the destination stack about our new primary colors so that it can
   * begin a transition to the new colors. We also want to do this upfront so
   * that we can reduce the amount of style invalidation caused during the
   * transitions.
   */

  fg = ide_page_get_primary_color_fg (page);
  bg = ide_page_get_primary_color_bg (page);
  _ide_frame_header_set_foreground_rgba (dest_priv->header, fg);
  _ide_frame_header_set_background_rgba (dest_priv->header, bg);

  /*
   * If both the old and the new stacks are mapped, we can animate
   * between them using a snapshot of the page. Well, we also need
   * to be sure they have a valid allocation, but that check is done
   * slightly after this because it makes things easier.
   */
  if (gtk_widget_get_mapped (GTK_WIDGET (self)) &&
      gtk_widget_get_mapped (GTK_WIDGET (dest)) &&
      gtk_widget_get_mapped (GTK_WIDGET (page)))
    {
      GtkAllocation alloc, dest_alloc;
      cairo_surface_t *surface = NULL;
      GdkWindow *window;
      GtkWidget *grid;
      gboolean enable_animations;

      grid = gtk_widget_get_ancestor (GTK_WIDGET (self), IDE_TYPE_GRID);

      gtk_widget_get_allocation (GTK_WIDGET (page), &alloc);
      gtk_widget_get_allocation (GTK_WIDGET (dest), &dest_alloc);

      g_object_get (gtk_settings_get_default (),
                    "gtk-enable-animations", &enable_animations,
                    NULL);

      if (enable_animations &&
          grid != NULL &&
          !is_uninitialized (&alloc) &&
          !is_uninitialized (&dest_alloc) &&
          dest_alloc.width > 0 && dest_alloc.height > 0 &&
          NULL != (window = gtk_widget_get_window (GTK_WIDGET (page))) &&
          NULL != (surface = gdk_window_create_similar_surface (window,
                                                                CAIRO_CONTENT_COLOR,
                                                                alloc.width,
                                                                alloc.height)))
        {
          DzlBoxTheatric *theatric = NULL;
          AnimationState *state;
          cairo_t *cr;

          cr = cairo_create (surface);
          gtk_widget_draw (GTK_WIDGET (page), cr);
          cairo_destroy (cr);

          gtk_widget_translate_coordinates (GTK_WIDGET (priv->stack), grid, 0, 0,
                                            &alloc.x, &alloc.y);
          gtk_widget_translate_coordinates (GTK_WIDGET (dest_priv->stack), grid, 0, 0,
                                            &dest_alloc.x, &dest_alloc.y);

          theatric = g_object_new (DZL_TYPE_BOX_THEATRIC,
                                   "surface", surface,
                                   "height", alloc.height,
                                   "target", grid,
                                   "width", alloc.width,
                                   "x", alloc.x,
                                   "y", alloc.y,
                                   NULL);

          state = g_slice_new0 (AnimationState);
          state->source = g_object_ref (self);
          state->dest = g_object_ref (dest);
          state->page = g_object_ref (page);
          state->theatric = theatric;

          dzl_object_animate_full (theatric,
                                   DZL_ANIMATION_EASE_IN_OUT_CUBIC,
                                   TRANSITION_DURATION,
                                   gtk_widget_get_frame_clock (GTK_WIDGET (self)),
                                   animation_state_complete,
                                   state,
                                   "x", dest_alloc.x,
                                   "width", dest_alloc.width,
                                   "y", dest_alloc.y,
                                   "height", dest_alloc.height,
                                   NULL);

          /*
           * Mark the page as in-transition so that when we remove it
           * we can ignore the items-changed until the animation completes.
           */
          g_ptr_array_add (priv->in_transition, g_object_ref (page));
          gtk_container_remove (GTK_CONTAINER (priv->stack), GTK_WIDGET (page));

          cairo_surface_destroy (surface);

          return;
        }
    }

  g_object_ref (page);
  gtk_container_remove (GTK_CONTAINER (priv->stack), GTK_WIDGET (page));
  gtk_container_add (GTK_CONTAINER (dest_priv->stack), GTK_WIDGET (page));
  g_object_unref (page);
}
示例#3
0
static void
ide_frame_pan_end (IdeFrame         *self,
                   GdkEventSequence *sequence,
                   GtkGesturePan    *gesture)
{
  IdeFramePrivate *priv = ide_frame_get_instance_private (self);
  IdeFramePrivate *dest_priv;
  IdeFrame *dest;
  GtkAllocation alloc;
  GtkWidget *grid;
  GtkWidget *column;
  gdouble x, y;
  gint direction;
  gint index = 0;

  IDE_ENTRY;

  g_assert (IDE_IS_FRAME (self));
  g_assert (GTK_IS_GESTURE_PAN (gesture));

  if (priv->pan_theatric == NULL || priv->pan_page == NULL)
    IDE_GOTO (cleanup);

  gtk_widget_get_allocation (GTK_WIDGET (self), &alloc);

  gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (gesture), &x, &y);

  if (x > DISTANCE_THRESHOLD (&alloc))
    direction = 1;
  else if (x < -DISTANCE_THRESHOLD (&alloc))
    direction = -1;
  else
    direction = 0;

  grid = gtk_widget_get_ancestor (GTK_WIDGET (self), IDE_TYPE_GRID);
  g_assert (grid != NULL);
  g_assert (IDE_IS_GRID (grid));

  column = gtk_widget_get_ancestor (GTK_WIDGET (self), IDE_TYPE_GRID_COLUMN);
  g_assert (column != NULL);
  g_assert (IDE_IS_GRID_COLUMN (column));

  gtk_container_child_get (GTK_CONTAINER (grid), GTK_WIDGET (column),
                           "index", &index,
                           NULL);

  dest = _ide_grid_get_nth_stack (IDE_GRID (grid), index + direction);
  dest_priv = ide_frame_get_instance_private (dest);
  g_assert (dest != NULL);
  g_assert (IDE_IS_FRAME (dest));

  gtk_widget_get_allocation (GTK_WIDGET (dest), &alloc);

  if (!is_uninitialized (&alloc))
    {
      AnimationState *state;

      state = g_slice_new0 (AnimationState);
      state->source = g_object_ref (self);
      state->dest = g_object_ref (dest);
      state->page = g_object_ref (priv->pan_page);
      state->theatric = g_object_ref (priv->pan_theatric);

      gtk_widget_translate_coordinates (GTK_WIDGET (dest_priv->top_stack), grid, 0, 0,
                                        &alloc.x, &alloc.y);

      /*
       * Use EASE_OUT_CUBIC, because user initiated the beginning of the
       * acceleration curve just by swiping. No need to duplicate.
       */
      dzl_object_animate_full (state->theatric,
                               DZL_ANIMATION_EASE_OUT_CUBIC,
                               TRANSITION_DURATION,
                               gtk_widget_get_frame_clock (GTK_WIDGET (self)),
                               animation_state_complete,
                               state,
                               "x", alloc.x,
                               "width", alloc.width,
                               NULL);

      if (dest != self)
        {
          g_ptr_array_add (priv->in_transition, g_object_ref (priv->pan_page));
          gtk_container_remove (GTK_CONTAINER (priv->stack), GTK_WIDGET (priv->pan_page));
        }

      IDE_TRACE_MSG ("Animating transition to %s column",
                     dest != self ? "another" : "same");
    }
  else
    {
      g_autoptr(IdePage) page = g_object_ref (priv->pan_page);

      IDE_TRACE_MSG ("Moving page to a previously non-existant column");

      gtk_container_remove (GTK_CONTAINER (priv->stack), GTK_WIDGET (page));
      gtk_widget_show (GTK_WIDGET (page));
      gtk_container_add (GTK_CONTAINER (dest_priv->stack), GTK_WIDGET (page));
    }

cleanup:
  g_clear_object (&priv->pan_theatric);
  g_clear_object (&priv->pan_page);

  gtk_widget_queue_draw (gtk_widget_get_toplevel (GTK_WIDGET (self)));

  ide_frame_set_cursor (self, "arrow");

  IDE_EXIT;
}
static void
inf_text_gtk_viewport_user_compute_user_area(InfTextGtkViewportUser* user)
{
  InfTextGtkViewportPrivate* priv;
  GtkWidget* textview;
  GtkWidget* scrollbar;
  GtkTextIter iter;
  GdkRectangle rect;
  gint y;
  gint end_y;

  gint scroll_height;
  gint slider_size;
  gint stepper_size;
  gint stepper_spacing;
  gint border;
  GdkRectangle allocation;
  gint scroll_ox;
  gint scroll_oy;
  gint dy;

  priv = INF_TEXT_GTK_VIEWPORT_PRIVATE(user->viewport);

  /* TODO: We might want to skip this if show-user-markers is false. */

  textview = gtk_bin_get_child(GTK_BIN(priv->scroll));
  scrollbar = gtk_scrolled_window_get_vscrollbar(priv->scroll);
#if GTK_CHECK_VERSION(2,20,0)
  if(GTK_IS_TEXT_VIEW(textview) && scrollbar != NULL &&
     gtk_widget_get_realized(textview))
#else
  if(GTK_IS_TEXT_VIEW(textview) && scrollbar != NULL &&
     GTK_WIDGET_REALIZED(textview))
#endif
  {
    gtk_text_buffer_get_iter_at_offset(
      gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)),
      &iter,
      inf_text_user_get_caret_position(user->user)
    );

    gtk_text_view_get_iter_location(GTK_TEXT_VIEW(textview), &iter, &rect);
    y = rect.y;

    gtk_text_buffer_get_end_iter(
      gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)),
      &iter
    );

    gtk_text_view_get_iter_location(GTK_TEXT_VIEW(textview), &iter, &rect);
    end_y = rect.y;

    g_assert(end_y > 0 || y == 0);

    gtk_widget_style_get(
      scrollbar,
      "slider-width", &slider_size,
      "stepper-size", &stepper_size,
      "stepper-spacing", &stepper_spacing,
      "trough-border", &border,
      NULL
    );

#if GTK_CHECK_VERSION(2,18,0)
    gtk_widget_get_allocation(scrollbar, &allocation);
#else
    allocation = scrollbar->allocation;
#endif

    scroll_ox = border;
    scroll_oy = border + stepper_size + stepper_spacing;
    scroll_height = allocation.height - 2*scroll_oy;

    if(end_y > 0)
      y = y * scroll_height / end_y;

    user->rectangle.x = scroll_ox + allocation.x;
    user->rectangle.y = scroll_oy + allocation.y + y - slider_size/3;
    user->rectangle.width = slider_size;
    user->rectangle.height = slider_size*2/3;

    if(user->rectangle.y < scroll_oy + allocation.y)
    {
      dy = scroll_oy + allocation.y - user->rectangle.y;
      user->rectangle.y += dy;
      user->rectangle.height -= dy;
    }

    if(user->rectangle.y + user->rectangle.height >
       scroll_oy + allocation.y + scroll_height)
    {
      user->rectangle.height =
        scroll_oy + allocation.y + scroll_height - user->rectangle.y;
    }
  }
  else
  {
    user->rectangle.x = user->rectangle.y = 0;
    user->rectangle.width = user->rectangle.height = 0;
  }
}
示例#5
0
文件: fish.c 项目: lanoxx/gnome-panel
static void
update_surface (FishApplet *fish)
{
	GtkWidget     *widget = fish->drawing_area;
	GtkRequisition prev_requisition;
	GtkAllocation  allocation;
	int            width  = -1;
	int            height = -1;
	int            pixbuf_width = -1;
	int            pixbuf_height = -1;
	gboolean       rotate = FALSE;
	cairo_t       *cr;
	cairo_matrix_t matrix;
	cairo_pattern_t *pattern;

	gtk_widget_get_allocation (widget, &allocation);

	if (!gtk_widget_get_realized (widget) ||
	    allocation.width <= 0 ||
	    allocation.height <= 0)
		return;

	if (!fish->pixbuf && !load_fish_image (fish))
		return;

	if (fish->rotate &&
	    (fish->orientation == PANEL_APPLET_ORIENT_LEFT ||
	     fish->orientation == PANEL_APPLET_ORIENT_RIGHT))
		rotate = TRUE;

	pixbuf_width  = gdk_pixbuf_get_width  (fish->pixbuf);
	pixbuf_height = gdk_pixbuf_get_height (fish->pixbuf);

	prev_requisition = fish->requisition;

	if (fish->orientation == PANEL_APPLET_ORIENT_UP ||
	    fish->orientation == PANEL_APPLET_ORIENT_DOWN) {
		height = allocation.height;
		width  = pixbuf_width * ((gdouble) height / pixbuf_height);

		fish->requisition.width = width / fish->n_frames;
		fish->requisition.height = height;
	} else {
		if (!rotate) {
			width = allocation.width * fish->n_frames;
			height = pixbuf_height * ((gdouble) width / pixbuf_width);
			fish->requisition.width = allocation.width;
			fish->requisition.height = height;
		} else {
			width = allocation.width;
			height = pixbuf_width * ((gdouble) width / pixbuf_height);
			fish->requisition.width = width;
			fish->requisition.height = height / fish->n_frames;
		}
	}

	if (prev_requisition.width  != fish->requisition.width ||
	    prev_requisition.height != fish->requisition.height) {
		gtk_widget_set_size_request (widget,
					     fish->requisition.width,
					     fish->requisition.height);
	}

	g_assert (width != -1 && height != -1);

	if (width == 0 || height == 0)
		return;

	if (fish->surface)
		cairo_surface_destroy (fish->surface);
	fish->surface = gdk_window_create_similar_surface (
			               gtk_widget_get_window (widget),
			               CAIRO_CONTENT_COLOR_ALPHA,
			               width, height);

	gtk_widget_queue_resize (widget);

	g_assert (pixbuf_width != -1 && pixbuf_height != -1);

	cr = cairo_create (fish->surface);

	cairo_set_source_rgb (cr, 1, 1, 1);
	cairo_paint (cr);

	gdk_cairo_set_source_pixbuf (cr, fish->pixbuf, 0, 0);
	pattern = cairo_get_source (cr);
	cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);

	cairo_matrix_init_identity (&matrix);

	if (fish->april_fools) {
		cairo_matrix_translate (&matrix,
					pixbuf_width - 1, pixbuf_height - 1);
		cairo_matrix_rotate (&matrix, M_PI);
	}

	if (rotate) {
		if (fish->orientation == PANEL_APPLET_ORIENT_RIGHT) {
			cairo_matrix_translate (&matrix, pixbuf_width - 1, 0);
			cairo_matrix_rotate (&matrix, M_PI * 0.5);
		} else {
			cairo_matrix_translate (&matrix, 0, pixbuf_height - 1);
			cairo_matrix_rotate (&matrix, M_PI * 1.5);
		}
		cairo_matrix_scale (&matrix,
				    (double) (pixbuf_height - 1) / width,
				    (double) (pixbuf_width - 1) / height);
	} else {
		cairo_matrix_scale (&matrix,
				    (double) (pixbuf_width - 1) / width,
				    (double) (pixbuf_height - 1) / height);
	}

	cairo_pattern_set_matrix (pattern, &matrix);

	cairo_rectangle (cr, 0, 0, width, height);
	cairo_fill (cr);

	if (fish->april_fools) {
		cairo_set_source_rgb (cr, 1, 0.5, 0);
		cairo_paint_with_alpha (cr, 0.25);
	}

	cairo_destroy (cr);
}
示例#6
0
static gboolean dt_iop_basecurve_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_basecurve_params_t *p = (dt_iop_basecurve_params_t *)self->params;
  dt_iop_basecurve_params_t *d = (dt_iop_basecurve_params_t *)self->default_params;
  dt_iop_basecurve_gui_data_t *c = (dt_iop_basecurve_gui_data_t *)self->gui_data;

  int ch = 0;
  int nodes = p->basecurve_nodes[ch];
  dt_iop_basecurve_node_t *basecurve = p->basecurve[ch];

  if(event->button == 1)
  {
    if(event->type == GDK_BUTTON_PRESS && (event->state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK
      && nodes < MAXNODES && c->selected == -1)
    {
      // if we are not on a node -> add a new node at the current x of the pointer and y of the curve at that x
      const int inset = DT_GUI_CURVE_EDITOR_INSET;
      GtkAllocation allocation;
      gtk_widget_get_allocation(widget, &allocation);
      int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset;
      c->mouse_x = CLAMP(event->x - inset, 0, width);
      c->mouse_y = CLAMP(event->y - inset, 0, height);

      const float mx = c->mouse_x / (float)width;
      const float linx = to_lin(mx, c->loglogscale);

      // don't add a node too close to others in x direction, it can crash dt
      int selected = -1;
      if(basecurve[0].x > linx)
        selected = 0;
      else
      {
        for(int k = 1; k < nodes; k++)
        {
          if(basecurve[k].x > linx)
          {
            selected = k;
            break;
          }
        }
      }
      if(selected == -1) selected = nodes;
      // > 0 -> check distance to left neighbour
      // < nodes -> check distance to right neighbour
      if(!((selected > 0 && linx - basecurve[selected - 1].x <= 0.025) ||
           (selected < nodes && basecurve[selected].x - linx <= 0.025)))
      {
        // evaluate the curve at the current x position
        const float y = dt_draw_curve_calc_value(c->minmax_curve, linx);

        if(y >= 0.0 && y <= 1.0) // never add something outside the viewport, you couldn't change it afterwards
        {
          // create a new node
          int selected = _add_node(basecurve, &p->basecurve_nodes[ch], linx, y);

          // maybe set the new one as being selected
          float min = .04f;
          min *= min; // comparing against square
          for(int k = 0; k < nodes; k++)
          {
            float other_y = to_log(basecurve[k].y, c->loglogscale);
            float dist = (y - other_y) * (y - other_y);
            if(dist < min) c->selected = selected;
          }

          dt_dev_add_history_item(darktable.develop, self, TRUE);
          gtk_widget_queue_draw(self->widget);
        }
      }
      return TRUE;
    }
    else if(event->type == GDK_2BUTTON_PRESS)
    {
      // reset current curve
      p->basecurve_nodes[ch] = d->basecurve_nodes[ch];
      p->basecurve_type[ch] = d->basecurve_type[ch];
      for(int k = 0; k < d->basecurve_nodes[ch]; k++)
      {
        p->basecurve[ch][k].x = d->basecurve[ch][k].x;
        p->basecurve[ch][k].y = d->basecurve[ch][k].y;
      }
      c->selected = -2; // avoid motion notify re-inserting immediately.
      dt_dev_add_history_item(darktable.develop, self, TRUE);
      gtk_widget_queue_draw(self->widget);
      return TRUE;
    }
  }
  return FALSE;
}
示例#7
0
static void
gimp_tag_popup_constructed (GObject *object)
{
  GimpTagPopup        *popup = GIMP_TAG_POPUP (object);
  GimpTaggedContainer *container;
  GtkWidget           *entry;
  GtkAllocation        entry_allocation;
  GtkStyle            *frame_style;
  gint                 x;
  gint                 y;
  gint                 width;
  gint                 height;
  gint                 popup_height;
  GHashTable          *tag_hash;
  GList               *tag_list;
  GList               *tag_iterator;
  gint                 i;
  gint                 max_height;
  gint                 screen_height;
  gchar              **current_tags;
  gint                 current_count;
  GdkRectangle         popup_rects[2]; /* variants of popup placement */
  GdkRectangle         popup_rect; /* best popup rect in screen coordinates */

  if (G_OBJECT_CLASS (parent_class)->constructed)
    G_OBJECT_CLASS (parent_class)->constructed (object);

  entry = GTK_WIDGET (popup->combo_entry);

  gtk_window_set_screen (GTK_WINDOW (popup), gtk_widget_get_screen (entry));

  popup->context = gtk_widget_create_pango_context (GTK_WIDGET (popup));
  popup->layout  = pango_layout_new (popup->context);

  gtk_widget_get_allocation (entry, &entry_allocation);

  gtk_widget_style_get (GTK_WIDGET (popup),
                        "scroll-arrow-vlength", &popup->scroll_arrow_height,
                        NULL);

  pango_layout_set_attributes (popup->layout,
                               popup->combo_entry->normal_item_attr);

  current_tags  = gimp_tag_entry_parse_tags (GIMP_TAG_ENTRY (popup->combo_entry));
  current_count = g_strv_length (current_tags);

  container = GIMP_TAG_ENTRY (popup->combo_entry)->container;

  tag_hash = container->tag_ref_counts;
  tag_list = g_hash_table_get_keys (tag_hash);
  tag_list = g_list_sort (tag_list, gimp_tag_compare_func);

  popup->tag_count = g_list_length (tag_list);
  popup->tag_data  = g_new0 (PopupTagData, popup->tag_count);

  for (i = 0, tag_iterator = tag_list;
       i < popup->tag_count;
       i++, tag_iterator = g_list_next (tag_iterator))
    {
      PopupTagData *tag_data = &popup->tag_data[i];
      gint          j;

      tag_data->tag   = tag_iterator->data;
      tag_data->state = GTK_STATE_NORMAL;

      g_object_ref (tag_data->tag);

      for (j = 0; j < current_count; j++)
        {
          if (! gimp_tag_compare_with_string (tag_data->tag, current_tags[j]))
            {
              tag_data->state = GTK_STATE_SELECTED;
              break;
            }
        }
    }

  g_list_free (tag_list);
  g_strfreev (current_tags);

  if (GIMP_TAG_ENTRY (popup->combo_entry)->mode == GIMP_TAG_ENTRY_MODE_QUERY)
    {
      for (i = 0; i < popup->tag_count; i++)
        {
          if (popup->tag_data[i].state != GTK_STATE_SELECTED)
            {
              popup->tag_data[i].state = GTK_STATE_INSENSITIVE;
            }
        }

      gimp_container_foreach (GIMP_CONTAINER (container),
                              (GFunc) gimp_tag_popup_check_can_toggle,
                              popup);
    }

  frame_style = gtk_widget_get_style (popup->frame);

  width  = (entry_allocation.width -
            2 * frame_style->xthickness);
  height = (gimp_tag_popup_layout_tags (popup, width) +
            2 * frame_style->ythickness);

  gdk_window_get_origin (gtk_widget_get_window (entry), &x, &y);

  max_height = entry_allocation.height * 10;

  screen_height = gdk_screen_get_height (gtk_widget_get_screen (entry));

  popup_height = MIN (height, max_height);

  popup_rects[0].x      = x;
  popup_rects[0].y      = 0;
  popup_rects[0].width  = entry_allocation.width;
  popup_rects[0].height = y + entry_allocation.height;

  popup_rects[1].x      = x;
  popup_rects[1].y      = y;
  popup_rects[1].width  = popup_rects[0].width;
  popup_rects[1].height = screen_height - popup_rects[0].height;

  if (popup_rects[0].height >= popup_height)
    {
      popup_rect = popup_rects[0];
      popup_rect.y += popup_rects[0].height - popup_height;
      popup_rect.height = popup_height;
    }
  else if (popup_rects[1].height >= popup_height)
    {
      popup_rect = popup_rects[1];
      popup_rect.height = popup_height;
    }
  else
    {
      if (popup_rects[0].height >= popup_rects[1].height)
        {
          popup_rect = popup_rects[0];
          popup_rect.y += popup->scroll_arrow_height + frame_style->ythickness;
        }
      else
        {
          popup_rect = popup_rects[1];
          popup_rect.y -= popup->scroll_arrow_height + frame_style->ythickness;
        }

      popup_height = popup_rect.height;
    }

  if (popup_height < height)
    {
      popup->arrows_visible    = TRUE;
      popup->upper_arrow_state = GTK_STATE_INSENSITIVE;

      gtk_alignment_set_padding (GTK_ALIGNMENT (popup->alignment),
                                 popup->scroll_arrow_height + 2,
                                 popup->scroll_arrow_height + 2, 0, 0);

      popup_height -= 2 * popup->scroll_arrow_height + 4;

      popup->scroll_height = height - popup_rect.height;
      popup->scroll_y      = 0;
      popup->scroll_step   = 0;
    }

  gtk_widget_set_size_request (popup->tag_area, width, popup_height);

  gtk_window_move (GTK_WINDOW (popup), popup_rect.x, popup_rect.y);
  gtk_window_resize (GTK_WINDOW (popup), popup_rect.width, popup_rect.height);
}
示例#8
0
文件: tray.c 项目: b4283/hime
void load_tray_icon()
{
//  dbg("load_tray_icon\n");
  if (!hime_status_tray)
    return;

  if (!da)
    create_tray(NULL);

  char *iconame = inmd[current_CS->in_method].icon;
  char fname[512];

  fname[0]=0;

  if (iconame)
    get_icon_path(iconame, fname);

#if GTK_CHECK_VERSION(2,17,7)
  GtkAllocation dwdh;
  gtk_widget_get_allocation(da, &dwdh);
  int dw = dwdh.width, dh = dwdh.height;
#else
    int dw = da->allocation.width, dh = da->allocation.height;
#endif

  if (!pixbuf || gdk_pixbuf_get_width (pixbuf) != dw || gdk_pixbuf_get_height (pixbuf) != dh) {
    char icon_fname[128];
    get_icon_path(HIME_TRAY_PNG, icon_fname);
    GError *err = NULL;
//    dbg("icon_name %s\n", icon_fname);
    pixbuf = gdk_pixbuf_new_from_file_at_size(icon_fname, dw, dh, &err);
    //Reduce troublesome when hime-tray.png does not exist
    //if (!pixbuf)
    //  p_err("cannot load file %s", icon_fname);
  }

#if 0
  dbg("fname %x %s\n", fname, fname);
#endif
  if (!fname[0]) {
    if (pixbuf_ch)
      g_object_unref(pixbuf_ch);

    pixbuf_ch = NULL;
    if (pixbuf_ch_fname)
      pixbuf_ch_fname[0] = 0;
  } else
  if (!pixbuf_ch_fname || strcmp(fname, pixbuf_ch_fname)) {
    free(pixbuf_ch_fname);
    pixbuf_ch_fname = strdup(fname);

    if (pixbuf_ch)
      g_object_unref(pixbuf_ch);

    dbg("ch %s\n", fname);
    GError *err = NULL;
    pixbuf_ch = gdk_pixbuf_new_from_file_at_size(fname, dw, dh, &err);
  }

  update_tray_icon();
}
示例#9
0
文件: tray.c 项目: b4283/hime
static void draw_icon()
{
  gboolean tsin_pho_mode();
//  dbg("draw_icon\n");

  if (!da)
    return;

  GdkPixbuf *pix =  ((! current_CS) ||
                     (current_CS->im_state != HIME_STATE_CHINESE)) ?
                    pixbuf : pixbuf_ch;

#if GTK_CHECK_VERSION(2,17,7)
  GtkAllocation dwdh;
  gtk_widget_get_allocation(da, &dwdh);
  int dw = dwdh.width, dh = dwdh.height;
#else
  int dw = da->allocation.width, dh = da->allocation.height;
#endif
  int w, h;

  GdkColor color_fg;


//  dbg("wh %d,%d\n", dw,dh);

  gdk_color_parse("black", &color_fg);
#if !GTK_CHECK_VERSION(2,90,6)
  gdk_gc_set_rgb_fg_color(gc, &color_fg);
#else
  gc = gdk_cairo_create (tray_da_win);
  gdk_cairo_set_source_color (gc, &color_fg);
#endif

  if (pix) {
    int ofs = (dh - gdk_pixbuf_get_height (pix))/2;
#if !GTK_CHECK_VERSION(2,90,6)
    gdk_draw_pixbuf(tray_da_win, NULL, pix, 0, 0, 0, ofs, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0);
#else
    gdk_cairo_set_source_pixbuf (gc, pix, 0, ofs);
    cairo_paint (gc);
    cairo_destroy (gc);
#endif
  } else {
    get_text_w_h(inmd[current_CS->in_method].cname, &w, &h);
#if !GTK_CHECK_VERSION(2,90,6)
    gdk_draw_layout(tray_da_win, gc, 0, 0, pango);
#else
    cairo_move_to (gc, 0, 0);
    pango_cairo_show_layout (gc, pango);
    cairo_destroy (gc);
#endif
  }

  if (current_CS) {
    if (current_CS->b_half_full_char || (
#if USE_TSIN
        current_method_type()==method_type_TSIN && tss.tsin_half_full &&
#endif
        current_CS->im_state == HIME_STATE_CHINESE)) {
      static char full[] = N_("全");
      get_text_w_h(full,  &w, &h);
#if !GTK_CHECK_VERSION(2,90,6)
      gdk_draw_layout(tray_da_win, gc, dw - w, dh - h, pango);
#else
      cairo_move_to (gc, dw - w, dh - h);
      pango_cairo_show_layout (gc, pango);
      cairo_destroy (gc);
#endif
    }

    if (current_CS->im_state == HIME_STATE_ENG_FULL) {
      static char efull[] = N_("A全");
      get_text_w_h(efull,  &w, &h);
#if !GTK_CHECK_VERSION(2,90,6)
      gdk_draw_layout(tray_da_win, gc, 0, 0, pango);
#else
      cairo_move_to (gc, 0, 0);
      pango_cairo_show_layout (gc, pango);
      cairo_destroy (gc);
#endif
    }
#if USE_TSIN
    if (((current_method_type()==method_type_TSIN) || (current_method_type()==method_type_MODULE)) &&
        (current_CS->im_state == HIME_STATE_CHINESE) &&
	 (! tsin_pho_mode())) {
      static char efull[] = "ABC";
      gdk_color_parse("blue", &color_fg);
#if !GTK_CHECK_VERSION(2,90,6)
      gdk_gc_set_rgb_fg_color(gc, &color_fg);
#else
      gc = gdk_cairo_create (tray_da_win);
      gdk_cairo_set_source_color (gc, &color_fg);
#endif

      get_text_w_h(efull,  &w, &h);
#if !GTK_CHECK_VERSION(2,90,6)
      gdk_draw_layout(tray_da_win, gc, 0, 0, pango);
#else
      cairo_move_to (gc, 0, 0);
      pango_cairo_show_layout (gc, pango);
      cairo_destroy (gc);
#endif
    }
#endif
  }

  gdk_color_parse("red", &color_fg);
#if !GTK_CHECK_VERSION(2,90,6)
  gdk_gc_set_rgb_fg_color(gc, &color_fg);
#else
  gc = gdk_cairo_create (tray_da_win);
  gdk_cairo_set_source_color (gc, &color_fg);
#endif

  if (gb_output) {
    static char sim[] = "简";
    get_text_w_h(sim,  &w, &h);
#if !GTK_CHECK_VERSION(2,90,6)
    gdk_draw_layout(tray_da_win, gc, 0, dh - h, pango);
#else
    cairo_move_to (gc, 0, dh - h);
    pango_cairo_show_layout (gc, pango);
    cairo_destroy (gc);
#endif
  }

}
示例#10
0
bool
sc_adjust_window(girara_session_t* session, girara_argument_t* argument,
                 girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);

  unsigned int pages_per_row = 1;
  girara_setting_get(session, "pages-per-row", &pages_per_row);

  unsigned int first_page_column = 1;
  girara_setting_get(session, "first-page-column", &first_page_column);

  int padding = 1;
  girara_setting_get(zathura->ui.session, "page-padding", &padding);

  if (zathura->ui.page_widget == NULL || zathura->document == NULL) {
    goto error_ret;
  }

  zathura_document_set_adjust_mode(zathura->document, argument->n);
  if (argument->n == ZATHURA_ADJUST_NONE) {
    /* there is nothing todo */
    goto error_ret;
  }

  /* get window size */
  GtkAllocation allocation;
  gtk_widget_get_allocation(session->gtk.view, &allocation);
  unsigned int width  = allocation.width;
  unsigned int height = allocation.height;

  /* scrollbar spacing */
  gint spacing;
  gtk_widget_style_get(session->gtk.view, "scrollbar_spacing", &spacing, NULL);
  width -= spacing;

  /* correct view size */
  if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.inputbar)) == true) {
    gtk_widget_get_allocation(session->gtk.inputbar, &allocation);
    height += allocation.height;
  }

  double scale = 1.0;
  unsigned int cell_height = 0, cell_width = 0;
  unsigned int document_height = 0, document_width = 0;

  zathura_document_set_scale(zathura->document, scale);
  zathura_document_get_cell_size(zathura->document, &cell_height, &cell_width);
  zathura_get_document_size(zathura, cell_height, cell_width,
                            &document_height, &document_width);

  double page_ratio   = (double)cell_height / (double)document_width;
  double window_ratio = (double)height / (double)width;

  if (argument->n == ZATHURA_ADJUST_WIDTH ||
      (argument->n == ZATHURA_ADJUST_BESTFIT && page_ratio < window_ratio)) {
    scale = (double)(width - (pages_per_row - 1) * padding) /
            (double)(pages_per_row * cell_width);
    zathura_document_set_scale(zathura->document, scale);

    bool show_scrollbars = false;
    girara_setting_get(session, "show-scrollbars", &show_scrollbars);

    if (show_scrollbars) {
      /* If the document is taller than the view, there's a vertical
       * scrollbar; we need to substract its width from the view's width. */
      zathura_get_document_size(zathura, cell_height, cell_width,
                                &document_height, &document_width);
      if (height < document_height) {
        GtkWidget* vscrollbar = gtk_scrolled_window_get_vscrollbar(
            GTK_SCROLLED_WINDOW(session->gtk.view));

        if (vscrollbar != NULL) {
          GtkRequisition requisition;
          gtk_widget_get_requisition(vscrollbar, &requisition);
          if (0 < requisition.width && (unsigned)requisition.width < width) {
            width -= requisition.width;
            scale = (double)(width - (pages_per_row - 1) * padding) /
                    (double)(pages_per_row * cell_width);
            zathura_document_set_scale(zathura->document, scale);
          }
        }
      }
    }
  }
  else if (argument->n == ZATHURA_ADJUST_BESTFIT) {
    scale = (double)height / (double)cell_height;
    zathura_document_set_scale(zathura->document, scale);
  }
  else {
    goto error_ret;
  }

  /* re-render all pages */
  render_all(zathura);

error_ret:

  return false;
}
示例#11
0
static gboolean _gradient_slider_expose(GtkWidget *widget, GdkEventExpose *event)
{
  GtkDarktableGradientSlider *gslider=DTGTK_GRADIENT_SLIDER(widget);

  assert(gslider->position > 0);

  g_return_val_if_fail(widget != NULL, FALSE);
  g_return_val_if_fail(DTGTK_IS_GRADIENT_SLIDER(widget), FALSE);
  g_return_val_if_fail(event != NULL, FALSE);
  GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkButton", GTK_TYPE_BUTTON);
  if(!style) style = gtk_rc_get_style(widget);
  int state = gtk_widget_get_state(widget);

  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  /*int x = allocation.x;
  int y = allocation.y;*/
  int width = allocation.width;
  int height = allocation.height;
  int margins = gslider->margins;

  // Begin cairo drawing
  cairo_t *cr;
  cr = gdk_cairo_create(gtk_widget_get_window(widget));

  // First build the cairo gradient and then fill the gradient
  float gheight=height/2.0;
  float gwidth=width-2*margins;
  GList *current=NULL;
  cairo_pattern_t *gradient=NULL;
  if((current=g_list_first(gslider->colors)) != NULL)
  {
    gradient=cairo_pattern_create_linear(0,0,gwidth,gheight);
    do
    {
      _gradient_slider_stop_t *stop=(_gradient_slider_stop_t *)current->data;
      cairo_pattern_add_color_stop_rgb(gradient,stop->position,stop->color.red/65535.0,stop->color.green/65535.0,stop->color.blue/65535.0);
    }
    while((current=g_list_next(current))!=NULL);
  }

  if(gradient!=NULL) // Do we got a gradient, lets draw it
  {
    cairo_set_line_width(cr,0.1);
    cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND);
    cairo_set_source(cr,gradient);
    cairo_rectangle(cr,margins,(height-gheight)/2.0,gwidth,gheight);
    cairo_fill(cr);
    cairo_stroke(cr);
  }



  // Lets draw position arrows

  cairo_set_source_rgba(cr,
                        style->fg[state].red/65535.0,
                        style->fg[state].green/65535.0,
                        style->fg[state].blue/65535.0,
                        1.0
                       );


  // do we have a picker value to draw?
  gdouble *picker = gslider->picker;
  if(picker[0] >= 0.0 && picker[0] <= 1.0)
  {
    int vx_min=_scale_to_screen(widget, picker[1]);
    int vx_max=_scale_to_screen(widget, picker[2]);
    int vx_avg=_scale_to_screen(widget, picker[0]);

    cairo_set_source_rgba(cr,
                          style->fg[state].red/65535.0,
                          style->fg[state].green/65535.0,
                          style->fg[state].blue/65535.0,
                          0.33
                         );

    cairo_rectangle(cr,vx_min,(height-gheight)/2.0,fmax((float)vx_max-vx_min, 0.0f),gheight);
    cairo_fill(cr);

    cairo_set_source_rgba(cr,
                          style->fg[state].red/65535.0,
                          style->fg[state].green/65535.0,
                          style->fg[state].blue/65535.0,
                          1.0
                         );

    cairo_move_to(cr,vx_avg,(height-gheight)/2.0);
    cairo_line_to(cr,vx_avg,(height+gheight)/2.0);
    cairo_set_antialias(cr,CAIRO_ANTIALIAS_NONE);
    cairo_set_line_width(cr,1.0);
    cairo_stroke(cr);
  }

  int indirect[GRADIENT_SLIDER_MAX_POSITIONS];
  for(int k=0; k<gslider->positions; k++)
    indirect[k] = gslider->selected == -1 ? k : (gslider->selected + 1 + k) % gslider->positions;


  for(int k=0; k<gslider->positions; k++)
  {
    int l = indirect[k];
    int vx=_scale_to_screen(widget, gslider->position[l]);
    int mk=gslider->marker[l];
    int sz=(mk & (1<<3)) ? 13 : 10;  // big or small marker?

    if(l == gslider->selected && (gslider->is_entered == TRUE || gslider->is_dragging == TRUE))
    {
      cairo_set_source_rgba(cr,
                            style->fg[state].red/65535.0,
                            style->fg[state].green/65535.0,
                            style->fg[state].blue/65535.0 * 0.5,
                            1.0
                           );

    }
    else
    {
      cairo_set_source_rgba(cr,
                            style->fg[state].red/65535.0*0.8,
                            style->fg[state].green/65535.0*0.8,
                            style->fg[state].blue/65535.0*0.8,
                            1.0
                           );
    }


    cairo_set_antialias(cr,CAIRO_ANTIALIAS_DEFAULT);

    if(mk & 0x04) /* upper arrow */
    {
      if (mk & 0x01) /* filled */
        dtgtk_cairo_paint_solid_triangle(cr, vx-sz/2, sz < 10 ? 1 : -2,sz,sz,CPF_DIRECTION_DOWN);
      else
        dtgtk_cairo_paint_triangle(cr, vx-sz/2, sz < 10 ? 1 : -2,sz,sz,CPF_DIRECTION_DOWN);
    }

    if(mk & 0x02) /* lower arrow */
    {
      if (mk & 0x01) /* filled */
        dtgtk_cairo_paint_solid_triangle(cr, vx-sz/2,sz < 10 ? height-6 : height-11,sz,sz,CPF_DIRECTION_UP);
      else
        dtgtk_cairo_paint_triangle(cr, vx-sz/2,sz < 10 ? height-6 : height-11,sz,sz,CPF_DIRECTION_UP);
    }
  }

  cairo_destroy(cr);
  return FALSE;
}
示例#12
0
static void
wrap_table_layout (EelWrapTable *wrap_table)
{
    GList *iterator;
    EelIPoint pos;
    EelDimensions max_child_dimensions;
    EelIRect content_bounds;
    guint num_cols;
    GtkAllocation allocation;

    g_assert (EEL_IS_WRAP_TABLE (wrap_table));

    max_child_dimensions = wrap_table_get_max_child_dimensions (wrap_table);
    max_child_dimensions.width = MAX (max_child_dimensions.width, 1);
    max_child_dimensions.height = MAX (max_child_dimensions.height, 1);

    content_bounds = wrap_table_get_content_bounds (wrap_table);
    pos.x = content_bounds.x0;
    pos.y = content_bounds.y0;

    gtk_widget_get_allocation (GTK_WIDGET (wrap_table), &allocation);
    num_cols = wrap_table_get_num_fitting (allocation.width -
                                           gtk_container_get_border_width (GTK_CONTAINER (wrap_table)) * 2,
                                           wrap_table->details->x_spacing,
                                           max_child_dimensions.width);
    if (num_cols != wrap_table->details->cols)
    {
        wrap_table->details->cols = num_cols;
        gtk_widget_queue_resize (GTK_WIDGET (wrap_table));
        return;
    }

    for (iterator = wrap_table->details->children; iterator; iterator = iterator->next)
    {
        GtkWidget *item;

        item = iterator->data;

        if (gtk_widget_get_visible (item))
        {
            GtkAllocation item_allocation;

            if (wrap_table->details->homogeneous)
            {
                item_allocation.x = pos.x;
                item_allocation.y = pos.y;
                item_allocation.width = max_child_dimensions.width;
                item_allocation.height = max_child_dimensions.height;

                if ((pos.x + max_child_dimensions.width) > content_bounds.x1)
                {
                    pos.x = content_bounds.x0 + wrap_table->details->x_spacing + max_child_dimensions.width;
                    pos.y += (max_child_dimensions.height + wrap_table->details->y_spacing);
                    item_allocation.x = content_bounds.x0;
                    item_allocation.y = pos.y;
                }
                else
                {
                    pos.x += (wrap_table->details->x_spacing + max_child_dimensions.width);
                }
            }
            else
            {
                GtkRequisition item_requisition;

                gtk_widget_size_request (item, &item_requisition);

                item_allocation.x = pos.x;
                item_allocation.y = pos.y;
                item_allocation.width = item_requisition.width;
                item_allocation.height = item_requisition.height;

                g_assert (item_allocation.width <= max_child_dimensions.width);
                g_assert (item_allocation.height <= max_child_dimensions.height);

                if ((pos.x + max_child_dimensions.width) > content_bounds.x1)
                {
                    pos.x = content_bounds.x0 + wrap_table->details->x_spacing + max_child_dimensions.width;
                    pos.y += (max_child_dimensions.height + wrap_table->details->y_spacing);
                    item_allocation.x = content_bounds.x0;
                    item_allocation.y = pos.y;
                }
                else
                {
                    pos.x += (wrap_table->details->x_spacing + max_child_dimensions.width);
                }

                switch (wrap_table->details->x_justification)
                {
                case EEL_JUSTIFICATION_MIDDLE:
                    item_allocation.x += (max_child_dimensions.width - (int) item_allocation.width) / 2;
                    break;
                case EEL_JUSTIFICATION_END:
                    item_allocation.x += (max_child_dimensions.width - (int) item_allocation.width);
                    break;
                default:
                    break;
                }

                switch (wrap_table->details->y_justification)
                {
                case EEL_JUSTIFICATION_MIDDLE:
                    item_allocation.y += (max_child_dimensions.height - (int) item_allocation.height) / 2;
                    break;
                case EEL_JUSTIFICATION_END:
                    item_allocation.y += (max_child_dimensions.height - (int) item_allocation.height);
                    break;
                default:
                    break;
                }
            }

            gtk_widget_size_allocate (item, &item_allocation);
        }
    }
}
示例#13
0
static void
cg_combo_flags_get_position (CgComboFlags *combo,
                             gint *x, 
                             gint *y, 
                             gint *width,
                             gint *height)
{
	CgComboFlagsPrivate *priv;
	GtkAllocation allocation;
	GtkRequisition popup_req;
	GdkWindow *window;
	GdkScreen *screen;
	GdkRectangle monitor;
	gint monitor_num;
  
	priv = CG_COMBO_FLAGS_PRIVATE (combo);
	
	g_assert (priv->window != NULL);

	window = gtk_widget_get_window (GTK_WIDGET (combo));
	gdk_window_get_origin (window, x, y);

	gtk_widget_get_allocation (GTK_WIDGET (combo), &allocation);

	if (!gtk_widget_get_has_window (GTK_WIDGET (combo)))
	{
		*x += allocation.x;
		*y += allocation.y;
	}

	gtk_widget_get_preferred_size (priv->window, &popup_req, NULL);

	*width = allocation.width;
	if (popup_req.width > *width) *width = popup_req.width;
	*height = popup_req.height;

	screen = gtk_widget_get_screen (GTK_WIDGET(combo));
	monitor_num = gdk_screen_get_monitor_at_window (screen, window);

	gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);

	if (*x < monitor.x)
	{
		*x = monitor.x;
	}
	else if (*x + *width > monitor.x + monitor.width)
	{
		*x = monitor.x + monitor.width - *width;
	}
  
	if (*y + allocation.height + *height <=
	    monitor.y + monitor.height)
	{
		*y += allocation.height;
	}
	else if (*y - *height >= monitor.y)
	{
		*y -= *height;
	}
	else if (monitor.y + monitor.height -
	         (*y + allocation.height) > *y - monitor.y)
	{
		*y += allocation.height;
		*height = monitor.y + monitor.height - *y;
	}
	else
	{
		*height = *y - monitor.y;
		*y = monitor.y;
	}
}
示例#14
0
/*!
 \brief draws the static part of the stripchart,  i.e. this is only the 
 history of the trace, as there's no point to re-render the whole f*****g thing
 every damn time when only 1 datapoint is being appended,  This writes to a
 pixmap, which is shifted and new trace data rendered, before graticaule/text
 overlay is added on.
 \param chart is the pointer to the chart object
 */
void generate_stripchart_static_traces(MtxStripChart *chart)
{
	cairo_t *cr = NULL;
	gint w = 0;
	gint h = 0;
	gint i = 0;
	gint j = 0;
	gfloat x = 0.0;
	gfloat y = 0.0;
	gfloat start_x = 0.0;
	gfloat start_y = 0.0;
	gint points = 0;
	MtxStripChartTrace *trace = NULL;
	MtxStripChartPrivate *priv = MTX_STRIPCHART_GET_PRIVATE(chart);
	GtkAllocation allocation;

	gtk_widget_get_allocation(GTK_WIDGET(chart),&allocation);

	w = allocation.width;
	h = allocation.height;

	if (!priv->trace_pixmap)
		return;
	/* get a cairo_t */

	cr = gdk_cairo_create (priv->trace_pixmap);
	cairo_set_font_options(cr,priv->font_options);
	cairo_set_source_rgb (cr, 
			priv->colors[COL_BG].red/65535.0,
			priv->colors[COL_BG].green/65535.0,
			priv->colors[COL_BG].blue/65535.0);
	/* Background Rectangle */

	cairo_rectangle (cr,
			0,0,w,h);
	cairo_fill(cr);

	for (i=0;i<priv->num_traces;i++)
	{
		trace = g_array_index(priv->traces,MtxStripChartTrace *,i);
		if (!trace)
			continue;


		cairo_set_line_width(cr,trace->lwidth);
		cairo_set_source_rgb (cr, 
				trace->color.red/65535.0,
				trace->color.green/65535.0,
				trace->color.blue/65535.0);
		points = trace->history->len < priv->w ? trace->history->len-1:priv->w;
		if (points < 1)
			continue;
		start_x = priv->w - points;
		start_y = priv->h - (((g_array_index(trace->history,gfloat,trace->history->len - points)-trace->min) / (trace->max - trace->min))*priv->h);
		cairo_move_to(cr,start_x,start_y);
		for (j=0;j<points;j++)
		{
			x = priv->w - points + j;
			y = priv->h - (((g_array_index(trace->history,gfloat,trace->history->len - points + j)-trace->min) / (trace->max - trace->min))*priv->h);
			cairo_line_to(cr,x,y);
		}
		cairo_stroke(cr);
	}
	cairo_destroy (cr);
}
示例#15
0
static gboolean dt_iop_basecurve_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_basecurve_gui_data_t *c = (dt_iop_basecurve_gui_data_t *)self->gui_data;
  dt_iop_basecurve_params_t *p = (dt_iop_basecurve_params_t *)self->params;

  int nodes = p->basecurve_nodes[0];
  dt_iop_basecurve_node_t *basecurve = p->basecurve[0];
  if(c->minmax_curve_type != p->basecurve_type[0] || c->minmax_curve_nodes != p->basecurve_nodes[0])
  {
    dt_draw_curve_destroy(c->minmax_curve);
    c->minmax_curve = dt_draw_curve_new(0.0, 1.0, p->basecurve_type[0]);
    c->minmax_curve_nodes = p->basecurve_nodes[0];
    c->minmax_curve_type = p->basecurve_type[0];
    for(int k = 0; k < p->basecurve_nodes[0]; k++)
      (void)dt_draw_curve_add_point(c->minmax_curve, p->basecurve[0][k].x, p->basecurve[0][k].y);
  }
  else
  {
    for(int k = 0; k < p->basecurve_nodes[0]; k++)
      dt_draw_curve_set_point(c->minmax_curve, k, p->basecurve[0][k].x, p->basecurve[0][k].y);
  }
  dt_draw_curve_t *minmax_curve = c->minmax_curve;
  dt_draw_curve_calc_values(minmax_curve, 0.0, 1.0, DT_IOP_TONECURVE_RES, c->draw_xs, c->draw_ys);

  const float xm = basecurve[nodes - 1].x;
  const float x[4] = { 0.7f * xm, 0.8f * xm, 0.9f * xm, 1.0f * xm };
  const float y[4] = { c->draw_ys[CLAMP((int)(x[0] * DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES - 1)],
                       c->draw_ys[CLAMP((int)(x[1] * DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES - 1)],
                       c->draw_ys[CLAMP((int)(x[2] * DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES - 1)],
                       c->draw_ys[CLAMP((int)(x[3] * DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES - 1)] };
  float unbounded_coeffs[3];
  dt_iop_estimate_exp(x, y, 4, unbounded_coeffs);

  const int inset = DT_GUI_CURVE_EDITOR_INSET;
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int width = allocation.width, height = allocation.height;
  cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);
  // clear bg
  cairo_set_source_rgb(cr, .2, .2, .2);
  cairo_paint(cr);

  cairo_translate(cr, inset, inset);
  width -= 2 * inset;
  height -= 2 * inset;

#if 0
  // draw shadow around
  float alpha = 1.0f;
  for(int k=0; k<inset; k++)
  {
    cairo_rectangle(cr, -k, -k, width + 2*k, height + 2*k);
    cairo_set_source_rgba(cr, 0, 0, 0, alpha);
    alpha *= 0.6f;
    cairo_fill(cr);
  }
#else
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0));
  cairo_set_source_rgb(cr, .1, .1, .1);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_stroke(cr);
#endif

  cairo_set_source_rgb(cr, .3, .3, .3);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_fill(cr);

  cairo_translate(cr, 0, height);
  cairo_scale(cr, 1.0f, -1.0f);

  // draw grid
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(.4));
  cairo_set_source_rgb(cr, .1, .1, .1);
  if(c->loglogscale)
    dt_draw_loglog_grid(cr, 4, 0, 0, width, height, c->loglogscale);
  else
    dt_draw_grid(cr, 4, 0, 0, width, height);

  // draw nodes positions
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.));
  cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
  for(int k = 0; k < nodes; k++)
  {
    const float x = to_log(basecurve[k].x, c->loglogscale), y = to_log(basecurve[k].y, c->loglogscale);
    cairo_arc(cr, x * width, y * height, DT_PIXEL_APPLY_DPI(3), 0, 2. * M_PI);
    cairo_stroke(cr);
  }

  // draw selected cursor
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.));

  if(c->selected >= 0)
  {
    cairo_set_source_rgb(cr, .9, .9, .9);
    const float x = to_log(basecurve[c->selected].x, c->loglogscale),
                y = to_log(basecurve[c->selected].y, c->loglogscale);
    cairo_arc(cr, x * width, y * height, DT_PIXEL_APPLY_DPI(4), 0, 2. * M_PI);
    cairo_stroke(cr);
  }

  // draw curve
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.));
  cairo_set_source_rgb(cr, .9, .9, .9);
  // cairo_set_line_cap  (cr, CAIRO_LINE_CAP_SQUARE);
  cairo_move_to(cr, 0, height * to_log(c->draw_ys[0], c->loglogscale));
  for(int k = 1; k < DT_IOP_TONECURVE_RES; k++)
  {
    const float xx = k / (DT_IOP_TONECURVE_RES - 1.0);
    if(xx > xm)
    {
      const float yy = dt_iop_eval_exp(unbounded_coeffs, xx);
      const float x = to_log(xx, c->loglogscale), y = to_log(yy, c->loglogscale);
      cairo_line_to(cr, x * width, height * y);
    }
    else
    {
      const float yy = c->draw_ys[k];
      const float x = to_log(xx, c->loglogscale), y = to_log(yy, c->loglogscale);
      cairo_line_to(cr, x * width, height * y);
    }
  }
  cairo_stroke(cr);

  cairo_destroy(cr);
  cairo_set_source_surface(crf, cst, 0, 0);
  cairo_paint(crf);
  cairo_surface_destroy(cst);
  return TRUE;
}
示例#16
0
void
_gtk_tooltip_handle_event (GdkEvent *event)
{
  gint x, y;
  gboolean return_value = FALSE;
  GtkWidget *has_tooltip_widget = NULL;
  GdkDisplay *display;
  GtkTooltip *current_tooltip;

  if (!tooltips_enabled (event))
    return;

  /* Returns coordinates relative to has_tooltip_widget's allocation. */
  has_tooltip_widget = find_topmost_widget_coords_from_event (event, &x, &y);
  display = gdk_window_get_display (event->any.window);
  current_tooltip = g_object_get_qdata (G_OBJECT (display), quark_current_tooltip);

  if (current_tooltip)
    {
      gtk_tooltip_set_last_window (current_tooltip, event->any.window);
    }

  if (current_tooltip && current_tooltip->keyboard_mode_enabled)
    {
      has_tooltip_widget = current_tooltip->keyboard_widget;
      if (!has_tooltip_widget)
	return;

      return_value = gtk_tooltip_run_requery (&has_tooltip_widget,
					      current_tooltip,
					      &x, &y);

      if (!return_value)
	gtk_tooltip_hide_tooltip (current_tooltip);
      else
	gtk_tooltip_start_delay (display);

      return;
    }

#ifdef DEBUG_TOOLTIP
  if (has_tooltip_widget)
    {
    GtkAllocation allocation;
    gtk_widget_get_allocation (has_tooltip_widget, &allocation);
    g_print ("%p (%s) at (%d, %d) %dx%d     pointer: (%d, %d)\n",
	     has_tooltip_widget, gtk_widget_get_name (has_tooltip_widget),
	     allocation.x,
	     allocation.y,
	     allocation.width,
	     allocation.height,
	     x, y);
    }
#endif /* DEBUG_TOOLTIP */

  /* Always poll for a next motion event */
  gdk_event_request_motions (&event->motion);

  /* Hide the tooltip when there's no new tooltip widget */
  if (!has_tooltip_widget)
    {
      if (current_tooltip)
	gtk_tooltip_hide_tooltip (current_tooltip);

      return;
    }

  switch (event->type)
    {
      case GDK_BUTTON_PRESS:
      case GDK_2BUTTON_PRESS:
      case GDK_3BUTTON_PRESS:
      case GDK_KEY_PRESS:
      case GDK_DRAG_ENTER:
      case GDK_GRAB_BROKEN:
      case GDK_SCROLL:
	gtk_tooltip_hide_tooltip (current_tooltip);
	break;

      case GDK_MOTION_NOTIFY:
      case GDK_ENTER_NOTIFY:
      case GDK_LEAVE_NOTIFY:
	if (current_tooltip)
	  {
	    gboolean tip_area_set;
	    GdkRectangle tip_area;
	    gboolean hide_tooltip;

	    tip_area_set = current_tooltip->tip_area_set;
	    tip_area = current_tooltip->tip_area;

	    return_value = gtk_tooltip_run_requery (&has_tooltip_widget,
						    current_tooltip,
						    &x, &y);

	    /* Requested to be hidden? */
	    hide_tooltip = !return_value;

	    /* Leave notify should override the query function */
	    hide_tooltip = (event->type == GDK_LEAVE_NOTIFY);

	    /* Is the pointer above another widget now? */
	    if (GTK_TOOLTIP_VISIBLE (current_tooltip))
	      hide_tooltip |= has_tooltip_widget != current_tooltip->tooltip_widget;

	    /* Did the pointer move out of the previous "context area"? */
	    if (tip_area_set)
	      hide_tooltip |= (x <= tip_area.x
			       || x >= tip_area.x + tip_area.width
			       || y <= tip_area.y
			       || y >= tip_area.y + tip_area.height);

	    if (hide_tooltip)
	      gtk_tooltip_hide_tooltip (current_tooltip);
	    else
	      gtk_tooltip_start_delay (display);
	  }
	else
	  {
	    /* Need a new tooltip for this display */
	    current_tooltip = g_object_new (GTK_TYPE_TOOLTIP, NULL);
	    g_object_set_qdata_full (G_OBJECT (display),
				     quark_current_tooltip,
				     current_tooltip,
                                     g_object_unref);
	    g_signal_connect (display, "closed",
			      G_CALLBACK (gtk_tooltip_display_closed),
			      current_tooltip);

	    gtk_tooltip_set_last_window (current_tooltip, event->any.window);

	    gtk_tooltip_start_delay (display);
	  }
	break;

      default:
	break;
    }
}
示例#17
0
static gboolean dt_iop_basecurve_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_basecurve_gui_data_t *c = (dt_iop_basecurve_gui_data_t *)self->gui_data;
  dt_iop_basecurve_params_t *p = (dt_iop_basecurve_params_t *)self->params;
  int ch = 0;
  int nodes = p->basecurve_nodes[ch];
  dt_iop_basecurve_node_t *basecurve = p->basecurve[ch];

  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  const int inset = DT_GUI_CURVE_EDITOR_INSET;
  int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset;
  c->mouse_x = CLAMP(event->x - inset, 0, width);
  c->mouse_y = CLAMP(event->y - inset, 0, height);

  const float mx = c->mouse_x / (float)width;
  const float my = 1.0f - c->mouse_y / (float)height;
  const float linx = to_lin(mx, c->loglogscale), liny = to_lin(my, c->loglogscale);

  if(event->state & GDK_BUTTON1_MASK)
  {
    // got a vertex selected:
    if(c->selected >= 0)
    {
      basecurve[c->selected].x = linx;
      basecurve[c->selected].y = liny;

      // delete vertex if order has changed:
      if(nodes > 2)
        if((c->selected > 0 && basecurve[c->selected - 1].x >= linx)
           || (c->selected < nodes - 1 && basecurve[c->selected + 1].x <= linx))
        {
          for(int k = c->selected; k < nodes - 1; k++)
          {
            basecurve[k].x = basecurve[k + 1].x;
            basecurve[k].y = basecurve[k + 1].y;
          }
          c->selected = -2; // avoid re-insertion of that point immediately after this
          p->basecurve_nodes[ch]--;
        }
      dt_dev_add_history_item(darktable.develop, self, TRUE);
    }
    else if(nodes < MAXNODES && c->selected >= -1)
    {
      // no vertex was close, create a new one!
      c->selected = _add_node(basecurve, &p->basecurve_nodes[ch], linx, liny);
      dt_dev_add_history_item(darktable.develop, self, TRUE);
    }
  }
  else
  {
    // minimum area around the node to select it:
    float min = .04f;
    min *= min; // comparing against square
    int nearest = -1;
    for(int k = 0; k < nodes; k++)
    {
      float dist
          = (my - to_log(basecurve[k].y, c->loglogscale)) * (my - to_log(basecurve[k].y, c->loglogscale))
            + (mx - to_log(basecurve[k].x, c->loglogscale)) * (mx - to_log(basecurve[k].x, c->loglogscale));
      if(dist < min)
      {
        min = dist;
        nearest = k;
      }
    }
    c->selected = nearest;
  }
  gtk_widget_queue_draw(widget);
  return TRUE;
}
示例#18
0
static void
child_location_foreach (GtkWidget *child,
			gpointer   data)
{
  GtkAllocation child_allocation;
  gint x, y;
  struct ChildLocation *child_loc = data;

  /* Ignore invisible widgets */
  if (!gtk_widget_is_drawable (child))
    return;

  gtk_widget_get_allocation (child, &child_allocation);

  x = 0;
  y = 0;

  /* (child_loc->x, child_loc->y) are relative to
   * child_loc->container's allocation.
   */

  if (!child_loc->child &&
      gtk_widget_translate_coordinates (child_loc->container, child,
					child_loc->x, child_loc->y,
					&x, &y))
    {
#ifdef DEBUG_TOOLTIP
      g_print ("candidate: %s  alloc=[(%d,%d)  %dx%d]     (%d, %d)->(%d, %d)\n",
	       gtk_widget_get_name (child),
               child_allocation.x,
               child_allocation.y,
               child_allocation.width,
               child_allocation.height,
	       child_loc->x, child_loc->y,
	       x, y);
#endif /* DEBUG_TOOLTIP */

      /* (x, y) relative to child's allocation. */
      if (x >= 0 && x < child_allocation.width
	  && y >= 0 && y < child_allocation.height)
        {
	  if (GTK_IS_CONTAINER (child))
	    {
	      struct ChildLocation tmp = { NULL, NULL, 0, 0 };
              GSList *children = NULL, *tmp_list;

	      /* Take (x, y) relative the child's allocation and
	       * recurse.
	       */
	      tmp.x = x;
	      tmp.y = y;
	      tmp.container = child;

	      gtk_container_forall (GTK_CONTAINER (child),
				    prepend_and_ref_widget, &children);

              for (tmp_list = children; tmp_list; tmp_list = tmp_list->next)
                {
                  child_location_foreach (tmp_list->data, &tmp);
                  g_object_unref (tmp_list->data);
                }

	      if (tmp.child)
		child_loc->child = tmp.child;
	      else
		child_loc->child = child;

              g_slist_free (children);
	    }
	  else
	    child_loc->child = child;
	}
    }
}
示例#19
0
文件: gtkcoloreditor.c 项目: Vort/gtk
static gboolean
get_child_position (GtkOverlay     *overlay,
                    GtkWidget      *widget,
                    GtkAllocation  *allocation,
                    GtkColorEditor *editor)
{
  GtkRequisition req;
  GtkAllocation alloc;
  gint s, e;

  gtk_widget_get_preferred_size (widget, &req, NULL);

  allocation->x = 0;
  allocation->y = 0;
  allocation->width = req.width;
  allocation->height = req.height;

  if (widget == editor->priv->sv_popup)
    {
      gtk_widget_translate_coordinates (editor->priv->sv_plane,
                                        gtk_widget_get_parent (editor->priv->grid),
                                        0, -6,
                                        &allocation->x, &allocation->y);
      if (gtk_widget_get_direction (GTK_WIDGET (overlay)) == GTK_TEXT_DIR_RTL)
        allocation->x = 0;
      else
        allocation->x = gtk_widget_get_allocated_width (GTK_WIDGET (overlay)) - req.width;
    }
  else if (widget == editor->priv->h_popup)
    {
      gtk_widget_get_allocation (editor->priv->h_slider, &alloc);
      gtk_range_get_slider_range (GTK_RANGE (editor->priv->h_slider), &s, &e);

      if (gtk_widget_get_direction (GTK_WIDGET (overlay)) == GTK_TEXT_DIR_RTL)
        gtk_widget_translate_coordinates (editor->priv->h_slider,
                                          gtk_widget_get_parent (editor->priv->grid),
                                          - req.width - 6, editor->priv->popup_position - req.height / 2,
                                          &allocation->x, &allocation->y);
      else
        gtk_widget_translate_coordinates (editor->priv->h_slider,
                                          gtk_widget_get_parent (editor->priv->grid),
                                          alloc.width + 6, editor->priv->popup_position - req.height / 2,
                                          &allocation->x, &allocation->y);
    }
  else if (widget == editor->priv->a_popup)
    {
      gtk_widget_get_allocation (editor->priv->a_slider, &alloc);
      gtk_range_get_slider_range (GTK_RANGE (editor->priv->a_slider), &s, &e);

      gtk_widget_translate_coordinates (editor->priv->a_slider,
                                        gtk_widget_get_parent (editor->priv->grid),
                                        editor->priv->popup_position - req.width / 2, - req.height - 6,
                                        &allocation->x, &allocation->y);
    }
  else
    return FALSE;

  allocation->x = CLAMP (allocation->x, 0, gtk_widget_get_allocated_width (GTK_WIDGET (overlay)) - req.width);
  allocation->y = CLAMP (allocation->y, 0, gtk_widget_get_allocated_height (GTK_WIDGET (overlay)) - req.height);

  return TRUE;
}
示例#20
0
/**
 * gimp_session_info_read_geometry:
 * @info:  A #GimpSessionInfo
 * @cevent A #GdkEventConfigure. If set, use the size from here
 *         instead of from the window allocation.
 *
 * Read geometry related information from the associated widget.
 **/
void
gimp_session_info_read_geometry (GimpSessionInfo   *info,
                                 GdkEventConfigure *cevent)
{
  GdkWindow *window;
  GdkScreen *screen  = gtk_widget_get_screen (info->p->widget);

  g_return_if_fail (GIMP_IS_SESSION_INFO (info));
  g_return_if_fail (GTK_IS_WINDOW (info->p->widget));

  window = gtk_widget_get_window (info->p->widget);
  screen = gtk_widget_get_screen (info->p->widget);

  if (window)
    {
      gint         x, y;
      gint         monitor;
      GdkRectangle geometry;

      gdk_window_get_root_origin (window, &x, &y);

      /* Don't write negative values to the sessionrc, they are
       * interpreted as relative to the right, respective bottom edge
       * of the screen.
       */
      info->p->x = MAX (0, x);
      info->p->y = MAX (0, y);

      monitor = gdk_screen_get_monitor_at_point (screen,
                                                 info->p->x, info->p->y);
      gdk_screen_get_monitor_geometry (screen, monitor, &geometry);

      /* Always store window coordinates relative to the monitor */
      info->p->x -= geometry.x;
      info->p->y -= geometry.y;

      if (gimp_session_info_get_remember_size (info))
        {
          int width;
          int height;

          if (cevent)
            {
              width  = cevent->width;
              height = cevent->height;
            }
          else
            {
              GtkAllocation allocation;

              gtk_widget_get_allocation (info->p->widget, &allocation);

              width  = allocation.width;
              height = allocation.height;
            }

          info->p->width  = width;
          info->p->height = height;
        }
      else
        {
          info->p->width  = 0;
          info->p->height = 0;
        }

      info->p->monitor = DEFAULT_MONITOR;

      if (monitor != gdk_screen_get_primary_monitor (screen))
        info->p->monitor = monitor;
    }

  info->p->open = FALSE;

  if (gimp_session_info_get_remember_if_open (info))
    {
      GimpDialogVisibilityState visibility;

      visibility =
        GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info->p->widget),
                                            GIMP_DIALOG_VISIBILITY_KEY));

      switch (visibility)
        {
        case GIMP_DIALOG_VISIBILITY_UNKNOWN:
          info->p->open = gtk_widget_get_visible (info->p->widget);
          break;

        case GIMP_DIALOG_VISIBILITY_INVISIBLE:
          info->p->open = FALSE;
          break;

        case GIMP_DIALOG_VISIBILITY_HIDDEN:
        case GIMP_DIALOG_VISIBILITY_VISIBLE:
          /* Even if a dialog is hidden (with Windows->Hide docks) it
           * is still considered open. It will be restored the next
           * time GIMP starts
           */
          info->p->open = TRUE;
          break;
        }
    }

  info->p->screen = DEFAULT_SCREEN;

  if (info->p->open)
    {
      GdkDisplay *display = gtk_widget_get_display (info->p->widget);

      if (screen != gdk_display_get_default_screen (display))
        info->p->screen = gdk_screen_get_number (screen);
    }
}
示例#21
0
static gboolean
gimp_tag_popup_border_event (GtkWidget *widget,
                             GdkEvent  *event)
{
  GimpTagPopup *popup = GIMP_TAG_POPUP (widget);

  if (event->type == GDK_BUTTON_PRESS)
    {
      GdkEventButton *button_event = (GdkEventButton *) event;
      GtkAllocation   allocation;
      gint            x;
      gint            y;

      if (button_event->window == gtk_widget_get_window (widget) &&
          gimp_tag_popup_button_scroll (popup, button_event))
        {
          return TRUE;
        }

      gtk_widget_get_allocation (widget, &allocation);

      gdk_window_get_pointer (gtk_widget_get_window (widget), &x, &y, NULL);

      if (button_event->window != gtk_widget_get_window (popup->tag_area) &&
          (x < allocation.y                    ||
           y < allocation.x                    ||
           x > allocation.x + allocation.width ||
           y > allocation.y + allocation.height))
        {
          /* user has clicked outside the popup area,
           * which means it should be hidden.
           */
          gtk_grab_remove (widget);
          gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
                                      GDK_CURRENT_TIME);
          gtk_widget_destroy (widget);
        }
    }
  else if (event->type == GDK_MOTION_NOTIFY)
    {
      GdkEventMotion *motion_event = (GdkEventMotion *) event;
      gint            x, y;

      gdk_window_get_pointer (gtk_widget_get_window (widget), &x, &y, NULL);

      gimp_tag_popup_handle_scrolling (popup, x, y,
                                       motion_event->window ==
                                       gtk_widget_get_window (widget),
                                       TRUE);
    }
  else if (event->type == GDK_BUTTON_RELEASE)
    {
      GdkEventButton *button_event = (GdkEventButton *) event;

      popup->single_select_disabled = TRUE;

      if (button_event->window == gtk_widget_get_window (widget) &&
          gimp_tag_popup_button_scroll (popup, button_event))
        {
          return TRUE;
        }
    }
  else if (event->type == GDK_GRAB_BROKEN)
    {
      gtk_grab_remove (widget);
      gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
                                  GDK_CURRENT_TIME);
      gtk_widget_destroy (widget);
    }
  else if (event->type == GDK_KEY_PRESS)
    {
      gtk_grab_remove (widget);
      gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
                                  GDK_CURRENT_TIME);
      gtk_widget_destroy (widget);
    }
  else if (event->type == GDK_SCROLL)
    {
      GdkEventScroll *scroll_event = (GdkEventScroll *) event;

      switch (scroll_event->direction)
        {
        case GDK_SCROLL_RIGHT:
        case GDK_SCROLL_DOWN:
          gimp_tag_popup_scroll_by (popup, MENU_SCROLL_STEP2);
          return TRUE;

        case GDK_SCROLL_LEFT:
        case GDK_SCROLL_UP:
          gimp_tag_popup_scroll_by (popup, - MENU_SCROLL_STEP2);
          return TRUE;
        }
    }

  return FALSE;
}
示例#22
0
static gboolean dt_iop_monochrome_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_monochrome_gui_data_t *g = (dt_iop_monochrome_gui_data_t *)self->gui_data;
  dt_iop_monochrome_params_t *p = (dt_iop_monochrome_params_t *)self->params;

  if(self->request_color_pick == DT_REQUEST_COLORPICK_MODULE)
  {
    p->a = self->picked_color[1];
    p->b = self->picked_color[2];
    float da = self->picked_color_max[1] - self->picked_color_min[1];
    float db = self->picked_color_max[2] - self->picked_color_min[2];
    p->size = CLAMP((da + db)/128.0, .5, 3.0);
  }

  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->colorpicker),
                               (self->request_color_pick == DT_REQUEST_COLORPICK_MODULE ? 1 : 0));

  const int inset = DT_COLORCORRECTION_INSET;
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int width = allocation.width, height = allocation.height;
  cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);
  // clear bg
  cairo_set_source_rgb(cr, .2, .2, .2);
  cairo_paint(cr);

  cairo_translate(cr, inset, inset);
  cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
  width -= 2 * inset;
  height -= 2 * inset;
  // clip region to inside:
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_clip(cr);
  // flip y:
  cairo_translate(cr, 0, height);
  cairo_scale(cr, 1., -1.);
  const int cells = 8;
  for(int j = 0; j < cells; j++)
    for(int i = 0; i < cells; i++)
    {
      double rgb[3] = { 0.5, 0.5, 0.5 };
      cmsCIELab Lab;
      Lab.L = 53.390011;
      Lab.a = Lab.b = 0; // grey
      // dt_iop_sRGB_to_Lab(rgb, Lab, 0, 0, 1.0, 1, 1); // get grey in Lab
      Lab.a = PANEL_WIDTH * (i / (cells - 1.0) - .5);
      Lab.b = PANEL_WIDTH * (j / (cells - 1.0) - .5);
      const float f = color_filter(Lab.a, Lab.b, p->a, p->b, 40 * 40 * p->size * p->size);
      Lab.L *= f * f; // exaggerate filter a little
      cmsDoTransform(g->xform, &Lab, rgb, 1);
      cairo_set_source_rgb(cr, rgb[0], rgb[1], rgb[2]);
      cairo_rectangle(cr, width * i / (float)cells, height * j / (float)cells,
                      width / (float)cells - DT_PIXEL_APPLY_DPI(1),
                      height / (float)cells - DT_PIXEL_APPLY_DPI(1));
      cairo_fill(cr);
    }
  cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
  cairo_set_source_rgb(cr, .7, .7, .7);
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.0));
  const float x = p->a * width / PANEL_WIDTH + width * .5f, y = p->b * height / PANEL_WIDTH + height * .5f;
  cairo_arc(cr, x, y, width * .22f * p->size, 0, 2.0 * M_PI);
  cairo_stroke(cr);

  cairo_destroy(cr);
  cairo_set_source_surface(crf, cst, 0, 0);
  cairo_paint(crf);
  cairo_surface_destroy(cst);
  return TRUE;
}
示例#23
0
static void
render_to_file (GtkButton *button,
                GtkWidget *widget)
{
  GtkAllocation allocation;
  GdkGLConfig *glconfig;
  Display *xdisplay;
  XVisualInfo *xvinfo;
  GLXFBConfigSGIX fbconfig;

  GLXPbufferSGIX pbuffer;
  int pb_attrib_list[] = {
    GLX_LARGEST_PBUFFER_SGIX, True,
    GLX_PRESERVED_CONTENTS_SGIX, False,
    None
  };
  int width, height;

  GdkGLContext *glcontext;
  GLXContext glxcontext;

  g_print ("Render to PPM file...\n");

  glconfig = gtk_widget_get_gl_config (widget);
  xdisplay = gdk_x11_gl_config_get_xdisplay (glconfig);
  xvinfo = gdk_x11_gl_config_get_xvinfo (glconfig);

  /*
   * Get FBConfig.
   */

  g_print ("- get FBConfig\n");
  fbconfig = GetFBConfigFromVisualSGIX (xdisplay, xvinfo);
  if (!fbconfig)
    {
      g_print ("cannot get FBConfig\n");
      return;
    }

  /*
   * Create GLXPbuffer.
   */

  gtk_widget_get_allocation (widget, &allocation);
  width = allocation.width;
  height = allocation.height;

  g_print ("- create GLXPbuffer\n");
  pbuffer = CreateGLXPbufferSGIX (xdisplay, fbconfig,
                                  width, height,
                                  pb_attrib_list);
  if (!pbuffer)
    {
      g_print ("cannot create GLXPbuffer\n");
      return;
    }

  /*
   * Render.
   */

  glcontext = gtk_widget_get_gl_context (widget);
  glxcontext = gdk_x11_gl_context_get_glxcontext (glcontext);

  glXMakeCurrent (xdisplay, pbuffer, glxcontext);

  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glCallList (1);

  glFlush ();

  /*
   * Write to file.
   */

  write_file ("simple-pbuffer-sgix.ppm", width, height);

  /*
   * Destroy GLXPbuffer.
   */

  glXMakeCurrent (xdisplay, None, NULL);

  g_print ("- destroy GLXPbuffer\n");
  DestroyGLXPbufferSGIX (xdisplay, pbuffer);

  g_print ("Done.\n\n");
}
示例#24
0
void
S9xXVDisplayDriver::update (int width, int height)
{
    int   current_width, current_height, final_pitch;
    uint8 *final_buffer;
    int   dst_x, dst_y, dst_width, dst_height;
    GtkAllocation allocation;

    gtk_widget_get_allocation (drawing_area, &allocation);
#if GTK_CHECK_VERSION(3,10,0)
    int gdk_scale_factor = gdk_window_get_scale_factor (gdk_window);

    allocation.width *= gdk_scale_factor;
    allocation.height *= gdk_scale_factor;

#endif

    current_width = allocation.width;
    current_height = allocation.height;

    if (output_window_width  != current_width ||
        output_window_height != current_height)
    {
        resize_window (current_width, current_height);
    }

    if (config->scale_method > 0)
    {
        uint8 *src_buffer = (uint8 *) padded_buffer[0];
        uint8 *dst_buffer = (uint8 *) padded_buffer[1];
        int   src_pitch = image_width * image_bpp;
        int   dst_pitch = scaled_max_width * image_bpp;

        S9xFilter (src_buffer,
                   src_pitch,
                   dst_buffer,
                   dst_pitch,
                   width,
                   height);

        final_buffer = (uint8 *) padded_buffer[1];
        final_pitch = dst_pitch;
    }
    else
    {
        final_buffer = (uint8 *) padded_buffer[0];
        final_pitch = image_width * image_bpp;
    }

    update_image_size (width, height);

    if (format == FOURCC_YUY2)
    {
        S9xConvertYUV (final_buffer,
                       (uint8 *) xv_image->data,
                       final_pitch,
                       2 * xv_image->width,
                       width + (width < xv_image->width ? (width % 2) + 4 : 0),
                       height + (height < xv_image->height ? 4 : 0));
    }
    else
    {
        S9xConvertMask (final_buffer,
                        (uint8 *) xv_image->data,
                        final_pitch,
                        bytes_per_pixel * xv_image->width,
                        width + (width < xv_image->width ? (width % 2) + 4 : 0),
                        height + (height < xv_image->height ? 4 : 0),
                        rshift,
                        gshift,
                        bshift,
                        bpp);
    }

    dst_x = width; dst_y = height;
    dst_width = current_width; dst_height = current_height;
    S9xApplyAspect (dst_x, dst_y, dst_width, dst_height);

    if (last_known_width != dst_width || last_known_height != dst_height)
    {
        last_known_width = dst_width;
        last_known_height = dst_height;
        clear ();
    }

    XvShmPutImage (display,
                   xv_portid,
                   xwindow,
                   XDefaultGC (display, XDefaultScreen (display)),
                   xv_image,
                   0,
                   0,
                   width,
                   height,
                   dst_x,
                   dst_y,
                   dst_width,
                   dst_height,
                   False);

    top_level->set_mouseable_area (dst_x, dst_y, dst_width, dst_height);

    XSync (display, False);

    return;
}
示例#25
0
static void
gtk_real_check_menu_item_draw_indicator (GtkCheckMenuItem *check_menu_item,
                                         cairo_t          *cr)
{
  GtkCheckMenuItemPrivate *priv = check_menu_item->priv;
  GtkWidget *widget;
  gint x, y;

  widget = GTK_WIDGET (check_menu_item);

  if (gtk_widget_is_drawable (widget))
    {
      GtkAllocation allocation;
      GtkStyleContext *context;
      guint border_width;
      guint offset;
      guint toggle_size;
      guint toggle_spacing;
      guint horizontal_padding;
      guint indicator_size;
      GtkStateFlags state;
      GtkBorder padding;

      context = gtk_widget_get_style_context (widget);
      state = gtk_widget_get_state_flags (widget);
      gtk_style_context_get_padding (context, state, &padding);

      gtk_widget_get_allocation (widget, &allocation);

      gtk_widget_style_get (widget,
                            "toggle-spacing", &toggle_spacing,
                            "horizontal-padding", &horizontal_padding,
                            "indicator-size", &indicator_size,
                            NULL);

      toggle_size = GTK_MENU_ITEM (check_menu_item)->priv->toggle_size;
      border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
      offset = border_width + padding.left + 2;

      if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
        {
          x = offset + horizontal_padding +
            (toggle_size - toggle_spacing - indicator_size) / 2;
        }
      else
        {
          x = allocation.width -
            offset - horizontal_padding - toggle_size + toggle_spacing +
            (toggle_size - toggle_spacing - indicator_size) / 2;
        }

      y = (allocation.height - indicator_size) / 2;

      gtk_style_context_save (context);

      if (priv->inconsistent)
        state |= GTK_STATE_FLAG_INCONSISTENT;
      else if (priv->active)
        state |= GTK_STATE_FLAG_ACTIVE;

      gtk_style_context_set_state (context, state);

      if (priv->draw_as_radio)
        {
          gtk_style_context_add_class (context, GTK_STYLE_CLASS_RADIO);
          gtk_render_option (context, cr, x, y,
                             indicator_size, indicator_size);
        }
      else
        {
          gtk_style_context_add_class (context, GTK_STYLE_CLASS_CHECK);
          gtk_render_check (context, cr, x, y,
                            indicator_size, indicator_size);
        }

      gtk_style_context_restore (context);
    }
}
示例#26
0
void
mate_panel_applet_position_menu (GtkMenu   *menu,
			    int       *x,
			    int       *y,
			    gboolean  *push_in,
			    GtkWidget *applet)
{
	GtkAllocation   allocation;
	GtkRequisition  requisition;
#if GTK_CHECK_VERSION(3, 0, 0)
	GdkDevice      *device;
#endif
	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);

#if GTK_CHECK_VERSION (3, 0, 0)
	gtk_widget_get_preferred_size (GTK_WIDGET (menu), &requisition, NULL);
#else
	gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
#endif

	gdk_window_get_origin (gtk_widget_get_window (applet), &menu_x, &menu_y);
#if GTK_CHECK_VERSION (3, 0, 0)
	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);
#else
	gtk_widget_get_pointer (applet, &pointer_x, &pointer_y);
#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;
#if GTK_CHECK_VERSION (3, 0, 0)
	*push_in = FALSE;
#else
	*push_in = TRUE;
#endif
}
示例#27
0
static gboolean
ide_frame_pan_begin (IdeFrame         *self,
                     GdkEventSequence *sequence,
                     GtkGesturePan    *gesture)
{
  IdeFramePrivate *priv = ide_frame_get_instance_private (self);
  GtkAllocation alloc;
  cairo_surface_t *surface = NULL;
  IdePage *page;
  GdkWindow *window;
  GtkWidget *grid;
  cairo_t *cr;
  gdouble x, y;
  gboolean enable_animations;

  IDE_ENTRY;

  g_assert (IDE_IS_FRAME (self));
  g_assert (GTK_IS_GESTURE_PAN (gesture));
  g_assert (priv->pan_theatric == NULL);

  page = ide_frame_get_visible_child (self);
  if (page != NULL)
    gtk_widget_get_allocation (GTK_WIDGET (page), &alloc);

  g_object_get (gtk_settings_get_default (),
                "gtk-enable-animations", &enable_animations,
                NULL);

  if (sequence != NULL ||
      page == NULL ||
      !enable_animations ||
      is_uninitialized (&alloc) ||
      NULL == (window = gtk_widget_get_window (GTK_WIDGET (page))) ||
      NULL == (surface = gdk_window_create_similar_surface (window,
                                                            CAIRO_CONTENT_COLOR,
                                                            alloc.width,
                                                            alloc.height)))
    {
      if (sequence != NULL)
        gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
      IDE_RETURN (FALSE);
    }

  gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (gesture), &x, &y);

  cr = cairo_create (surface);
  gtk_widget_draw (GTK_WIDGET (page), cr);
  cairo_destroy (cr);

  grid = gtk_widget_get_ancestor (GTK_WIDGET (self), IDE_TYPE_GRID);
  gtk_widget_translate_coordinates (GTK_WIDGET (priv->top_stack), grid, 0, 0,
                                    &alloc.x, &alloc.y);

  priv->pan_page = g_object_ref (page);
  priv->pan_theatric = g_object_new (DZL_TYPE_BOX_THEATRIC,
                                     "surface", surface,
                                     "target", grid,
                                     "x", alloc.x + (gint)x,
                                     "y", alloc.y,
                                     "width", alloc.width,
                                     "height", alloc.height,
                                     NULL);

  g_clear_pointer (&surface, cairo_surface_destroy);

  /* Hide the page while we begin the possible transition to another
   * layout stack.
   */
  gtk_widget_hide (GTK_WIDGET (priv->pan_page));

  /*
   * Hide the mouse cursor until ide_frame_pan_end() is called.
   * It can be distracting otherwise (and we want to warp it to the new
   * grid column too).
   */
  ide_frame_set_cursor (self, "none");

  IDE_RETURN (TRUE);
}
示例#28
0
static gboolean
text_item_renderer (AboutRenderer *r, AboutState *state)
{
	PangoLayout *layout = r->layout;
	int age = state->now - r->start_time;
	double rage = CLAMP (age / (double)r->duration, 0.0, 1.0);
	GtkWidget *widget = state->anim_area;
	GtkStyleContext *ctxt;
	const int fade = 500;
	int x, y, width, height;
	cairo_t *cr;
	GtkAllocation wa;
	GdkRGBA color;
	double alpha = 1;

	if (age >= r->duration)
		return FALSE;

	if (r->fade_in && age < fade)
		alpha = age / (double)fade;
	else if (r->fade_out && r->duration - age < fade)
		alpha = (r->duration - age) / (double)fade;

	ctxt = gtk_widget_get_style_context (widget);

	gtk_widget_get_allocation (widget, &wa);
	x = (int)(PANGO_SCALE * wa.width *
		  (r->start.x + rage * (r->end.x - r->start.x)));
	y = (int)(PANGO_SCALE * wa.height *
		  (r->start.y + rage * (r->end.y - r->start.y)));

	if (r->expansion.count) {
		PangoAttrList *attrlist = pango_layout_get_attributes (layout);
		const char *p, *text = pango_layout_get_text (layout);
		PangoRectangle ink, logical;

		memset (&ink, 0, sizeof (ink));
		logical = ink;

		logical.width = (int)(rage * r->expansion.rate * r->natural_width / r->expansion.count);

		p = text;
		while (*p) {
			const char *next = g_utf8_next_char (p);
			gunichar uc = g_utf8_get_char (p);
			PangoAttribute *attr;

			if (uc == UNICODE_ZERO_WIDTH_SPACE_C) {
				attr = pango_attr_shape_new (&ink, &logical);
				attr->start_index = p - text;
				attr->end_index = next - text;
				pango_attr_list_change (attrlist, attr);
			}
			p = next;
		}
		pango_layout_set_attributes (layout, attrlist);
	}

	pango_layout_get_size (layout, &width, &height);
	x -= width / 2;
	y -= height / 2;

	cr = r->cr;
	gtk_style_context_get_color (ctxt, GTK_STATE_FLAG_NORMAL, &color);
	color.alpha = alpha;
	gdk_cairo_set_source_rgba (cr, &color);
	cairo_move_to (cr, x / (double)PANGO_SCALE, y / (double)PANGO_SCALE);
	pango_cairo_show_layout (cr, layout);

	return TRUE;
}
示例#29
0
cairo_surface_t *
gb_widget_snapshot (GtkWidget *widget,
                    gint       width,
                    gint       height,
                    gdouble    alpha,
                    gboolean   draw_border)
{
  cairo_surface_t *surface;
  GtkAllocation alloc;
  gdouble x_ratio = 1.0;
  gdouble y_ratio = 1.0;
  cairo_t *cr;

  /*
   * XXX: This function conflates the drawing of borders and snapshoting.
   *      Totally not ideal, but we can clean that up later.
   */

  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
  cr = cairo_create (surface);

  gtk_widget_get_allocation (widget, &alloc);

  if ((width != alloc.width) || (height != alloc.height))
    {
      if (alloc.width > alloc.height)
        {
          x_ratio = (gdouble) width / (gdouble) alloc.width;
          y_ratio = (gdouble) width / (gdouble) alloc.width;
        }
      else
        {
          x_ratio = (gdouble) height / (gdouble) alloc.height;
          y_ratio = (gdouble) height / (gdouble) alloc.height;
        }
      cairo_scale (cr, x_ratio, y_ratio);
    }

  gtk_widget_draw (widget, cr);

  cairo_destroy (cr);

  {
    cairo_surface_t *other;
    GdkRectangle rect = {
      3,
      3,
      ceil (alloc.width * x_ratio) - 6,
      ceil (alloc.height * y_ratio) - 6
    };

    other = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (other);

    cairo_save (cr);

    if (draw_border)
      {
        gdk_cairo_rectangle (cr, &rect);
        cairo_clip (cr);
      }

    cairo_set_source_surface (cr, surface, 0, 0);
    cairo_paint_with_alpha (cr, alpha);

    cairo_restore (cr);

    if (draw_border)
      {
        GdkRGBA rgba;

        gb_cairo_rounded_rectangle (cr, &rect, 3, 3);

        gdk_rgba_parse (&rgba, "#729fcf");
        gb_rgba_shade (&rgba, &rgba, 0.8);
        gdk_cairo_set_source_rgba (cr, &rgba);
        cairo_set_line_width (cr, 3.0);

        cairo_stroke (cr);

        gb_cairo_rounded_rectangle (cr, &rect, 1, 1);

        gdk_rgba_parse (&rgba, "#729fcf");
        gb_rgba_shade (&rgba, &rgba, 1.2);
        gdk_cairo_set_source_rgba (cr, &rgba);

        cairo_set_line_width (cr, 1.0);
        cairo_stroke (cr);
      }

    cairo_surface_destroy (surface);
    surface = other;
  }

  return surface;
}
示例#30
0
static gboolean dt_iop_colorcorrection_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_colorcorrection_gui_data_t *g = (dt_iop_colorcorrection_gui_data_t *)self->gui_data;
  dt_iop_colorcorrection_params_t *p = (dt_iop_colorcorrection_params_t *)self->params;

  const int inset = DT_COLORCORRECTION_INSET;
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int width = allocation.width, height = allocation.height;
  cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);
  // clear bg
  cairo_set_source_rgb(cr, .2, .2, .2);
  cairo_paint(cr);

  cairo_translate(cr, inset, inset);
  cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
  width -= 2 * inset;
  height -= 2 * inset;
  // flip y:
  cairo_translate(cr, 0, height);
  cairo_scale(cr, 1., -1.);
  const int cells = 8;
  for(int j = 0; j < cells; j++)
    for(int i = 0; i < cells; i++)
    {
      double rgb[3] = { 0.5, 0.5, 0.5 }; // Lab: rgb grey converted to Lab
      cmsCIELab Lab;
      Lab.L = 53.390011;
      Lab.a = Lab.b = 0; // grey
      // dt_iop_sRGB_to_Lab(rgb, Lab, 0, 0, 1.0, 1, 1); // get grey in Lab
      // printf("lab = %f %f %f\n", Lab[0], Lab[1], Lab[2]);
      Lab.a = p->saturation * (Lab.a + Lab.L * .05 * DT_COLORCORRECTION_MAX * (i / (cells - 1.0) - .5));
      Lab.b = p->saturation * (Lab.b + Lab.L * .05 * DT_COLORCORRECTION_MAX * (j / (cells - 1.0) - .5));
      cmsDoTransform(g->xform, &Lab, rgb, 1);
      // dt_iop_Lab_to_sRGB(Lab, rgb, 0, 0, 1.0, 1, 1);
      cairo_set_source_rgb(cr, rgb[0], rgb[1], rgb[2]);
      cairo_rectangle(cr, width * i / (float)cells, height * j / (float)cells,
                      width / (float)cells - DT_PIXEL_APPLY_DPI(1),
                      height / (float)cells - DT_PIXEL_APPLY_DPI(1));
      cairo_fill(cr);
    }
  cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
  float loa, hia, lob, hib;
  loa = .5f * (width + width * p->loa / (float)DT_COLORCORRECTION_MAX);
  hia = .5f * (width + width * p->hia / (float)DT_COLORCORRECTION_MAX);
  lob = .5f * (height + height * p->lob / (float)DT_COLORCORRECTION_MAX);
  hib = .5f * (height + height * p->hib / (float)DT_COLORCORRECTION_MAX);
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.));
  cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
  cairo_move_to(cr, loa, lob);
  cairo_line_to(cr, hia, hib);
  cairo_stroke(cr);

  cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
  if(g->selected == 1)
    cairo_arc(cr, loa, lob, DT_PIXEL_APPLY_DPI(5), 0, 2. * M_PI);
  else
    cairo_arc(cr, loa, lob, DT_PIXEL_APPLY_DPI(3), 0, 2. * M_PI);
  cairo_fill(cr);

  cairo_set_source_rgb(cr, 0.9, 0.9, 0.9);
  if(g->selected == 2)
    cairo_arc(cr, hia, hib, DT_PIXEL_APPLY_DPI(5), 0, 2. * M_PI);
  else
    cairo_arc(cr, hia, hib, DT_PIXEL_APPLY_DPI(3), 0, 2. * M_PI);
  cairo_fill(cr);

  cairo_destroy(cr);
  cairo_set_source_surface(crf, cst, 0, 0);
  cairo_paint(crf);
  cairo_surface_destroy(cst);
  return TRUE;
}