示例#1
0
/* Handle a draw/expose by finding the paragraphs that intersect
 * the region and reexposing them.
 */
void
draw (GtkWidget *layout, GdkRectangle *area)
{
  GList *tmp_list;
  guint height = 0;
  HDC hdc;
  const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND|GDK_GC_FONT;
  
  gdk_draw_rectangle (GTK_LAYOUT (layout)->bin_window,
		      layout->style->base_gc[layout->state],
		      TRUE,
		      area->x, area->y, 
		      area->width, area->height);
  
  gdk_gc_set_clip_rectangle (layout->style->text_gc[layout->state], area);

  hdc = gdk_win32_hdc_get (GTK_LAYOUT (layout)->bin_window,
			   layout->style->text_gc[GTK_STATE_NORMAL],
			   mask);
  tmp_list = paragraphs;
  while (tmp_list &&
	 height < area->y + area->height + GTK_LAYOUT (layout)->yoffset)
    {
      Paragraph *para = tmp_list->data;
      tmp_list = tmp_list->next;
      
      if (height + para->height >= GTK_LAYOUT (layout)->yoffset + area->y)
	pango_win32_render_layout (hdc, para->layout,
				   0, height - GTK_LAYOUT (layout)->yoffset);
      height += para->height;
    }

  gdk_win32_hdc_release (GTK_LAYOUT (layout)->bin_window,
			 layout->style->text_gc[GTK_STATE_NORMAL],
			 mask);
  gdk_gc_set_clip_rectangle (layout->style->text_gc[layout->state], NULL);

  if (highlight_para)
    xor_char (layout, area, highlight_para, highlight_offset);
}
示例#2
0
文件: window.c 项目: ysei/NetSurf
static gboolean
nsgtk_window_draw_event(GtkWidget *widget, cairo_t *cr, gpointer data)
{
	struct gui_window *gw = data;
	struct gui_window *z;
	struct rect clip;
	struct redraw_context ctx = {
		.interactive = true,
		.background_images = true,
		.plot = &nsgtk_plotters
	};

	double x1;
	double y1;
	double x2;
	double y2;

	assert(gw);
	assert(gw->bw);

	for (z = window_list; z && z != gw; z = z->next)
		continue;
	assert(z);
	assert(GTK_WIDGET(gw->layout) == widget);

	current_widget = (GtkWidget *)gw->layout;
	current_cr = cr;

	GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(gw->layout);
	GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(gw->layout);

	cairo_clip_extents(cr, &x1, &y1, &x2, &y2);

	clip.x0 = x1;
	clip.y0 = y1;
	clip.x1 = x2;
	clip.y1 = y2;

	browser_window_redraw(gw->bw,
			      -gtk_adjustment_get_value(hscroll),
			      -gtk_adjustment_get_value(vscroll),
			      &clip,
			      &ctx);

	if (gw->careth != 0) {
		nsgtk_plot_caret(gw->caretx, gw->carety, gw->careth);
	}

	current_widget = NULL;

	return FALSE;
}

#else

static gboolean
nsgtk_window_draw_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
	struct gui_window *gw = data;
	struct gui_window *z;
	struct rect clip;
	struct redraw_context ctx = {
		.interactive = true,
		.background_images = true,
		.plot = &nsgtk_plotters
	};

	assert(gw);
	assert(gw->bw);

	for (z = window_list; z && z != gw; z = z->next)
		continue;
	assert(z);
	assert(GTK_WIDGET(gw->layout) == widget);

	current_widget = (GtkWidget *)gw->layout;
	current_cr = gdk_cairo_create(nsgtk_layout_get_bin_window(gw->layout));

	clip.x0 = event->area.x;
	clip.y0 = event->area.y;
	clip.x1 = event->area.x + event->area.width;
	clip.y1 = event->area.y + event->area.height;

	browser_window_redraw(gw->bw, 0, 0, &clip, &ctx);

	if (gw->careth != 0) {
		nsgtk_plot_caret(gw->caretx, gw->carety, gw->careth);
	}

	cairo_destroy(current_cr);

	current_widget = NULL;

	return FALSE;
}

#endif

static gboolean nsgtk_window_motion_notify_event(GtkWidget *widget,
					  GdkEventMotion *event, gpointer data)
{
	struct gui_window *g = data;
	bool shift = event->state & GDK_SHIFT_MASK;
	bool ctrl = event->state & GDK_CONTROL_MASK;

	if ((abs(event->x - g->last_x) < 5) &&
	    (abs(event->y - g->last_y) < 5)) {
		/* Mouse hasn't moved far enough from press coordinate for this
		 * to be considered a drag. */
		return FALSE;
	} else {
		/* This is a drag, ensure it's always treated as such, even if
		 * we drag back over the press location */
		g->last_x = INT_MIN;
		g->last_y = INT_MIN;
	}

	if (g->mouse.state & BROWSER_MOUSE_PRESS_1) {
		/* Start button 1 drag */
		browser_window_mouse_click(g->bw, BROWSER_MOUSE_DRAG_1,
				g->mouse.pressed_x, g->mouse.pressed_y);

		/* Replace PRESS with HOLDING and declare drag in progress */
		g->mouse.state ^= (BROWSER_MOUSE_PRESS_1 |
				BROWSER_MOUSE_HOLDING_1);
		g->mouse.state |= BROWSER_MOUSE_DRAG_ON;
	} else if (g->mouse.state & BROWSER_MOUSE_PRESS_2) {
		/* Start button 2 drag */
		browser_window_mouse_click(g->bw, BROWSER_MOUSE_DRAG_2,
				g->mouse.pressed_x, g->mouse.pressed_y);

		/* Replace PRESS with HOLDING and declare drag in progress */
		g->mouse.state ^= (BROWSER_MOUSE_PRESS_2 |
				BROWSER_MOUSE_HOLDING_2);
		g->mouse.state |= BROWSER_MOUSE_DRAG_ON;
	}

	/* Handle modifiers being removed */
	if (g->mouse.state & BROWSER_MOUSE_MOD_1 && !shift)
		g->mouse.state ^= BROWSER_MOUSE_MOD_1;
	if (g->mouse.state & BROWSER_MOUSE_MOD_2 && !ctrl)
		g->mouse.state ^= BROWSER_MOUSE_MOD_2;

	browser_window_mouse_track(g->bw, g->mouse.state,
			event->x / browser_window_get_scale(g->bw),
			event->y / browser_window_get_scale(g->bw));

	return TRUE;
}

static gboolean nsgtk_window_button_press_event(GtkWidget *widget,
					 GdkEventButton *event, gpointer data)
{
	struct gui_window *g = data;

	gtk_widget_grab_focus(GTK_WIDGET(g->layout));
	gtk_widget_hide(GTK_WIDGET(nsgtk_scaffolding_history_window(
			g->scaffold)->window));

	g->mouse.pressed_x = event->x / browser_window_get_scale(g->bw);
	g->mouse.pressed_y = event->y / browser_window_get_scale(g->bw);

	switch (event->button) {
	case 1:	/* Left button, usually. Pass to core as BUTTON 1. */
		g->mouse.state = BROWSER_MOUSE_PRESS_1;
		break;

	case 2:	/* Middle button, usually. Pass to core as BUTTON 2 */
		g->mouse.state = BROWSER_MOUSE_PRESS_2;
		break;

	case 3:	/* Right button, usually. Action button, context menu. */
		browser_window_remove_caret(g->bw, true);
		nsgtk_scaffolding_popup_menu(g->scaffold, g->mouse.pressed_x,
				g->mouse.pressed_y);
		return TRUE;

	default:
		return FALSE;
	}

	/* Modify for double & triple clicks */
	if (event->type == GDK_3BUTTON_PRESS)
		g->mouse.state |= BROWSER_MOUSE_TRIPLE_CLICK;
	else if (event->type == GDK_2BUTTON_PRESS)
		g->mouse.state |= BROWSER_MOUSE_DOUBLE_CLICK;

	/* Handle the modifiers too */
	if (event->state & GDK_SHIFT_MASK)
		g->mouse.state |= BROWSER_MOUSE_MOD_1;
	if (event->state & GDK_CONTROL_MASK)
		g->mouse.state |= BROWSER_MOUSE_MOD_2;

	/* Record where we pressed, for use when determining whether to start
	 * a drag in motion notify events. */
	g->last_x = event->x;
	g->last_y = event->y;

	browser_window_mouse_click(g->bw, g->mouse.state, g->mouse.pressed_x,
			g->mouse.pressed_y);

	return TRUE;
}

static gboolean nsgtk_window_button_release_event(GtkWidget *widget,
					 GdkEventButton *event, gpointer data)
{
	struct gui_window *g = data;
	bool shift = event->state & GDK_SHIFT_MASK;
	bool ctrl = event->state & GDK_CONTROL_MASK;

	/* If the mouse state is PRESS then we are waiting for a release to emit
	 * a click event, otherwise just reset the state to nothing */
	if (g->mouse.state & BROWSER_MOUSE_PRESS_1)
		g->mouse.state ^= (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_CLICK_1);
	else if (g->mouse.state & BROWSER_MOUSE_PRESS_2)
		g->mouse.state ^= (BROWSER_MOUSE_PRESS_2 | BROWSER_MOUSE_CLICK_2);

	/* Handle modifiers being removed */
	if (g->mouse.state & BROWSER_MOUSE_MOD_1 && !shift)
		g->mouse.state ^= BROWSER_MOUSE_MOD_1;
	if (g->mouse.state & BROWSER_MOUSE_MOD_2 && !ctrl)
		g->mouse.state ^= BROWSER_MOUSE_MOD_2;

	if (g->mouse.state & (BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_CLICK_2)) {
		browser_window_mouse_click(g->bw, g->mouse.state,
				event->x / browser_window_get_scale(g->bw),
				event->y / browser_window_get_scale(g->bw));
	} else {
		browser_window_mouse_track(g->bw, 0,
				event->x / browser_window_get_scale(g->bw),
				event->y / browser_window_get_scale(g->bw));
	}

	g->mouse.state = 0;
	return TRUE;
}

static gboolean
nsgtk_window_scroll_event(GtkWidget *widget,
			  GdkEventScroll *event,
			  gpointer data)
{
	struct gui_window *g = data;
	double value;
	double deltax = 0;
	double deltay = 0;
	GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(g->layout);
	GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(g->layout);
	GtkAllocation alloc;

	switch (event->direction) {
	case GDK_SCROLL_LEFT:
		deltax = -1.0;
		break;

	case GDK_SCROLL_UP:
		deltay = -1.0;
		break;

	case GDK_SCROLL_RIGHT:
		deltax = 1.0;
		break;

	case GDK_SCROLL_DOWN:
		deltay = 1.0;
		break;

#if GTK_CHECK_VERSION(3,4,0)
	case GDK_SCROLL_SMOOTH:
		gdk_event_get_scroll_deltas((GdkEvent *)event, &deltax, &deltay);
		break;
#endif
	default:
		LOG(("Unhandled mouse scroll direction"));
		return TRUE;
	}

	deltax *= nsgtk_adjustment_get_step_increment(hscroll);
	deltay *= nsgtk_adjustment_get_step_increment(vscroll);

	if (browser_window_scroll_at_point(g->bw,
			event->x / browser_window_get_scale(g->bw),
			event->y / browser_window_get_scale(g->bw),
			deltax, deltay) != true) {

		/* core did not handle event so change adjustments */

		/* Horizontal */
		if (deltax != 0) {
			value = gtk_adjustment_get_value(hscroll) + deltax;

			/* @todo consider gtk_widget_get_allocated_width() */
			nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);

			if (value > nsgtk_adjustment_get_upper(hscroll) - alloc.width) {
				value = nsgtk_adjustment_get_upper(hscroll) - alloc.width;
			}
			if (value < nsgtk_adjustment_get_lower(hscroll)) {
				value = nsgtk_adjustment_get_lower(hscroll);
			}

			gtk_adjustment_set_value(hscroll, value);
		}

		/* Vertical */
		if (deltay != 0) {
			value = gtk_adjustment_get_value(vscroll) + deltay;

			/* @todo consider gtk_widget_get_allocated_height */
			nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);

			if (value > (nsgtk_adjustment_get_upper(vscroll) - alloc.height)) {
				value = nsgtk_adjustment_get_upper(vscroll) - alloc.height;
			}
			if (value < nsgtk_adjustment_get_lower(vscroll)) {
				value = nsgtk_adjustment_get_lower(vscroll);
			}

			gtk_adjustment_set_value(vscroll, value);
		}
	}

	return TRUE;
}

static gboolean nsgtk_window_keypress_event(GtkWidget *widget,
				GdkEventKey *event, gpointer data)
{
	struct gui_window *g = data;
	uint32_t nskey = gtk_gui_gdkkey_to_nskey(event);

	if (browser_window_key_press(g->bw, nskey))
		return TRUE;

	if ((event->state & 0x7) != 0)
		return TRUE;

	double value;
	GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(g->layout);
	GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(g->layout);
	GtkAllocation alloc;

	/* @todo consider gtk_widget_get_allocated_width() */
	nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);

	switch (event->keyval) {

	case GDK_KEY(Home):
	case GDK_KEY(KP_Home):
		value = nsgtk_adjustment_get_lower(vscroll);
		gtk_adjustment_set_value(vscroll, value);
		break;

	case GDK_KEY(End):
	case GDK_KEY(KP_End):
		value = nsgtk_adjustment_get_upper(vscroll) - alloc.height;

		if (value < nsgtk_adjustment_get_lower(vscroll))
			value = nsgtk_adjustment_get_lower(vscroll);

		gtk_adjustment_set_value(vscroll, value);
		break;

	case GDK_KEY(Left):
	case GDK_KEY(KP_Left):
		value = gtk_adjustment_get_value(hscroll) -
			nsgtk_adjustment_get_step_increment(hscroll);

		if (value < nsgtk_adjustment_get_lower(hscroll))
			value = nsgtk_adjustment_get_lower(hscroll);

		gtk_adjustment_set_value(hscroll, value);
		break;

	case GDK_KEY(Up):
	case GDK_KEY(KP_Up):
		value = gtk_adjustment_get_value(vscroll) -
			nsgtk_adjustment_get_step_increment(vscroll);

		if (value < nsgtk_adjustment_get_lower(vscroll))
			value = nsgtk_adjustment_get_lower(vscroll);

		gtk_adjustment_set_value(vscroll, value);
		break;

	case GDK_KEY(Right):
	case GDK_KEY(KP_Right):
		value = gtk_adjustment_get_value(hscroll) +
			nsgtk_adjustment_get_step_increment(hscroll);

		if (value > nsgtk_adjustment_get_upper(hscroll) - alloc.width)
			value = nsgtk_adjustment_get_upper(hscroll) - alloc.width;

		gtk_adjustment_set_value(hscroll, value);
		break;

	case GDK_KEY(Down):
	case GDK_KEY(KP_Down):
		value = gtk_adjustment_get_value(vscroll) +
			nsgtk_adjustment_get_step_increment(vscroll);

		if (value > nsgtk_adjustment_get_upper(vscroll) - alloc.height)
			value = nsgtk_adjustment_get_upper(vscroll) - alloc.height;

		gtk_adjustment_set_value(vscroll, value);
		break;

	case GDK_KEY(Page_Up):
	case GDK_KEY(KP_Page_Up):
		value = gtk_adjustment_get_value(vscroll) -
			nsgtk_adjustment_get_page_increment(vscroll);

		if (value < nsgtk_adjustment_get_lower(vscroll))
			value = nsgtk_adjustment_get_lower(vscroll);

		gtk_adjustment_set_value(vscroll, value);
		break;

	case GDK_KEY(Page_Down):
	case GDK_KEY(KP_Page_Down):
		value = gtk_adjustment_get_value(vscroll) +
			nsgtk_adjustment_get_page_increment(vscroll);

		if (value > nsgtk_adjustment_get_upper(vscroll) - alloc.height)
			value = nsgtk_adjustment_get_upper(vscroll) - alloc.height;

		gtk_adjustment_set_value(vscroll, value);
		break;

	default:
		break;

	}

	return TRUE;
}

static gboolean nsgtk_window_size_allocate_event(GtkWidget *widget,
		GtkAllocation *allocation, gpointer data)
{
	struct gui_window *g = data;

	g->bw->reformat_pending = true;
	browser_reformat_pending = true;


	return TRUE;
}


/**  when the pane position is changed update the user option
 *
 * The slightly awkward implementation with the first allocation flag
 * is necessary because the initial window creation does not cause an
 * allocate-event signal so the position value in the pane is incorrect
 * and we cannot know what it should be until after the allocation
 * (which did not generate a signal) is done as the user position is a
 * percentage of pane total width not an absolute value.
 */
static void
nsgtk_paned_notify__position(GObject *gobject, GParamSpec *pspec, gpointer data)
{
	struct gui_window *g = data;
	GtkAllocation pane_alloc;

	gtk_widget_get_allocation(GTK_WIDGET(g->paned), &pane_alloc);

	if (g->paned_sized == false)
	{
		g->paned_sized = true;
		gtk_paned_set_position(g->paned,
		(nsoption_int(toolbar_status_size) * pane_alloc.width) / 10000);
		return;
	}

	nsoption_set_int(toolbar_status_size,
	 ((gtk_paned_get_position(g->paned) * 10000) / (pane_alloc.width - 1)));
}

/** Set status bar / scroll bar proportion according to user option
 * when pane is resized.
 */
static gboolean nsgtk_paned_size_allocate_event(GtkWidget *widget,
		GtkAllocation *allocation, gpointer data)
{
	gtk_paned_set_position(GTK_PANED(widget),
	       (nsoption_int(toolbar_status_size) * allocation->width) / 10000);

	return TRUE;
}

/* destroy the browsing context as there is nothing to display it now */
static void window_destroy(GtkWidget *widget, gpointer data)
{
	struct gui_window *gw = data;

	browser_window_destroy(gw->bw);
}

/* Core interface documented in desktop/gui.h to create a gui_window */
static struct gui_window *
gui_window_create(struct browser_window *bw,
		struct gui_window *existing,
		gui_window_create_flags flags)
{
	struct gui_window *g; /**< what we're creating to return */
	GError* error = NULL;
	bool tempback;
	GtkBuilder* xml;

	/* open builder file first to ease error handling on faliure */
	xml = gtk_builder_new();
	if (!gtk_builder_add_from_file(xml,
				       glade_file_location->tabcontents,
				       &error)) {
		g_warning ("Couldn't load builder file: %s", error->message);
		g_error_free(error);
		return NULL;
	}

	g = calloc(1, sizeof(*g));
	if (!g) {
		warn_user("NoMemory", 0);
		g_object_unref(xml);
		return NULL;
	}

	LOG(("Creating gui window %p for browser window %p", g, bw));

	g->bw = bw;
	g->mouse.state = 0;
	g->current_pointer = GUI_POINTER_DEFAULT;
	if (flags & GW_CREATE_CLONE) {
		assert(existing != NULL);
		bw->scale = existing->bw->scale;
	} else {
		bw->scale = nsoption_int(scale) / 100;
	}

	/* attach scaffold */
	if (flags & GW_CREATE_TAB) {
		assert(existing != NULL);
		g->scaffold = existing->scaffold;
	} else {
		/* Now construct and attach a scaffold */
		g->scaffold = nsgtk_new_scaffolding(g);
	}
	if (g->scaffold == NULL) {
		warn_user("NoMemory", 0);
		free(g);
		g_object_unref(xml);
		return NULL;
	}

	/* Construct our primary elements */
	g->container = GTK_WIDGET(gtk_builder_get_object(xml, "tabContents"));
	g->layout = GTK_LAYOUT(gtk_builder_get_object(xml, "layout"));
	g->status_bar = GTK_LABEL(gtk_builder_get_object(xml, "status_bar"));
	g->paned = GTK_PANED(gtk_builder_get_object(xml, "hpaned1"));


	/* add new gui window to global list (push_top) */
	if (window_list) {
		window_list->prev = g;
	}
	g->next = window_list;
	g->prev = NULL;
	window_list = g;

	/* set the events we're interested in receiving from the browser's
	 * drawing area.
	 */
	gtk_widget_add_events(GTK_WIDGET(g->layout),
				GDK_EXPOSURE_MASK |
				GDK_LEAVE_NOTIFY_MASK |
				GDK_BUTTON_PRESS_MASK |
				GDK_BUTTON_RELEASE_MASK |
				GDK_POINTER_MOTION_MASK |
				GDK_POINTER_MOTION_HINT_MASK |
				GDK_KEY_PRESS_MASK |
				GDK_KEY_RELEASE_MASK |
				GDK_SCROLL_MASK);
	nsgtk_widget_set_can_focus(GTK_WIDGET(g->layout), TRUE);

	/* set the default background colour of the drawing area to white. */
	nsgtk_widget_override_background_color(GTK_WIDGET(g->layout),
					       GTK_STATE_NORMAL,
					       0, 0xffff, 0xffff, 0xffff);

	nsgtk_connect_draw_event(GTK_WIDGET(g->layout),
				 G_CALLBACK(nsgtk_window_draw_event), g);

	/* layout signals */
	CONNECT(g->layout, "motion-notify-event",
			nsgtk_window_motion_notify_event, g);
	g->signalhandler[NSGTK_WINDOW_SIGNAL_CLICK] =
			CONNECT(g->layout, "button-press-event",
			nsgtk_window_button_press_event, g);
	CONNECT(g->layout, "button-release-event",
			nsgtk_window_button_release_event, g);
	CONNECT(g->layout, "key-press-event",
			nsgtk_window_keypress_event, g);
	CONNECT(g->layout, "size-allocate",
			nsgtk_window_size_allocate_event, g);
	CONNECT(g->layout, "scroll-event",
			nsgtk_window_scroll_event, g);

	/* status pane signals */
	CONNECT(g->paned, "size-allocate",
		nsgtk_paned_size_allocate_event, g);

	CONNECT(g->paned, "notify::position",
		nsgtk_paned_notify__position, g);

	/* gtk container destructor */
	CONNECT(g->container, "destroy",
		window_destroy, g);

	/* add the tab container to the scaffold notebook */
	switch (temp_open_background) {
	case -1:
		tempback = !(nsoption_bool(focus_new));
		break;
	case 0:
		tempback = false;
		break;
	default:
		tempback = true;
		break;
	}
	nsgtk_tab_add(g, g->container, tempback);

	/* safe to drop the reference to the xml as the container is
	 * referenced by the notebook now.
	 */
	g_object_unref(xml);

	return g;
}



void nsgtk_reflow_all_windows(void)
{
	for (struct gui_window *g = window_list; g; g = g->next) {
		nsgtk_tab_options_changed(
				nsgtk_scaffolding_notebook(g->scaffold));
		g->bw->reformat_pending = true;
	}

	browser_reformat_pending = true;
}


/**
 * Process pending reformats
 */

void nsgtk_window_process_reformats(void)
{
	struct gui_window *g;
	GtkAllocation alloc;

	browser_reformat_pending = false;
	for (g = window_list; g; g = g->next) {
		if (!g->bw->reformat_pending)
			continue;

		g->bw->reformat_pending = false;

		/* @todo consider gtk_widget_get_allocated_width() */
		nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);

		browser_window_reformat(g->bw, false, alloc.width, alloc.height);
	}
}

void nsgtk_window_destroy_browser(struct gui_window *gw)
{
	/* remove tab */
	gtk_widget_destroy(gw->container);
}
示例#3
0
/*
 * Calculate the size of the scrolled area and allocate the top-level
 * widget. This function is called when the top-level Dw widget has
 * changed its size etc.
 */
void Dw_gtk_viewport_calc_size (GtkDwViewport *viewport)
{
   GtkWidget *widget;
   GtkScrolledWindow *scrolled;

   DwRequisition child_requisition;
   DwAllocation child_allocation;
   gint border_width,  space;

   GtkRequisition bar_requisition;
   gint max_width, max_height, bar_width_diff, bar_height_diff, child_height;

   if (viewport->calc_size_blocked)
      return;

   viewport->calc_size_blocked = TRUE;

   if (viewport->child) {
      /*
       * Determine the size hints for the Dw widget. This is a bit
       * tricky, because you must know if scrollbars are visible or
       * not, which depends on the size of the Dw widget, which then
       * depends on the hints. The idea is to test several
       * configurations, there are four of them, from combining the
       * cases horizontal/vertical scrollbar visible/invisible.
       *
       * For optimization, the horizontal scrollbar is currently not
       * regarded, the height hint is always the same, as if the
       * scrollbar was allways visible. In future, this may be
       * implemented correctly, by using the minimal width to optimize
       * most cases. (Minimal widths will also be used by tables.)
       *
       * Furthermore, the last result (vertical scrollbar visible or
       * not) is stored in the viewport, and tested first. This will
       * make a second test only necessary when the visibility
       * switches, which normally happens only once when filling the
       * page with text. (Actually, this assumes that the page size is
       * always *growing*, but this is nevertheless true in dillo.)
       */

      widget = GTK_WIDGET (viewport);
      scrolled = GTK_SCROLLED_WINDOW (widget->parent->parent);
      space = GTK_SCROLLED_WINDOW_CLASS(GTK_OBJECT(scrolled)->klass)
         ->scrollbar_spacing;
      border_width = GTK_CONTAINER(viewport)->border_width;

      gtk_widget_size_request (scrolled->vscrollbar, &bar_requisition);
      bar_width_diff = bar_requisition.width + space;
      max_width = widget->allocation.width - 2 * border_width;
      if (scrolled->vscrollbar_visible)
         max_width += bar_width_diff;

      gtk_widget_size_request (scrolled->hscrollbar, &bar_requisition);
      bar_height_diff = bar_requisition.height + space;
      max_height = widget->allocation.height - 2 * border_width;
      if (scrolled->hscrollbar_visible)
         max_height += bar_height_diff;

      DEBUG_MSG (2, "------------------------------------------------->\n");
      DEBUG_MSG (2, "Dw_gtk_viewport_calc_size: %d x %d (%c/%c) -> %d x %d\n",
                 widget->allocation.width, widget->allocation.height,
                 scrolled->vscrollbar_visible ? 't' : 'f',
                 scrolled->hscrollbar_visible ? 't' : 'f',
                 max_width, max_height);

      if (scrolled->vscrollbar_policy == GTK_POLICY_NEVER)
         child_height = max_height;
      else
         child_height = max_height - bar_height_diff;

      switch (scrolled->vscrollbar_policy) {
      case GTK_POLICY_ALWAYS:
         Dw_gtk_viewport_calc_child_size (viewport, max_width - bar_width_diff,
                                          child_height,
                                          &child_requisition);
         break;

      case GTK_POLICY_AUTOMATIC:
         if (viewport->vscrollbar_used) {
            DEBUG_MSG (2, "Testing with vertical scrollbar ...\n");
            Dw_gtk_viewport_calc_child_size (viewport,
                                             max_width - bar_width_diff,
                                             child_height,
                                             &child_requisition);

            if (child_requisition.ascent
                + child_requisition.descent <= child_height) {
               DEBUG_MSG (2, "   failed!\n");
               Dw_gtk_viewport_calc_child_size (viewport, max_width,
                                                child_height,
                                                &child_requisition);
               viewport->vscrollbar_used = TRUE;
            }

         } else {
            DEBUG_MSG (2, "Testing without vertical scrollbar ...\n");
            Dw_gtk_viewport_calc_child_size (viewport, max_width,
                                             child_height,
                                             &child_requisition);

            /* todo: see above */
            if (child_requisition.ascent
                + child_requisition.descent > child_height) {
               DEBUG_MSG (2, "   failed!\n");
               Dw_gtk_viewport_calc_child_size (viewport,
                                                max_width - bar_width_diff,
                                                child_height,
                                                &child_requisition);
               viewport->vscrollbar_used = TRUE;
            }
         }
         break;

      case GTK_POLICY_NEVER:
         Dw_gtk_viewport_calc_child_size (viewport, max_width,
                                          child_height,
                                          &child_requisition);
      }

      child_allocation.x = border_width;
      child_allocation.y = border_width;
      child_allocation.width = child_requisition.width;
      child_allocation.ascent = child_requisition.ascent;
      child_allocation.descent = child_requisition.descent;
      p_Dw_widget_size_allocate (viewport->child, &child_allocation);

      gtk_layout_set_size (GTK_LAYOUT (viewport),
                           child_requisition.width + 2 * border_width,
                           child_requisition.ascent + child_requisition.descent
                           + 2 * border_width);

      DEBUG_MSG (1, "Setting size to %d x %d\n",
                 child_requisition.width + 2 * border_width,
                 child_requisition.ascent + child_requisition.descent
                 + 2 * border_width);

      DEBUG_MSG (2, "<-------------------------------------------------\n");
   } else {
      gtk_layout_set_size (GTK_LAYOUT (viewport), 1, 1);
      viewport->hscrollbar_used = FALSE;
      viewport->vscrollbar_used = FALSE;
   }

   Dw_gtk_viewport_update_anchor (viewport);
   gtk_widget_queue_draw (GTK_WIDGET (viewport));

   viewport->calc_size_blocked = FALSE;
}
示例#4
0
int main(int argc, char **argv){
	gtk_init (&argc, &argv);

	GtkWidget *p_window;
	GdkPixbuf *Pixbuf; 
	GError *error=NULL;

	/* Creation de la fenetre principale de notre application */
	p_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_window_set_position(GTK_WINDOW(p_window), GTK_WIN_POS_CENTER);
	gtk_window_set_title(GTK_WINDOW(p_window),"Face Identifier Project");
	gtk_window_set_default_size(GTK_WINDOW(p_window),800,500);
	Pixbuf = gdk_pixbuf_new_from_file("logo.jpeg",&error);
	gtk_window_set_icon(GTK_WINDOW(p_window),Pixbuf);
	GdkGeometry hints;
	hints.min_width = 800;
	hints.max_width = 800;
	hints.min_height = 500;
	hints.max_height = 500;

	gtk_window_set_geometry_hints(
			GTK_WINDOW(p_window),
			p_window,
			&hints,
			(GdkWindowHints)(GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE));

	/* Creation des buttons */
	GtkWidget *p_button1= gtk_button_new_with_label("Search");
	gtk_widget_set_size_request(p_button1,120,90);
	GtkWidget *p_button2= gtk_button_new_with_label("Identify");
	gtk_widget_set_size_request(p_button2,120,90);
	GtkWidget *p_button3= gtk_button_new_with_label("Add");
	gtk_widget_set_size_request(p_button3,120,90);

	/* Insertion des boutons */
	g_signal_connect (G_OBJECT (p_button1), "clicked", G_CALLBACK (cb_open), NULL);
	g_signal_connect (G_OBJECT (p_button2), "clicked", G_CALLBACK (face_detection), NULL);
	g_signal_connect (G_OBJECT (p_button3), "clicked", G_CALLBACK (cb_add), NULL);

	layout = gtk_layout_new(NULL, NULL);
	GtkWidget *backgrd = gtk_image_new_from_file("backgroundUI.jpg");
	GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
	GtkWidget *scrollbar = gtk_scrolled_window_new(NULL, NULL);
	
	DIR* FD = opendir ("./DataBase");
	struct dirent* in_file;

	GtkWidget *ImgScr;
	GdkPixbuf *Pbx;
	GtkWidget *Label;

	if (NULL != FD) 
	{
		while ((in_file =readdir(FD)))
		{
			if (!strcmp (in_file->d_name, "."))
				continue;
			if (!strcmp (in_file->d_name, ".."))    
				continue;

			Pbx = gdk_pixbuf_new_from_file_at_scale (concat("DataBase/",in_file->d_name),220,150,TRUE,NULL);
			ImgScr = gtk_image_new_from_pixbuf(Pbx);

			Label = gtk_label_new (remove_after_dot(in_file->d_name));
			g_object_unref (Pbx);
			gtk_box_pack_start(GTK_BOX(box), ImgScr, FALSE, FALSE, 3);
			gtk_box_pack_start(GTK_BOX(box), Label, FALSE, FALSE, 3);
		}
		(void) closedir (FD);
	}

	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollbar),GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);

	gtk_widget_set_size_request(scrollbar, 253,398);
	gtk_container_add(GTK_CONTAINER(scrollbar), box);

	gtk_layout_put(GTK_LAYOUT(layout), backgrd, 0, 0);

	gtk_container_add(GTK_CONTAINER(p_window), layout);
	gtk_layout_put(GTK_LAYOUT (layout), scrollbar, 548,0);

	gtk_layout_put (GTK_LAYOUT (layout), p_button1, 250, 405);
	gtk_layout_put (GTK_LAYOUT (layout), p_button2, 100, 405);
	gtk_layout_put (GTK_LAYOUT (layout), p_button3, 400, 405);

	g_signal_connect(G_OBJECT(p_window), "destroy",
			G_CALLBACK(gtk_main_quit), NULL);
	/* Affichage de la fenetre principale */
	gtk_widget_show_all (p_window); 
	/* Lancement de la boucle principale */
	gtk_main ();
	return EXIT_SUCCESS;

	return 0;
}
示例#5
0
文件: window.c 项目: fmf/music-widget
gboolean update_track_info(track_t *t)
{
	gchar dummy[10], *markup = NULL, *markupProps = NULL;
	gint i = 0;
	GdkPixbuf *starPix = NULL;
	PangoLayout *layout = NULL;


	get_track_info(&t->track);
	if (!validate_track_info(&t->track)) {
		g_print("Malformed track data\n");
		gtk_main_quit();
	}


	if (t->track.changed) {
		gtk_image_set_from_file(GTK_IMAGE(t->trackw.image), t->track.artworkId);


		markupProps = g_strdup("<span font='Sans 11' font_weight='bold' color='#FFFFFF'>%s</span>");


		t->track.x.name = 0;
		t->track.x.name2 = 0;

		markup = g_markup_printf_escaped(markupProps, t->track.name);
		gtk_label_set_markup(GTK_LABEL(t->trackw.label.name), markup);
		layout = gtk_label_get_layout(GTK_LABEL(t->trackw.label.name));
		pango_layout_get_pixel_size(PANGO_LAYOUT(layout), &t->track.nameLen, NULL);

		if (t->track.nameLen > SCROLL_SIZE_W) {
			if (t->track.nameScroll)
				g_source_remove(t->track.nameTag);
			t->track.nameScroll = TRUE;
			t->track.nameTag = g_timeout_add(SCROLL_SPEED, (GSourceFunc) scroll_label_name, t);
		} else if (t->track.nameScroll) {
			/* if the previous label was scrolled and this one doesn't need do
			 * it stops the scrolling and puts the label at it's origin. Failure to do
			 * so causes the new label to be displayed at the last position the previous
			 * label was scrolled. */
			g_source_remove(t->track.nameTag);
			gtk_layout_move(GTK_LAYOUT(t->trackw.layout.name), t->trackw.label.name, 0, 0);
			t->track.nameScroll = FALSE;
		}
		g_free(markup);


		t->track.x.artist = 0;
		t->track.x.artist2 = 0;

		markup = g_markup_printf_escaped(markupProps, t->track.artist);
		gtk_label_set_markup(GTK_LABEL(t->trackw.label.artist), markup);
		layout = gtk_label_get_layout(GTK_LABEL(t->trackw.label.artist));
		pango_layout_get_pixel_size(PANGO_LAYOUT(layout), &t->track.artistLen, NULL);

		if (t->track.artistLen > SCROLL_SIZE_W-23) {
			if (t->track.artistScroll)
				g_source_remove(t->track.artistTag);
			t->track.artistScroll = TRUE;
			t->track.artistTag = g_timeout_add(SCROLL_SPEED, (GSourceFunc) scroll_label_artist, t);
		} else if (t->track.artistScroll) {
			g_source_remove(t->track.artistTag);
			gtk_layout_move(GTK_LAYOUT(t->trackw.layout.artist), t->trackw.label.artist, 0, 0);
			t->track.artistScroll = FALSE;
		}
		g_free(markup);


		t->track.x.album = 0;
		t->track.x.album2 = 0;

		markup = g_markup_printf_escaped(markupProps, t->track.album);
		gtk_label_set_markup(GTK_LABEL(t->trackw.label.album), markup);
		layout = gtk_label_get_layout(GTK_LABEL(t->trackw.label.album));
		pango_layout_get_pixel_size(PANGO_LAYOUT(layout), &t->track.albumLen, NULL);

		if (t->track.albumLen > SCROLL_SIZE_W-40) {
			if (t->track.albumScroll)
				g_source_remove(t->track.albumTag);
			t->track.albumScroll = TRUE;
			t->track.albumTag = g_timeout_add(SCROLL_SPEED, (GSourceFunc) scroll_label_album, t);
		} else if (t->track.albumScroll) {
			g_source_remove(t->track.albumTag);
			gtk_layout_move(GTK_LAYOUT(t->trackw.layout.album), t->trackw.label.album, 0, 0);
			t->track.albumScroll = FALSE;
		}
		g_free(markup);
		g_free(markupProps);


		markupProps = g_strdup("<span font='Sans 11' color='#FFFFFF'>%s</span>");
		markup = g_markup_printf_escaped(markupProps, t->track.genre);
		gtk_label_set_markup(GTK_LABEL(t->trackw.genre), markup);
		g_free(markup);

		g_sprintf(dummy, "%d", t->track.year);
		markup = g_markup_printf_escaped(markupProps, dummy);
		gtk_label_set_markup(GTK_LABEL(t->trackw.year), markup);
		g_free(markup);
		dummy[0] = '\0';

		format_time(dummy, t->track.length);
		markup = g_markup_printf_escaped(markupProps, dummy);
		gtk_label_set_markup(GTK_LABEL(t->trackw.length), markup);
		g_free(markup);
		g_free(markupProps);
		dummy[0] = '\0';


		gtk_range_set_range(GTK_RANGE(t->trackw.slider), 0, t->track.length);

		/* set the rating */
		starPix = gdk_pixbuf_new_from_xpm_data(starFull_xpm);
		for (i = 1; i <= t->track.rating; i++)
			gtk_image_set_from_pixbuf(GTK_IMAGE(t->trackw.stars[i-1]), GDK_PIXBUF(starPix));
		g_object_unref(starPix);
		starPix = gdk_pixbuf_new_from_xpm_data(starHollow_xpm);
		while (i <= 5) {
			gtk_image_set_from_pixbuf(GTK_IMAGE(t->trackw.stars[i-1]), GDK_PIXBUF(starPix));
			i++;
		}
		g_object_unref(starPix);
	}


	markupProps = g_strdup("<span font='Sans 11' color='#FFFFFF'>%s</span>");

	g_sprintf(dummy, "%d", t->track.playcount);
	markup = g_markup_printf_escaped(markupProps, dummy);
	gtk_label_set_markup(GTK_LABEL(t->trackw.playcount), markup);
	g_free(markup);
	dummy[0] = '\0';

	format_time(dummy, t->track.position);
	markup = g_markup_printf_escaped(markupProps, dummy);
	gtk_label_set_markup(GTK_LABEL(t->trackw.position), markup);
	g_free(markup);
	g_free(markupProps);
	dummy[0] = '\0';


	gtk_range_set_fill_level(GTK_RANGE(t->trackw.slider), t->track.position);
	gtk_range_set_value(GTK_RANGE(t->trackw.slider), t->track.position);


	/* NOTE: reuses the starPix pixbuf */
	if (t->playerInfo.counter == 4) { /* 2 seconds on currently UPDATE_SPEED */
		if (!get_player_info(&t->playerInfo))
				return FALSE;
		else {
			if (t->playerInfo.status) {
				starPix = gdk_pixbuf_new_from_xpm_data(pause_xpm);
				gtk_image_set_from_pixbuf(GTK_IMAGE(t->playerControls.playPause), starPix);
				g_object_unref(starPix);
			} else {
				starPix = gdk_pixbuf_new_from_xpm_data(play_xpm);
				gtk_image_set_from_pixbuf(GTK_IMAGE(t->playerControls.playPause), starPix);
				g_object_unref(starPix);
			}

			if (t->playerInfo.repeat == 0) {
				starPix = gdk_pixbuf_new_from_xpm_data(repeatOff_xpm);
				gtk_image_set_from_pixbuf(GTK_IMAGE(t->playerControls.repeat), starPix);
				g_object_unref(starPix);
			} else if (t->playerInfo.repeat == 1) {
				starPix = gdk_pixbuf_new_from_xpm_data(repeatAll_xpm);
				gtk_image_set_from_pixbuf(GTK_IMAGE(t->playerControls.repeat), starPix);
				g_object_unref(starPix);
			} else {
				starPix = gdk_pixbuf_new_from_xpm_data(repeatSingle_xpm);
				gtk_image_set_from_pixbuf(GTK_IMAGE(t->playerControls.repeat), starPix);
				g_object_unref(starPix);
			}

			if (t->playerInfo.shuffle) {
				starPix = gdk_pixbuf_new_from_xpm_data(shuffleOn_xpm);
				gtk_image_set_from_pixbuf(GTK_IMAGE(t->playerControls.shuffle), starPix);
				g_object_unref(starPix);
			} else {
				starPix = gdk_pixbuf_new_from_xpm_data(shuffleOff_xpm);
				gtk_image_set_from_pixbuf(GTK_IMAGE(t->playerControls.shuffle), starPix);
				g_object_unref(starPix);
			}
		}

		t->playerInfo.counter = 0;
	}


	free_track_info(&t->track);
	t->playerInfo.counter++;

	return TRUE;
}
示例#6
0
/*
 * ECell::event method
 */
static gint
ect_event (ECellView *ecell_view,
           GdkEvent *event,
           gint model_col,
           gint view_col,
           gint row,
           ECellFlags flags,
           ECellActions *actions)
{
	GtkLayout *layout;
	GdkWindow *window;
	ECellTreeView *tree_view = (ECellTreeView *) ecell_view;
	ETreeModel *tree_model = e_cell_tree_get_tree_model (ecell_view->e_table_model, row);
	ETreeTableAdapter *etta = e_cell_tree_get_tree_table_adapter (ecell_view->e_table_model, row);
	ETreePath node = e_cell_tree_get_node (ecell_view->e_table_model, row);
	gint offset = offset_of_node (ecell_view->e_table_model, row);
	gint result;

	layout = GTK_LAYOUT (tree_view->canvas);
	window = gtk_layout_get_bin_window (layout);

	switch (event->type) {
	case GDK_BUTTON_PRESS:

		if (event_in_expander (event, offset, 0)) {
			if (e_tree_model_node_is_expandable (tree_model, node)) {
				gboolean expanded = e_tree_table_adapter_node_is_expanded (etta, node);
				gint tmp_row = row;
				GdkRectangle area;
				animate_closure_t *closure = g_new0 (animate_closure_t, 1);
				cairo_t *cr;
				gint hgt;

				e_table_item_get_cell_geometry (
					tree_view->cell_view.e_table_item_view,
					&tmp_row, &view_col, &area.x, &area.y, NULL, &area.height);
				area.width = offset - 2;
				hgt = e_cell_height (ecell_view, model_col, view_col, row);

				if (hgt != area.height) /* Composite cells */
					area.height += hgt;

				cr = gdk_cairo_create (window);
				draw_expander (
					tree_view, cr, expanded ?
					GTK_EXPANDER_SEMI_EXPANDED :
					GTK_EXPANDER_SEMI_COLLAPSED,
					GTK_STATE_NORMAL, &area);
				cairo_destroy (cr);

				closure->ectv = tree_view;
				closure->etta = etta;
				closure->node = node;
				closure->expanded = expanded;
				closure->area = area;
				tree_view->animate_timeout =
					e_named_timeout_add (
					50, animate_expander, closure);
				return TRUE;
			}
		}
		else if (event->button.x < (offset - INDENT_AMOUNT))
			return FALSE;
		break;

	case GDK_MOTION_NOTIFY:

		if (e_tree_model_node_is_expandable (tree_model, node)) {
			gint height = ect_height (ecell_view, model_col, view_col, row);
			GdkRectangle area;
			gboolean in_expander = event_in_expander (event, offset, height);

			if (tree_view->prelit ^ in_expander) {
				gint tmp_row = row;
				cairo_t *cr;

				e_table_item_get_cell_geometry (
					tree_view->cell_view.e_table_item_view,
					&tmp_row, &view_col, &area.x, &area.y, NULL, &area.height);
				area.width = offset - 2;

				cr = gdk_cairo_create (window);
				draw_expander (
					tree_view, cr,
					e_tree_table_adapter_node_is_expanded (etta, node) ?
					GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED,
					in_expander ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL, &area);
				cairo_destroy (cr);

				tree_view->prelit = in_expander;
				return TRUE;
			}

		}
		break;

	case GDK_LEAVE_NOTIFY:

		if (tree_view->prelit) {
			gint tmp_row = row;
			GdkRectangle area;
			cairo_t *cr;

			e_table_item_get_cell_geometry (
				tree_view->cell_view.e_table_item_view,
				&tmp_row, &view_col, &area.x, &area.y, NULL, &area.height);
			area.width = offset - 2;

			cr = gdk_cairo_create (window);
			draw_expander (
				tree_view, cr,
				e_tree_table_adapter_node_is_expanded (etta, node) ?
				GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED,
				GTK_STATE_NORMAL, &area);
			cairo_destroy (cr);

			tree_view->prelit = FALSE;
		}
		return TRUE;

	default:
		break;
	}

	adjust_event_position (event, -offset);
	result = e_cell_event (tree_view->subcell_view, event, model_col, view_col, row, flags, actions);
	adjust_event_position (event, offset);

	return result;
}
void
gnc_item_edit_show_popup (GncItemEdit *item_edit)
{
    GtkToggleButton *toggle;
    GtkAdjustment *vadj, *hadj;
    GtkAllocation alloc;
    GnucashSheet *sheet;
    gint x, y, w, h;
    gint y_offset, x_offset;
    gint popup_x, popup_y;
    gint popup_w = -1, popup_h = -1;
    gint popup_max_width, popup_max_height;
    gint view_width, view_height;
    gint down_height, up_height;
    gint sheet_width;

    g_return_if_fail (item_edit != NULL);
    g_return_if_fail (GNC_IS_ITEM_EDIT(item_edit));

    if (!item_edit->is_popup)
        return;

    sheet = item_edit->sheet;

    sheet_width = sheet->width;

    gtk_widget_get_allocation (GTK_WIDGET (sheet), &alloc);
    view_height = alloc.height;
    view_width  = alloc.width;

    vadj = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(sheet));
    hadj = gtk_scrollable_get_hadjustment(GTK_SCROLLABLE(sheet));

    y_offset = gtk_adjustment_get_value(vadj);
    x_offset = gtk_adjustment_get_value(hadj);
    gnc_item_edit_get_pixel_coords (item_edit, &x, &y, &w, &h);

    popup_x = x;

    up_height = y - y_offset;
    down_height = view_height - (up_height + h);

    popup_max_height = MAX (up_height, down_height);
    popup_max_width = sheet_width - popup_x + x_offset; // always pops to the right

    if (item_edit->popup_get_height)
        popup_h = item_edit->popup_get_height
                       (item_edit->popup_item, popup_max_height, h,
                        item_edit->popup_user_data);

    if (item_edit->popup_autosize)
        popup_w =
            item_edit->popup_autosize (item_edit->popup_item,
                                       popup_max_width,
                                       item_edit->popup_user_data);
    else
        popup_w = 0;

    // Adjust the popup_y point based on popping above or below
    if (up_height > down_height)
        popup_y = y - popup_h;
    else
        popup_y = y + h;

    if (!gtk_widget_get_parent (item_edit->popup_item))
        gtk_layout_put (GTK_LAYOUT(sheet), item_edit->popup_item, popup_x, popup_y);

    gtk_widget_set_size_request (item_edit->popup_item, popup_w - 1, popup_h);

    toggle = GTK_TOGGLE_BUTTON(item_edit->popup_toggle.tbutton);

    if (!gtk_toggle_button_get_active (toggle))
    {
        block_toggle_signals (item_edit);
        gtk_toggle_button_set_active (toggle, TRUE);
        unblock_toggle_signals (item_edit);
    }

    // set the popup arrow direction up
    item_edit->popup_toggle.arrow_down = FALSE;

    if (item_edit->popup_set_focus)
        item_edit->popup_set_focus (item_edit->popup_item,
                                    item_edit->popup_user_data);

    if (item_edit->popup_post_show)
        item_edit->popup_post_show (item_edit->popup_item,
                                    item_edit->popup_user_data);

    if (item_edit->popup_get_width)
    {
        int popup_width;

        popup_width = item_edit->popup_get_width
                      (item_edit->popup_item,
                       item_edit->popup_user_data);

        if (popup_width > popup_w)
            popup_width = popup_w;

        if (popup_width > popup_max_width)
        {
            popup_x -= popup_width - popup_max_width;
            popup_x = MAX (0, popup_x);
        }
        else
            popup_x = x;

        gtk_layout_move (GTK_LAYOUT(sheet), item_edit->popup_item, popup_x, popup_y);
    }
}
示例#8
0
static void timing_inst_layout_refresh(struct vgpu_compute_unit_t *compute_unit)
{
	struct vgpu_uop_t *uop;
	int x, y, top_y;
	int i;

	/* Check if diagram needs to get recalculated */
	if (timing_dia_needs_refresh(compute_unit))
		timing_dia_refresh(compute_unit);

	/* Remove all child widgets in 'timing_inst_layout' */
	gtk_container_destroy_children(GTK_CONTAINER(compute_unit->timing_inst_layout));

	/* White background */
	GdkColor color;
	gdk_color_parse("white", &color);

	/* Attributes for labels */
	PangoAttrList *attrs;
	PangoAttribute *size_attr;
	attrs = pango_attr_list_new();
	size_attr = pango_attr_size_new_absolute(13 << 10);
	pango_attr_list_insert(attrs, size_attr);

	/* Instruction list */
	top_y = -((int) compute_unit->timing_dia_vscrollbar_value % timing_dia_row_height);
	y = top_y;
	for (i = 0; i < compute_unit->timing_dia_height; i++)
	{
		char text[MAX_STRING_SIZE];

		GtkWidget *label;
		GtkWidget *event_box;
		GtkRequisition req;

		uop = list_get(compute_unit->timing_inst_uops, i);
		if (uop)
		{
			/* Create label + event box for 'I-x' */
			x = 0;
			snprintf(text, sizeof text, "I-%d", uop->id);
			label = gtk_label_new(text);
			event_box = gtk_event_box_new();
			gtk_widget_modify_bg(event_box, GTK_STATE_NORMAL, &color);
			gtk_container_add(GTK_CONTAINER(event_box), label);
			gtk_layout_put(GTK_LAYOUT(compute_unit->timing_inst_layout), event_box, x, y);
			gtk_widget_set_size_request(event_box, 40, timing_dia_row_height);
			gtk_label_set_attributes(GTK_LABEL(label), attrs);
			g_signal_connect(G_OBJECT(event_box), "enter-notify-event", G_CALLBACK(list_layout_label_enter_notify_event), NULL);
			g_signal_connect(G_OBJECT(event_box), "leave-notify-event", G_CALLBACK(list_layout_label_leave_notify_event), NULL);
			g_signal_connect(G_OBJECT(event_box), "button-press-event", G_CALLBACK(timing_inst_layout_clicked_event), uop);

			/* Create label + event box for instruction name */
			x = 42;
			label = gtk_label_new(NULL);
			event_box = gtk_event_box_new();
			gtk_widget_modify_bg(event_box, GTK_STATE_NORMAL, &color);
			vgpu_uop_get_markup(uop, text, sizeof(text));
			gtk_label_set_markup(GTK_LABEL(label), text);
			gtk_container_add(GTK_CONTAINER(event_box), label);
			gtk_layout_put(GTK_LAYOUT(compute_unit->timing_inst_layout), event_box, x, y);
			gtk_widget_size_request(label, &req);
			gtk_widget_set_size_request(event_box, req.width, timing_dia_row_height);
			gtk_label_set_attributes(GTK_LABEL(label), attrs);
			gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);

		}
		y += timing_dia_row_height;
	}
	gtk_widget_show_all(compute_unit->timing_inst_layout);
}
示例#9
0
void ygtk_html_wrap_scroll (GtkWidget *widget, gboolean top)
{
	ygutils_scrollAdj (GTK_LAYOUT (widget)->vadjustment, top);
}
示例#10
0
void init_stuff (int argc, char *argv[])
{
  GtkWidget *w;
  GList *dev_list;
  GdkDevice *device;
  GdkScreen *screen;
  int i, j;
  struct Brush *b;
  gboolean can_xinput, success;
  gchar *tmppath, *tmpfn;

  // create some data structures needed to populate the preferences
  ui.default_page.bg = g_new(struct Background, 1);

  // initialize config file names
  tmppath = g_build_filename(g_get_home_dir(), CONFIG_DIR, NULL);
  mkdir(tmppath, 0700); // safer (MRU data may be confidential)
  ui.mrufile = g_build_filename(tmppath, MRU_FILE, NULL);
  ui.configfile = g_build_filename(tmppath, CONFIG_FILE, NULL);
  g_free(tmppath);

  // initialize preferences
  init_config_default();
  load_config_from_file();
  ui.font_name = g_strdup(ui.default_font_name);
  ui.font_size = ui.default_font_size;
  ui.hiliter_alpha_mask = 0xffffff00 + (guint)(255*ui.hiliter_opacity);

  // we need an empty canvas prior to creating the journal structures
  canvas = GNOME_CANVAS (gnome_canvas_new_aa ());

  // initialize data
  ui.default_page.bg->canvas_item = NULL;
  ui.layerbox_length = 0;

  if (argc > 2 || (argc == 2 && argv[1][0] == '-')) {
    printf(_("Invalid command line parameters.\n"
           "Usage: %s [filename.xoj]\n"), argv[0]);
    gtk_exit(0);
  }
   
  undo = NULL; redo = NULL;
  journal.pages = NULL;
  bgpdf.status = STATUS_NOT_INIT;

  new_journal();  
  
  ui.cur_item_type = ITEM_NONE;
  ui.cur_item = NULL;
  ui.cur_path.coords = NULL;
  ui.cur_path_storage_alloc = 0;
  ui.cur_path.ref_count = 1;
  ui.cur_widths = NULL;
  ui.cur_widths_storage_alloc = 0;

  ui.selection = NULL;
  ui.cursor = NULL;
  ui.pen_cursor_pix = ui.hiliter_cursor_pix = NULL;

  ui.cur_brush = &(ui.brushes[0][ui.toolno[0]]);
  for (j=0; j<=NUM_BUTTONS; j++)
    for (i=0; i < NUM_STROKE_TOOLS; i++) {
      b = &(ui.brushes[j][i]);
      b->tool_type = i;
      if (b->color_no>=0) {
        b->color_rgba = predef_colors_rgba[b->color_no];
        if (i == TOOL_HIGHLIGHTER) {
          b->color_rgba &= ui.hiliter_alpha_mask;
        }
      }
      b->thickness = predef_thickness[i][b->thickness_no];
    }
  for (i=0; i<NUM_STROKE_TOOLS; i++)
    g_memmove(ui.default_brushes+i, &(ui.brushes[0][i]), sizeof(struct Brush));

  ui.cur_mapping = 0;
  ui.which_unswitch_button = 0;
  ui.in_proximity = FALSE;
  ui.warned_generate_fontconfig = FALSE;
  
  reset_recognizer();

  // initialize various interface elements
  
  gtk_window_set_default_size(GTK_WINDOW (winMain), ui.window_default_width, ui.window_default_height);
  if (ui.maximize_at_start) gtk_window_maximize(GTK_WINDOW (winMain));
  update_toolbar_and_menu();
  update_font_button();

  gtk_check_menu_item_set_active(
    GTK_CHECK_MENU_ITEM(GET_COMPONENT("journalApplyAllPages")), ui.bg_apply_all_pages);
  gtk_check_menu_item_set_active(
    GTK_CHECK_MENU_ITEM(GET_COMPONENT("journalNewPageKeepsBG")), ui.new_page_bg_from_pdf);
  if (ui.fullscreen) {
    gtk_check_menu_item_set_active(
      GTK_CHECK_MENU_ITEM(GET_COMPONENT("viewFullscreen")), TRUE);
    gtk_toggle_tool_button_set_active(
      GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonFullscreen")), TRUE);
    gtk_window_fullscreen(GTK_WINDOW(winMain));
  }
  gtk_button_set_relief(GTK_BUTTON(GET_COMPONENT("buttonColorChooser")), GTK_RELIEF_NONE);

  allow_all_accels();
  add_scroll_bindings();

  // prevent interface items from stealing focus
  // glade doesn't properly handle can_focus, so manually set it
  gtk_combo_box_set_focus_on_click(GTK_COMBO_BOX(GET_COMPONENT("comboLayer")), FALSE);
  g_signal_connect(GET_COMPONENT("spinPageNo"), "activate",
          G_CALLBACK(handle_activate_signal), NULL);
  gtk_container_forall(GTK_CONTAINER(winMain), unset_flags, (gpointer)GTK_CAN_FOCUS);
  GTK_WIDGET_SET_FLAGS(GTK_WIDGET(canvas), GTK_CAN_FOCUS);
  GTK_WIDGET_SET_FLAGS(GTK_WIDGET(GET_COMPONENT("spinPageNo")), GTK_CAN_FOCUS);
  
  // install hooks on button/key/activation events to make the spinPageNo lose focus
  gtk_container_forall(GTK_CONTAINER(winMain), install_focus_hooks, NULL);

  // set up and initialize the canvas

  gtk_widget_show (GTK_WIDGET (canvas));
  w = GET_COMPONENT("scrolledwindowMain");
  gtk_container_add (GTK_CONTAINER (w), GTK_WIDGET (canvas));
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (w), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_widget_set_events (GTK_WIDGET (canvas), 
     GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | 
     GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | 
     GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
     GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK);
  gnome_canvas_set_pixels_per_unit (canvas, ui.zoom);
  gnome_canvas_set_center_scroll_region (canvas, TRUE);
  gtk_layout_get_hadjustment(GTK_LAYOUT (canvas))->step_increment = ui.scrollbar_step_increment;
  gtk_layout_get_vadjustment(GTK_LAYOUT (canvas))->step_increment = ui.scrollbar_step_increment;

  // set up the page size and canvas size
  update_page_stuff();

  g_signal_connect ((gpointer) canvas, "button_press_event",
                    G_CALLBACK (on_canvas_button_press_event),
                    NULL);
  g_signal_connect ((gpointer) canvas, "button_release_event",
                    G_CALLBACK (on_canvas_button_release_event),
                    NULL);
  g_signal_connect ((gpointer) canvas, "enter_notify_event",
                    G_CALLBACK (on_canvas_enter_notify_event),
                    NULL);
  g_signal_connect ((gpointer) canvas, "leave_notify_event",
                    G_CALLBACK (on_canvas_leave_notify_event),
                    NULL);
  g_signal_connect ((gpointer) canvas, "proximity_in_event",
                    G_CALLBACK (on_canvas_proximity_event),
                    NULL);
  g_signal_connect ((gpointer) canvas, "proximity_out_event",
                    G_CALLBACK (on_canvas_proximity_event),
                    NULL);
  g_signal_connect ((gpointer) canvas, "expose_event",
                    G_CALLBACK (on_canvas_expose_event),
                    NULL);
  g_signal_connect ((gpointer) canvas, "key_press_event",
                    G_CALLBACK (on_canvas_key_press_event),
                    NULL);
  g_signal_connect ((gpointer) canvas, "motion_notify_event",
                    G_CALLBACK (on_canvas_motion_notify_event),
                    NULL);
  g_signal_connect ((gpointer) gtk_layout_get_vadjustment(GTK_LAYOUT(canvas)),
                    "value-changed", G_CALLBACK (on_vscroll_changed),
                    NULL);
  g_signal_connect ((gpointer) gtk_layout_get_hadjustment(GTK_LAYOUT(canvas)),
                    "value-changed", G_CALLBACK (on_hscroll_changed),
                    NULL);
  g_object_set_data (G_OBJECT (winMain), "canvas", canvas);

  screen = gtk_widget_get_screen(winMain);
  ui.screen_width = gdk_screen_get_width(screen);
  ui.screen_height = gdk_screen_get_height(screen);
  
  can_xinput = FALSE;
  dev_list = gdk_devices_list();
  while (dev_list != NULL) {
    device = (GdkDevice *)dev_list->data;
    if (device != gdk_device_get_core_pointer() && device->num_axes >= 2) {
      /* get around a GDK bug: map the valuator range CORRECTLY to [0,1] */
#ifdef ENABLE_XINPUT_BUGFIX
      gdk_device_set_axis_use(device, 0, GDK_AXIS_IGNORE);
      gdk_device_set_axis_use(device, 1, GDK_AXIS_IGNORE);
#endif
      gdk_device_set_mode(device, GDK_MODE_SCREEN);
      if (g_strrstr(device->name, "raser"))
        gdk_device_set_source(device, GDK_SOURCE_ERASER);
      can_xinput = TRUE;
    }
    dev_list = dev_list->next;
  }
  if (!can_xinput)
    gtk_widget_set_sensitive(GET_COMPONENT("optionsUseXInput"), FALSE);

  ui.use_xinput = ui.allow_xinput && can_xinput;

  gtk_check_menu_item_set_active(
    GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsProgressiveBG")), ui.progressive_bg);
  gtk_check_menu_item_set_active(
    GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsPrintRuling")), ui.print_ruling);
  gtk_check_menu_item_set_active(
    GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsAutoloadPdfXoj")), ui.autoload_pdf_xoj);
  gtk_check_menu_item_set_active(
    GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsAutosaveXoj")), ui.autosave_enabled);
  gtk_check_menu_item_set_active(
    GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsLeftHanded")), ui.left_handed);
  gtk_check_menu_item_set_active(
    GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsShortenMenus")), ui.shorten_menus);
  gtk_check_menu_item_set_active(
    GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsAutoSavePrefs")), ui.auto_save_prefs);
  gtk_check_menu_item_set_active(
    GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsButtonSwitchMapping")), ui.button_switch_mapping);
  gtk_check_menu_item_set_active
    (GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsLargePenCursor")), ui.large_pencursor);
  gtk_check_menu_item_set_active(
    GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsPenCursor")), ui.pen_cursor);
  
  hide_unimplemented();

  update_undo_redo_enabled();
  update_copy_paste_enabled();
  update_vbox_order(ui.vertical_order[ui.fullscreen?1:0]);
  gtk_widget_grab_focus(GTK_WIDGET(canvas));

  // show everything...
  
  gtk_widget_show (winMain);
  update_cursor();

  /* this will cause extension events to get enabled/disabled, but
     we need the windows to be mapped first */
  gtk_check_menu_item_set_active(
    GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsUseXInput")), ui.use_xinput);

  /* fix a bug in GTK+ 2.16 and 2.17: scrollbars shouldn't get extended
     input events from pointer motion when cursor moves into main window */

  if (!gtk_check_version(2, 16, 0)) {
    g_signal_connect (
      GET_COMPONENT("menubar"),
      "event", G_CALLBACK (filter_extended_events),
      NULL);
    g_signal_connect (
      GET_COMPONENT("toolbarMain"),
      "event", G_CALLBACK (filter_extended_events),
      NULL);
    g_signal_connect (
      GET_COMPONENT("toolbarPen"),
      "event", G_CALLBACK (filter_extended_events),
      NULL);
    g_signal_connect (
      GET_COMPONENT("statusbar"),
      "event", G_CALLBACK (filter_extended_events),
      NULL);
    g_signal_connect (
      (gpointer)(gtk_scrolled_window_get_vscrollbar(GTK_SCROLLED_WINDOW(w))),
      "event", G_CALLBACK (filter_extended_events),
      NULL);
    g_signal_connect (
      (gpointer)(gtk_scrolled_window_get_hscrollbar(GTK_SCROLLED_WINDOW(w))),
      "event", G_CALLBACK (filter_extended_events),
      NULL);
  }

  // load the MRU
  
  init_mru();

  // and finally, open a file specified on the command line
  // (moved here because display parameters weren't initialized yet...)
  
  if (argc == 1) return;
  set_cursor_busy(TRUE);
  if (g_path_is_absolute(argv[1]))
    tmpfn = g_strdup(argv[1]);
  else {
    tmppath = g_get_current_dir();
    tmpfn = g_build_filename(tmppath, argv[1], NULL);
    g_free(tmppath);
  }
  success = open_journal(tmpfn);
  g_free(tmpfn);
  set_cursor_busy(FALSE);
  if (!success) {
    w = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
       GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), argv[1]);
    gtk_dialog_run(GTK_DIALOG(w));
    gtk_widget_destroy(w);
  }
}
示例#11
0
void FloatingWindow::rectangle_set (const GdkRectangle& rectangle)
{
  my_gdk_rectangle = rectangle;
  gtk_layout_move (GTK_LAYOUT (layout), vbox_window, my_gdk_rectangle.x, my_gdk_rectangle.y);
  gtk_widget_set_size_request (vbox_window, my_gdk_rectangle.width, my_gdk_rectangle.height); 
}
示例#12
0
void FloatingWindow::display(bool startup)
// Does the bookkeeping necessary for displaying the floating box.
// startup: whether the box is started at program startup.
{
  // Settings.
  extern Settings *settings;

  // The parameters of all the windows.
  WindowData window_parameters(false);

  // Clear the new window's position.
  my_gdk_rectangle.x = 0;
  my_gdk_rectangle.y = 0;
  my_gdk_rectangle.width = 0;
  my_gdk_rectangle.height = 0;

  // At program startup extract the position and size of the window from the general configuration.
  // It does not matter whether the space for the window is already taken up by another window,
  // because the user wishes to use the coordinates that he has set for this window.
  for (unsigned int i = 0; i < window_parameters.widths.size(); i++) {
    if ((window_parameters.ids[i] == window_id) && (window_parameters.titles[i] == title) && startup) {
      my_gdk_rectangle.x = window_parameters.x_positions[i];
      my_gdk_rectangle.y = window_parameters.y_positions[i];
      my_gdk_rectangle.width = window_parameters.widths[i];
      my_gdk_rectangle.height = window_parameters.heights[i];
    }
  }

  // Reject zero width and zero height values on startup.
  if ((my_gdk_rectangle.width == 0) || (my_gdk_rectangle.height == 0))
    startup = false;

  // When a new window needs to be allocated, there are a few steps to be taken.
  if (!startup) {

    // Step 1: The area rectangle where the window should fit in is defined. 
    GdkRectangle area_rectangle;
    area_rectangle.x = 0;
    area_rectangle.y = 0;
    area_rectangle.width = 0;
    area_rectangle.height = 0;
    {
      guint width, height;
      gtk_layout_get_size (GTK_LAYOUT (layout), &width, &height);
      area_rectangle.width = width;
      area_rectangle.height = height;
    }

    // Step 2: An available region is made of that whole area.
    GdkRegion *available_region = gdk_region_rectangle(&area_rectangle);

    // Step 3: The regions of each of the open windows is substracted from the available region.
    for (unsigned int i = 0; i < settings->session.open_floating_windows.size(); i++) {
      FloatingWindow * floating_window = (FloatingWindow *) settings->session.open_floating_windows[i];
      GdkRectangle rectangle = floating_window->rectangle_get();
      GdkRegion *region = gdk_region_rectangle(&rectangle);
      gdk_region_subtract(available_region, region);
      gdk_region_destroy(region);
    }

    // Step 4: The rectangles that the area region consists of are requested,
    // and the biggest suitable rectangle is chosen for the window.
    // A rectangle is considered suitable if it has at least 10% of the width, and 10% of the height of the area rectangle.
    GdkRectangle *gdk_rectangles = NULL;
    gint rectangle_count = 0;
    gdk_region_get_rectangles(available_region, &gdk_rectangles, &rectangle_count);
    for (int i = 0; i < rectangle_count; ++i) {
      GdkRectangle & rectangle = gdk_rectangles[i];
      if (rectangle.width >= (area_rectangle.width / 10)) {
        if (rectangle.height >= (area_rectangle.height / 10)) {
          if ((rectangle.width * rectangle.height) > (my_gdk_rectangle.width * my_gdk_rectangle.height)) {
            my_gdk_rectangle = rectangle;
          }
        }
      }
    }
    g_free(gdk_rectangles);

    // Step 5: The available region is destroyed.
    gdk_region_destroy(available_region);

    // Step 6: If no area big enough is found, then the window that takes most space in the area is chosen, 
    // the longest side is halved, and the new window is put in that freed area.
    if ((my_gdk_rectangle.width == 0) || (my_gdk_rectangle.height == 0)) {
      FloatingWindow * resize_window_pointer = NULL;
      int largest_size = 0;
      for (unsigned int i = 0; i < settings->session.open_floating_windows.size(); i++) {
        FloatingWindow *floating_window = (FloatingWindow *) settings->session.open_floating_windows[i];
        GdkRectangle rectangle = floating_window->rectangle_get ();
        int size = rectangle.width * rectangle.height;
        if (size > largest_size) {
          resize_window_pointer = floating_window;
          largest_size = size;
        }
      }
      if (resize_window_pointer) {
        GdkRectangle resize_window_rectangle = resize_window_pointer->rectangle_get();
        my_gdk_rectangle = resize_window_pointer->rectangle_get();
        if (resize_window_rectangle.width > resize_window_rectangle.height) {
          resize_window_rectangle.width /= 2;
          my_gdk_rectangle.width /= 2;
          my_gdk_rectangle.x += resize_window_rectangle.width;
        } else {
          resize_window_rectangle.height /= 2;
          my_gdk_rectangle.height /= 2;
          my_gdk_rectangle.y += resize_window_rectangle.height;
        }
        resize_window_pointer->rectangle_set (resize_window_rectangle);
      }
    }
  }
  // Add the window to the layout and set its position and size.
  gtk_layout_put (GTK_LAYOUT (layout), vbox_window, my_gdk_rectangle.x, my_gdk_rectangle.y);
  rectangle_set (my_gdk_rectangle);
  // Store a pointer to this window in the Session.
  settings->session.open_floating_windows.push_back(gpointer (this));
}
示例#13
0
static void
create_layout (GtkWidget *vbox)
{
  GtkAdjustment *hadjustment, *vadjustment;
  GtkLayout *layout;
  GtkWidget *layout_widget;
  GtkWidget *scrolledwindow;
  GtkWidget *button;
  gchar buf[16];
  gint i, j;

  scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
				       GTK_SHADOW_IN);
  gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolledwindow),
				     GTK_CORNER_TOP_RIGHT);

  gtk_box_pack_start (GTK_BOX (vbox), scrolledwindow, TRUE, TRUE, 0);

  layout_widget = gtk_layout_new (NULL, NULL);
  layout = GTK_LAYOUT (layout_widget);
  gtk_container_add (GTK_CONTAINER (scrolledwindow), layout_widget);

  /* We set step sizes here since GtkLayout does not set
   * them itself.
   */
  hadjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout));
  vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (layout));
  gtk_adjustment_set_step_increment (hadjustment, 10.0);
  gtk_adjustment_set_step_increment (vadjustment, 10.0);
  gtk_scrollable_set_hadjustment (GTK_SCROLLABLE (layout), hadjustment);
  gtk_scrollable_set_vadjustment (GTK_SCROLLABLE (layout), vadjustment);

  gtk_widget_set_events (layout_widget, GDK_EXPOSURE_MASK);
  g_signal_connect (layout, "draw",
		    G_CALLBACK (layout_draw_handler),
                    NULL);

  gtk_layout_set_size (layout, 1600, 128000);

  for (i = 0 ; i < 16 ; i++)
    for (j = 0 ; j < 16 ; j++)
      {
	g_snprintf (buf, sizeof (buf), "Button %d, %d", i, j);

	if ((i + j) % 2)
	  button = gtk_button_new_with_label (buf);
	else
	  button = gtk_label_new (buf);

	gtk_layout_put (layout, button,	j * 100, i * 100);
      }

  for (i = 16; i < 1280; i++)
    {
      g_snprintf (buf, sizeof (buf), "Button %d, %d", i, 0);

      if (i % 2)
	button = gtk_button_new_with_label (buf);
      else
	button = gtk_label_new (buf);

      gtk_layout_put (layout, button, 0, i * 100);
    }

  layout_timeout = g_timeout_add (1000, scroll_layout, layout);
}
示例#14
0
/* Draw the exon view */
static void drawExonView(GtkWidget *exonView, GdkDrawable *drawable)
{
    GtkWidget *blxWindow = exonViewGetBlxWindow(exonView);
    BlxViewContext *bc = blxWindowGetContext(blxWindow);

    ExonViewProperties *properties = exonViewGetProperties(exonView);
    const IntRange* const displayRange = bigPictureGetDisplayRange(properties->bigPicture);

    /* First, highlight any assembly gaps */
    /* Get the display range in dna coords */
    IntRange bpRange;
    convertDisplayRangeToDnaRange(displayRange, bc->seqType, bc->numFrames, bc->displayRev, &bc->refSeqRange, &bpRange);

    GdkColor *gapColor = getGdkColor(BLXCOLOR_ASSEMBLY_GAP, bc->defaultColors, FALSE, bc->usePrintColors);
    drawAssemblyGaps(exonView, drawable, gapColor, bc->displayRev, &properties->exonViewRect, &bpRange, bc->featureLists[BLXMSP_GAP]);

    /* Set a clip rectangle for drawing the exons and introns (because they are drawn "over the
     * edges" to make sure intron lines have the correct slope etc.) */
    GdkGC *gc = gdk_gc_new(drawable);

    gdk_gc_set_clip_origin(gc, 0, 0);
    gdk_gc_set_clip_rectangle(gc, &properties->exonViewRect);

    /* Draw the exons and introns. Since we could have a lot of them in the loop, extract all the
     * info we need now and pass it around so we don't have to look for this stuff each time. */

    DrawData drawData = {
        drawable,
        gc,
        &properties->exonViewRect,
        blxWindow,
        bc,
        properties->currentStrand,
        displayRange,
        &bc->refSeqRange,
        bc->displayRev,
        bc->numFrames,
        bc->seqType,
        properties->expanded,
        FALSE,
        properties->yPad,
        properties->exonViewRect.y,
        properties->exonHeight
    };

    /* If the view is compressed (i.e. exons will overlap each other), then
     * only draw "normal" MSPs the first time round, and draw grouped/selected
     * MSPs afterwards, so that they appear on top. If the view is expanded,
     * we can draw them all in a single loop, because they will not overlap. */
    drawData.normalOnly = !properties->expanded;

    /* Loop through all sequences, drawing all msps that are exons/introns */
    GList *seqList = blxWindowGetAllMatchSeqs(blxWindow);
    g_list_foreach(seqList, drawExonIntronItem, &drawData);

    if (!properties->expanded)
    {
        drawData.normalOnly = FALSE;

        /* Draw all selected msps */
        g_list_foreach(bc->selectedSeqs, drawExonIntronItem, &drawData);

        /* Increment the y value when finished, because we calculate the view height based on this */
        drawData.y += drawData.height + drawData.yPad;
    }

    /* Set the height based on the height of the exons that were actually drawn */
    const int newHeight = drawData.y - properties->exonViewRect.y + drawData.yPad;
    gtk_layout_set_size(GTK_LAYOUT(exonView), exonView->allocation.width, newHeight);

    g_object_unref(gc);
}
示例#15
0
/* Callback for keypresses */
gboolean
key_press(GtkWidget * widget, GdkEventKey * event, gpointer data)
{
    AppUIData *app_ui_data;
    GtkAdjustment *adj = NULL;
    GtkWidget *w = NULL;

    app_ui_data = (AppUIData *) data;
    app_ui_data->key_pressed = event->keyval;
    
    switch (event->keyval)
    {
        /* F6 (or SELECT when file open) = toggle full screen mode */
        case GDK_KP_Enter:
        case GDK_Return:      
			if( !PDF_FLAGS_IS_SET(app_ui_data->flags,
				PDF_FLAGS_SELECT_KEY_ALLOWED ) ||
				pdf_viewer_get_num_pages() == 0 ) {
							
				break;
			}
			PDF_FLAGS_UNSET(app_ui_data->flags, PDF_FLAGS_SELECT_KEY_ALLOWED);			
        case GDK_F6:
            ui_toggle_fullscreen(app_ui_data,
	            !PDF_FLAGS_IS_SET(app_ui_data->flags, PDF_FLAGS_FULLSCREEN));
            return TRUE;
        case GDK_F4:           // we only return for menu key
        	return FALSE;
		case GDK_Escape:
            return FALSE;
    }

    if( key_press_disabled(app_ui_data, event) ) {
        return TRUE;
    }

    switch (event->keyval)
    {

		/* scrolling UP or LEFT is almost the same, just different
         * GtkAdjustments */
        /* UP = scroll up 20% */
        case GDK_KP_Up:
        case GDK_Up:
	    ui_hide_overlay_image(app_ui_data, app_ui_data->ovr_image_orig);//prasanna
            adj = gtk_layout_get_vadjustment(GTK_LAYOUT(app_ui_data->layout));

            /* LEFT = scroll left 20% */
        case GDK_KP_Left:
        case GDK_Left:
            
	    ui_hide_overlay_image(app_ui_data, app_ui_data->ovr_image_orig);//prasanna
            if (!adj) {

				/* Ignore when no document loaded */
				if( app_ui_data->app_data->state == PDF_VIEWER_STATE_EMPTY ) {
					/*ui_show_banner(GTK_WIDGET(app_ui_data->app_view),
						_("pdfv_ib_menu_not_available") );*/
            		return TRUE;
            	}

                adj = gtk_layout_get_hadjustment(
                	GTK_LAYOUT(app_ui_data->layout));
            }

            /* If scroll is far left/top or page fits to screen then try to
               move to previous page */
            if ( adj->upper <= adj->page_size || adj->value == 0.0 ) {
            	w = gtk_ui_manager_get_widget(app_ui_data->ui_manager,
					"/ToolBar/pdfv_me_menu_page_previous");

				if ((w != NULL) && (GTK_WIDGET_IS_SENSITIVE(w))) {
					on_page_previous(NULL, data);
					adj = gtk_layout_get_vadjustment(GTK_LAYOUT          (app_ui_data->layout));	
					gtk_adjustment_set_value(adj,adj->value + adj->upper - adj->page_size -0.0001);
				} else {
					if (pdf_viewer_get_current_page() == 1) {
                            ui_show_banner(GTK_WIDGET(app_ui_data->app_view),
                                           _("pdfv_ib_first_page_reached"));
                    }
                }

                return TRUE;
            }            
            
            /* scroll the page by 20% */            
            if (adj->lower <= adj->value - 0.2 * adj->page_size)
                gtk_adjustment_set_value(adj,
                                         adj->value - 0.2 * adj->page_size);
            else
                gtk_adjustment_set_value(adj, adj->lower);

            return TRUE;

            /* scrolling DOWN or RIGHT is almost the same, just different
             * GtkAdjustments */
            /* DOWN = scroll down 20% */
        case GDK_KP_Down:
	case GDK_Down:
	    ui_hide_overlay_image(app_ui_data, app_ui_data->ovr_image_orig);//prasanna
            adj = gtk_layout_get_vadjustment(GTK_LAYOUT(app_ui_data->layout));

            /* RIGHT = scroll to the right 20% */
        case GDK_KP_Right:
        case GDK_Right:
	    ui_hide_overlay_image(app_ui_data, app_ui_data->ovr_image_orig);//prasanna
			if( !adj ) {
	            adj = gtk_layout_get_hadjustment(GTK_LAYOUT(app_ui_data->layout));

				/* Ignore when no document loaded */
				if( app_ui_data->app_data->state == PDF_VIEWER_STATE_EMPTY ) {
					/*ui_show_banner(GTK_WIDGET(app_ui_data->app_view),
						_("pdfv_ib_menu_not_available") );*/
	           		return TRUE;
	           	}
	           	
	        }
            
	        if( adj->page_size < adj->upper &&
	           	adj->value < ( adj->upper - adj->page_size ) ) {
		           
				/* scroll the page by 20% */
	    	    if (adj->value + adj->page_size * 0.2 <=
	    	    	adj->upper - adj->page_size)
						gtk_adjustment_set_value(adj,
							adj->value + adj->page_size * 0.2);
	    	    else
					gtk_adjustment_set_value(adj, adj->upper - adj->page_size);
	    	    
			/* Move more space to move, to next page */             
			} else {
	           	on_page_next(NULL, data);
			}

            return TRUE;

	case GDK_KP_Space: 
        case GDK_space: 
                ui_hide_overlay_image(app_ui_data, app_ui_data->ovr_image_orig);
                adj = gtk_layout_get_vadjustment(GTK_LAYOUT(app_ui_data->layout));

		if (event->state & GDK_SHIFT_MASK) {
	            /* scroll the page up by one screen-height, when Shift+Spacebar is pressed*/		
                    if (adj->lower <= adj->value - adj->page_size)
                        gtk_adjustment_set_value(adj, adj->value - adj->page_size);
	            else
	                 gtk_adjustment_set_value(adj, adj->lower);
                 }
		else
		 {
	            /* scroll the page down by one screen-height, when Spacebar is pressed*/		
		    if( adj->page_size < adj->upper && 
				    adj->value < ( adj->upper - adj->page_size ) ) {
                	if (adj->value + adj->page_size <= adj->upper - adj->page_size)
                            gtk_adjustment_set_value(adj, adj->value + adj->page_size);
			else
		            gtk_adjustment_set_value(adj, adj->upper - adj->page_size);
	            }
	         }
	
		return TRUE;
				      
            /* display infoprint when maximum or minimum zoom level has been
             * reached. See Bugzilla 18393 */

        /* F8 = zoom out */
        case GDK_F8:
	        w = gtk_ui_manager_get_widget(app_ui_data->ui_manager,
				"/ToolBar/pdfv_me_menu_screen_zoom_out");
			if ((w != NULL) && (GTK_WIDGET_IS_SENSITIVE(w))) {
				pdf_viewer_zoom(DOC_ZOOM_OUT);
			} else if (pdf_viewer_get_zoom_percent() <= 50) {
				ui_show_banner(GTK_WIDGET(app_ui_data->app_view),
					_("pdfv_ib_minimum_zoom"));
			}
			return TRUE;

        /* F7 = zoom in */
        case GDK_F7:
	        w = gtk_ui_manager_get_widget(app_ui_data->ui_manager,
 	           "/ToolBar/pdfv_me_menu_screen_zoom_in");
            if ((w != NULL) && (GTK_WIDGET_IS_SENSITIVE(w))) {
				pdf_viewer_zoom(DOC_ZOOM_IN);
			} else if (pdf_viewer_get_zoom_percent() >= 400) {
	            ui_show_banner(GTK_WIDGET(app_ui_data->app_view),
	                _("pdfv_ib_maximum_zoom"));
			}
			return TRUE;

            /* 
             * RETURN/SELECT = if no document present Open file dialog else
             * full screen mode 
        case GDK_KP_Enter:
        case GDK_Return:
	        if( !PDF_FLAGS_IS_SET(app_ui_data->flags,
	        	PDF_FLAGS_SELECT_KEY_ALLOWED ) ) {
	        	break;
	        }
            PDF_FLAGS_UNSET(app_ui_data->flags, PDF_FLAGS_SELECT_KEY_ALLOWED);
            
            if( (pdf_viewer_get_num_pages() != 0) ||
                !(GTK_WIDGET_IS_SENSITIVE( gtk_ui_manager_get_widget
                  (app_ui_data->ui_manager,
                  	"/MenuBar/pdfv_me_main_menu_document/"
                  	"pdfv_me_menu_document_open")))) {

                ui_toggle_fullscreen(app_ui_data,
                	!PDF_FLAGS_IS_SET( app_ui_data->flags,
						PDF_FLAGS_FULLSCREEN));
                  	
            }
            
            return TRUE;
			*/

        default:
            break;
    }

    return FALSE;
}
C4Window* C4Window::Init(WindowKind windowKind, C4AbstractApp * pApp, const char * Title, const C4Rect * size)
{
	Active = true;
#ifdef GDK_WINDOWING_X11
	if(!FindFBConfig(Config.Graphics.MultiSampling, &Info))
	{
		// Disable multisampling if we don't find a visual which
		// supports the currently configured setting.
		if(!FindFBConfig(0, &Info)) return NULL;
		Config.Graphics.MultiSampling = 0;
	}
#endif

	assert(!window);

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	if (windowKind == W_Viewport)
	{
		C4ViewportWindow * vw = static_cast<C4ViewportWindow *>(this);

		// Cannot just use ScrolledWindow because this would just move
		// the GdkWindow of the DrawingArea.
		GtkWidget* table = gtk_grid_new();
		render_widget = gtk_drawing_area_new();
		gtk_widget_set_hexpand(GTK_WIDGET(render_widget), true);
		gtk_widget_set_vexpand(GTK_WIDGET(render_widget), true);
		gtk_grid_attach(GTK_GRID(table), GTK_WIDGET(render_widget), 0, 0, 1, 1);
		vw->h_scrollbar = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, NULL);
		gtk_grid_attach(GTK_GRID(table), vw->h_scrollbar, 0, 1, 1, 1);
		vw->v_scrollbar = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, NULL);
		gtk_grid_attach(GTK_GRID(table), vw->v_scrollbar, 1, 0, 1, 1);

		GtkAdjustment* adjustment = gtk_range_get_adjustment(GTK_RANGE(vw->h_scrollbar));

		g_signal_connect(
		  G_OBJECT(adjustment),
		  "value-changed",
		  G_CALLBACK(OnHScrollStatic),
		  this
		);

		adjustment = gtk_range_get_adjustment(GTK_RANGE(vw->v_scrollbar));

		g_signal_connect(
		  G_OBJECT(adjustment),
		  "value-changed",
		  G_CALLBACK(OnVScrollStatic),
		  this
		);

		gtk_container_add(GTK_CONTAINER(window), table);

		gtk_widget_add_events(GTK_WIDGET(window), GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK | GDK_POINTER_MOTION_MASK);

		gtk_drag_dest_set(GTK_WIDGET(render_widget), GTK_DEST_DEFAULT_ALL, drag_drop_entries, 1, GDK_ACTION_COPY);
		g_signal_connect(G_OBJECT(render_widget), "drag-data-received", G_CALLBACK(OnDragDataReceivedStatic), this);
		g_signal_connect(G_OBJECT(render_widget), "draw", G_CALLBACK(OnExposeStatic), this);
		g_signal_connect(G_OBJECT(window), "key-press-event", G_CALLBACK(OnKeyPressStatic), this);
		g_signal_connect(G_OBJECT(window), "key-release-event", G_CALLBACK(OnKeyReleaseStatic), this);
		g_signal_connect(G_OBJECT(window), "scroll-event", G_CALLBACK(OnScrollVW), this);
		g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(OnButtonPressStatic), this);
		g_signal_connect(G_OBJECT(window), "button-release-event", G_CALLBACK(OnButtonReleaseStatic), this);
		g_signal_connect(G_OBJECT(window), "motion-notify-event", G_CALLBACK(OnMotionNotifyStatic), this);
		g_signal_connect(G_OBJECT(window), "key-press-event", G_CALLBACK(OnKeyPress), this);
		g_signal_connect(G_OBJECT(window), "key-release-event", G_CALLBACK(OnKeyRelease), this);
		g_signal_connect(G_OBJECT(window), "configure-event", G_CALLBACK(OnConfigureStatic), this);
		g_signal_connect(G_OBJECT(window), "realize", G_CALLBACK(OnRealizeStatic), this);

		g_signal_connect_after(G_OBJECT(render_widget), "configure-event", G_CALLBACK(OnConfigureDareaStatic), this);

#if !GTK_CHECK_VERSION(3,10,0)
		// do not draw the default background
		gtk_widget_set_double_buffered (GTK_WIDGET(render_widget), false);
#endif

		gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(Console.window));
#if !GTK_CHECK_VERSION(3,14,0)
		gtk_window_set_has_resize_grip(GTK_WINDOW(window), false);
#endif
	}
	else if (windowKind == W_Fullscreen)
	{
		render_widget = gtk_drawing_area_new();
		gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(render_widget));

		g_signal_connect(G_OBJECT(window), "configure-event", G_CALLBACK(OnConfigureNotify), this);
		g_signal_connect(G_OBJECT(window), "focus-in-event", G_CALLBACK(OnFocusInFS), this);
		g_signal_connect(G_OBJECT(window), "focus-out-event", G_CALLBACK(OnFocusOutFS), this);
		g_signal_connect(G_OBJECT(window), "unmap-event", G_CALLBACK(OnFocusOutFS), this);
		g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(OnButtonPressFS), this);
		g_signal_connect(G_OBJECT(window), "button-release-event", G_CALLBACK(OnButtonRelease), this);
		g_signal_connect(G_OBJECT(window), "motion-notify-event", G_CALLBACK(OnMotionNotify), this);
		g_signal_connect(G_OBJECT(window), "key-press-event", G_CALLBACK(OnKeyPress), this);
		g_signal_connect(G_OBJECT(window), "key-release-event", G_CALLBACK(OnKeyRelease), this);
		g_signal_connect(G_OBJECT(window), "scroll-event", G_CALLBACK(OnScroll), this);
		gtk_widget_add_events(GTK_WIDGET(window), GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
#if !GTK_CHECK_VERSION(3,10,0)
		gtk_widget_set_double_buffered (GTK_WIDGET(render_widget), false);
#endif

		GValue val = {0,{{0}}};
		g_value_init (&val, G_TYPE_BOOLEAN);
		g_value_set_boolean (&val, true);
		g_object_set_property (G_OBJECT (render_widget), "can-focus", &val);
		g_object_set_property (G_OBJECT (window), "can-focus", &val);
		g_value_unset (&val);
#if !GTK_CHECK_VERSION(3,14,0)
		gtk_window_set_has_resize_grip(GTK_WINDOW(window), false);
#endif
	}
	else if (windowKind == W_GuiWindow)
	{
		render_widget = window;
		g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(OnButtonPressGD), this);
		g_signal_connect(G_OBJECT(window), "button-release-event", G_CALLBACK(OnButtonReleaseGD), this);
		g_signal_connect(G_OBJECT(window), "motion-notify-event", G_CALLBACK(OnMotionNotifyGD), this);
		g_signal_connect(G_OBJECT(window), "configure-event", G_CALLBACK(OnConfigureGD), this);
		g_signal_connect(G_OBJECT(window), "scroll-event", G_CALLBACK(OnScroll), this);

		gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(Console.window));
#if !GTK_CHECK_VERSION(3,14,0)
		gtk_window_set_has_resize_grip(GTK_WINDOW(window), false);
#endif
	}
	else if (windowKind == W_Console)
	{
		render_widget = window;
	}
	assert(window);
	assert(render_widget);
	// Override gtk's default to match name/class of the XLib windows
	gtk_window_set_wmclass(GTK_WINDOW(window), C4ENGINENAME, C4ENGINENAME);
	gtk_window_set_default_size(GTK_WINDOW(window), size->Wdt, size->Hgt);

	g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(OnDelete), this);
	handlerDestroy = g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(OnDestroyStatic), this);
	gtk_widget_add_events(GTK_WIDGET(window), GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_SCROLL_MASK);

	// TODO: It would be nice to support GDK_SCROLL_SMOOTH_MASK and
	// smooth scrolling for scrolling in menus, however that should not
	// change the scroll wheel behaviour ingame for zooming or
	// inventory change. Note that when both GDK_SCROLL_MASK and
	// GDK_SMOOTH_SCROLL_MASK are enabled, both type of scroll events
	// are reported, so one needs to make sure to not double-process them.
	// It would be nice to have smooth scrolling also e.g. for zooming
	// ingame, but it probably requires the notion of smooth scrolling
	// other parts of the engine as well.
#ifdef GDK_WINDOWING_X11
	GdkScreen * scr = gtk_widget_get_screen(GTK_WIDGET(render_widget));
	Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default());
	XVisualInfo *vis_info = glXGetVisualFromFBConfig(dpy, Info);
	assert(vis_info);
	GdkVisual * vis = gdk_x11_screen_lookup_visual(scr, vis_info->visualid);
	XFree(vis_info);
	gtk_widget_set_visual(GTK_WIDGET(render_widget),vis);
#endif
	gtk_widget_show_all(GTK_WIDGET(window));

//  XVisualInfo vitmpl; int blub;
//  vitmpl.visual = gdk_x11_visual_get_xvisual(gtk_widget_get_visual(window));
//  vitmpl.visualid = XVisualIDFromVisual(vitmpl.visual);
//  Info = XGetVisualInfo(dpy, VisualIDMask, &vitmpl, &blub);

//  printf("%p\n", gtk_widget_get_visual(render_widget));
//  Info = gdk_x11_visual_get_xvisual(gtk_widget_get_visual(render_widget));

	// Default icon has been set right after gtk_init(),
	// so we don't need to take care about setting the icon here.

	SetTitle(Title);

	// Wait until window is mapped to get the window's XID
	gtk_widget_show_now(GTK_WIDGET(window));
	GdkWindow* render_gdk_wnd;
	if (GTK_IS_LAYOUT(render_widget))
		render_gdk_wnd = gtk_layout_get_bin_window(GTK_LAYOUT(render_widget));
	else
		render_gdk_wnd = gtk_widget_get_window(GTK_WIDGET(render_widget));

#ifdef GDK_WINDOWING_X11
	renderwnd = GDK_WINDOW_XID(render_gdk_wnd);
#elif defined(GDK_WINDOWING_WIN32)
	renderwnd = reinterpret_cast<HWND>(gdk_win32_window_get_handle(render_gdk_wnd));
#endif
	// Make sure the window is shown and ready to be rendered into,
	// this avoids an async X error.
	gdk_flush();

	if (windowKind == W_Fullscreen)
		gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(render_widget)),
		                      gdk_cursor_new_for_display(gdk_display_get_default(), GDK_BLANK_CURSOR));
	return this;
}
示例#17
0
gboolean
on_screen_motion(GtkWidget * widget, GdkEventMotion * event,
                 gpointer user_data)
{
    AppUIData *app_ui_data = (AppUIData *) user_data;
    GtkAdjustment *adj;
    gdouble value;
    gint x, y;
    gint dx, dy;
    g_return_val_if_fail(app_ui_data != NULL, TRUE);

    /* ignore event if button is not pressed, or page is rendering */
    /* TODO could add test to ensure that document is loaded */
    if (!PDF_FLAGS_IS_SET(app_ui_data->flags, PDF_FLAGS_BUTTON_DOWN)
        || pdf_viewer_is_rendering() ) {
        return TRUE;
    }

    if (event->is_hint)
    {
        /* hint event, retrieve pointer location */
        gdk_window_get_pointer(event->window, &x, &y, NULL);
    }
    else
    {
        /* use motion event coordinates */
        x = (gint) event->x;
        y = (gint) event->y;
    }

    /* calculate delta values */
    dx = x - app_ui_data->lastx;
    dy = y - app_ui_data->lasty;

    if (!PDF_FLAGS_IS_SET(app_ui_data->flags, PDF_FLAGS_PANNING))
    {
        /* not panning yet, check if threshold exceeded */
        if (ABS(dx) > PANNING_THRESHOLD || ABS(dy) > PANNING_THRESHOLD)
        {
            /* start panning */
            PDF_FLAGS_SET(app_ui_data->flags, PDF_FLAGS_PANNING);

            /* don't move just yet */
            app_ui_data->lastx = x;
            app_ui_data->lasty = y;
        }
    }
    else
    {
        /* panning */

        /* retrieve and set vertical adjustment, ensure that range is not
         * exceeded */
        adj = gtk_layout_get_vadjustment(GTK_LAYOUT(app_ui_data->layout));
        value = adj->value - (gdouble) dy;
        if (value < adj->lower)
            value = adj->lower;
        else if (value > (adj->upper - adj->page_size))
            value = adj->upper - adj->page_size;
        gtk_adjustment_set_value(adj, value);

        /* retrieve and set horizontal adjustment */
        adj = gtk_layout_get_hadjustment(GTK_LAYOUT(app_ui_data->layout));
        value = adj->value - (gdouble) dx;
        if (value < adj->lower)
            value = adj->lower;
        else if (value > (adj->upper - adj->page_size))
            value = adj->upper - adj->page_size;
        gtk_adjustment_set_value(adj, value);

        /* NOTE on_screen_scroll handler is invoked automatically when
         * gtk_adjustment_set_value is called */
    }

    return FALSE;
}
示例#18
0
GtkWidget *
ghack_init_map_window()
{
    GtkWidget *vbox;
    GtkWidget *hbox;
    GtkWidget *table;
    GtkWidget *frame;
    GtkWidget *w;
    GtkWidget *hSeparator;
    GtkAdjustment *adj;
    GnomeCanvasImage *bg;
    double width, height, x, y;
    int i;

    width = COLNO * ghack_glyph_width();
    height = ROWNO * ghack_glyph_height();

    vbox = gtk_vbox_new(FALSE, 4);
    gtk_container_set_border_width(GTK_CONTAINER(vbox), 4);
    gtk_widget_show(vbox);

    /* Add in a horiz seperator */
    hSeparator = gtk_hseparator_new();
    gtk_box_pack_start(GTK_BOX(vbox), hSeparator, FALSE, FALSE, 2);
    gtk_widget_show(hSeparator);

    hbox = gtk_hbox_new(FALSE, 4);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
    gtk_widget_show(hbox);

    /* Create the Zoom spinbutton.
    */
    ghack_map.zoom = 1.0;
    w = gtk_label_new("Zoom:");
    gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 0);
    gtk_widget_show(w);
    adj =
        GTK_ADJUSTMENT(gtk_adjustment_new(1.00, 0.5, 3.00, 0.05, 0.50, 0.50));
    w = gtk_spin_button_new(adj, 0.5, 2);
    gtk_widget_set_usize(w, 50, 0);
    gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 0);
    gtk_widget_show(w);

    /* Canvas and scrollbars
    */
    gtk_widget_push_visual(gdk_imlib_get_visual());
    gtk_widget_push_colormap(gdk_imlib_get_colormap());
    ghack_map.canvas = GNOME_CANVAS(gnome_canvas_new());
    // gtk_widget_push_visual(gdk_rgb_get_visual());
    // gtk_widget_push_colormap(gdk_rgb_get_cmap());
    // ghack_map.canvas = GNOME_CANVAS (gnome_canvas_new_aa());

    gtk_widget_pop_colormap();
    gtk_widget_pop_visual();
    gtk_widget_show(GTK_WIDGET(ghack_map.canvas));

    table = gtk_table_new(2, 2, FALSE);
    gtk_table_set_row_spacings(GTK_TABLE(table), 4);
    gtk_table_set_col_spacings(GTK_TABLE(table), 4);
    gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
    gtk_widget_show(table);

    frame = gtk_frame_new(NULL);
    ghack_map.frame = frame;
    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
    gtk_table_attach(GTK_TABLE(table), frame, 0, 1, 0, 1,
                     GTK_EXPAND | GTK_FILL | GTK_SHRINK,
                     GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
    gtk_widget_show(frame);

    gtk_container_add(GTK_CONTAINER(frame), GTK_WIDGET(ghack_map.canvas));
    gnome_canvas_set_scroll_region(GNOME_CANVAS(ghack_map.canvas), 0, 0,
                                   width + 2 * ghack_glyph_width(),
                                   height + 2 * ghack_glyph_height());

    gnome_canvas_set_pixels_per_unit(GNOME_CANVAS(ghack_map.canvas), 1.0);

    w = gtk_hscrollbar_new(GTK_LAYOUT(ghack_map.canvas)->hadjustment);
    gtk_table_attach(GTK_TABLE(table), w, 0, 1, 1, 2,
                     GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL, 0, 0);
    gtk_widget_show(w);

    w = gtk_vscrollbar_new(GTK_LAYOUT(ghack_map.canvas)->vadjustment);
    gtk_table_attach(GTK_TABLE(table), w, 1, 2, 0, 1, GTK_FILL,
                     GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
    gtk_widget_show(w);

    myCanvasGroup = GNOME_CANVAS_GROUP(gnome_canvas_item_new(
                                           gnome_canvas_root(GNOME_CANVAS(ghack_map.canvas)),
                                           gnome_canvas_group_get_type(), "x", 0.0, "y", 0.0, NULL));

    /* Tile the map background with a pretty image */
    background = gdk_imlib_load_image((char *) "mapbg.xpm");
    if (background == NULL) {
        g_warning(
            "Bummer! Failed to load the map background image (mapbg.xpm)!");
    } else {
        gdk_imlib_render(background, background->rgb_width,
                         background->rgb_height);

        /* Tile the map background */
        for (y = 0; y < height + background->rgb_height;
                y += background->rgb_height) {
            for (x = 0; x < width + background->rgb_width;
                    x += background->rgb_width) {
                bg = GNOME_CANVAS_IMAGE(gnome_canvas_item_new(
                                            myCanvasGroup, gnome_canvas_image_get_type(), "x",
                                            (double) x, "y", (double) y, "width",
                                            (double) background->rgb_width, "height",
                                            (double) background->rgb_height, "image", background,
                                            "anchor", (GtkAnchorType) GTK_ANCHOR_CENTER, NULL));
                gnome_canvas_item_lower_to_bottom(GNOME_CANVAS_ITEM(bg));
            }
        }
    }

    /* ghack_map.map is an array of canvas images.  Each cell of
     * the array will contain one tile.  Here, we create the
     * space for the cells and then create the cells for easy
     * access later.
    */
    for (i = 0, y = 0; y < height; y += ghack_glyph_height()) {
        for (x = 0; x < width; x += ghack_glyph_width()) {
            ghack_map.map[i++] = GNOME_CANVAS_IMAGE(gnome_canvas_item_new(
                    myCanvasGroup, gnome_canvas_image_get_type(), "x", (double) x,
                    "y", (double) y, "width", (double) ghack_glyph_width(),
                    "height", (double) ghack_glyph_height(), "anchor",
                    GTK_ANCHOR_NORTH_WEST, NULL));
        }
    }

    /* Set up the pet mark image */
    petmark = gdk_imlib_create_image_from_xpm_data(pet_mark_xpm);
    if (petmark == NULL) {
        g_warning("Bummer! Failed to load the pet_mark image!");
    } else {
        gdk_imlib_render(petmark, petmark->rgb_width, petmark->rgb_height);

        /* ghack_map.overlay is an array of canvas images used to
         * overlay tile images...
         */
        for (i = 0, y = 0; y < height; y += ghack_glyph_height()) {
            for (x = 0; x < width; x += ghack_glyph_width()) {
                ghack_map.overlay[i] =
                    GNOME_CANVAS_IMAGE(gnome_canvas_item_new(
                                           myCanvasGroup, gnome_canvas_image_get_type(), "x",
                                           (double) x, "y", (double) y, "width",
                                           (double) petmark->rgb_width, "height",
                                           (double) petmark->rgb_height, "image", petmark,
                                           "anchor", GTK_ANCHOR_NORTH_WEST, NULL));
                gnome_canvas_item_lower_to_bottom(
                    GNOME_CANVAS_ITEM(ghack_map.overlay[i++]));
            }
        }
    }

    /* Resize the canvas when the spinbutton changes
    */
    gtk_signal_connect(GTK_OBJECT(adj), "value_changed",
                       (GtkSignalFunc) ghack_map_window_zoom,
                       ghack_map.canvas);

    /* Game signals
    */
    gtk_signal_connect(GTK_OBJECT(vbox), "ghack_curs",
                       GTK_SIGNAL_FUNC(ghack_map_cursor_to), NULL);
    gtk_signal_connect(GTK_OBJECT(vbox), "ghack_putstr",
                       GTK_SIGNAL_FUNC(ghack_map_putstr), NULL);
    gtk_signal_connect(GTK_OBJECT(vbox), "ghack_print_glyph",
                       GTK_SIGNAL_FUNC(ghack_map_print_glyph), NULL);
    gtk_signal_connect(GTK_OBJECT(vbox), "ghack_clear",
                       GTK_SIGNAL_FUNC(ghack_map_clear), NULL);
    gtk_signal_connect(GTK_OBJECT(vbox), "ghack_display",
                       GTK_SIGNAL_FUNC(ghack_map_display), NULL);
    gtk_signal_connect(GTK_OBJECT(vbox), "ghack_cliparound",
                       GTK_SIGNAL_FUNC(ghack_map_cliparound), NULL);
    gtk_signal_connect(GTK_OBJECT(ghack_map.canvas), "button_press_event",
                       GTK_SIGNAL_FUNC(ghack_handle_button_press), NULL);
    gtk_signal_connect(GTK_OBJECT(ghack_map.canvas), "gnome_delay_output",
                       GTK_SIGNAL_FUNC(ghack_delay), NULL);

    return GTK_WIDGET(vbox);
}
GtkWidget *
gnc_item_edit_new (GnucashSheet *sheet)
{
    char *hpad_str, *vpad_str, *entry_css;
    GtkStyleContext *stylecontext;
    GtkCssProvider *provider;
    GncItemEdit *item_edit =
            g_object_new (GNC_TYPE_ITEM_EDIT,
                          "sheet", sheet,
                          "spacing",     0,
                          "homogeneous", FALSE,
                           NULL);
    gtk_layout_put (GTK_LAYOUT(sheet), GTK_WIDGET(item_edit), 0, 0);

    // This sets a style class for when Gtk+ version is less than 3.20
    gnc_widget_set_css_name (GTK_WIDGET(item_edit), "cursor");

    /* Create the text entry */
    item_edit->editor = gtk_entry_new();
    sheet->entry = item_edit->editor;
    gtk_entry_set_width_chars (GTK_ENTRY(item_edit->editor), 1);
    gtk_box_pack_start (GTK_BOX(item_edit), item_edit->editor,  TRUE, TRUE, 0);

    // Make sure the Entry can not have focus and no frame
    gtk_widget_set_can_focus (GTK_WIDGET(item_edit->editor), FALSE);
    gtk_entry_set_has_frame (GTK_ENTRY(item_edit->editor), FALSE);

    // Connect to the draw signal so we can draw a cursor
    g_signal_connect_after (item_edit->editor, "draw",
                            G_CALLBACK (draw_text_cursor_cb), NULL);

    // Fill in the background so the underlying sheet cell can not be seen
    g_signal_connect (item_edit, "draw",
                            G_CALLBACK (draw_background_cb), item_edit);

    /* Force padding on the entry to align with the rest of the register this
       is done in the gnucash.css file which should be in line with sheet.h */

    /* Create the popup button
       It will only be displayed when the cell being edited provides
       a popup item (like a calendar or account list) */
    item_edit->popup_toggle.tbutton = gtk_toggle_button_new();
    gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (item_edit->popup_toggle.tbutton), FALSE);

    /* Force padding on the button to keep it small and display as much as
       possible of the arrow which is done in the gnucash.css file */

    /* Wrap the popup button in an event box to give it its own gdkwindow.
     * Without one the button would disappear behind the grid object. */
    item_edit->popup_toggle.ebox = gtk_event_box_new();
    g_object_ref(item_edit->popup_toggle.ebox);
    gtk_container_add(GTK_CONTAINER(item_edit->popup_toggle.ebox),
                      item_edit->popup_toggle.tbutton);

    gtk_box_pack_start (GTK_BOX(item_edit),
                        item_edit->popup_toggle.ebox,
                        FALSE, TRUE, 0);
    gtk_widget_show_all(GTK_WIDGET(item_edit));

    return GTK_WIDGET(item_edit);
}
示例#20
0
MimeView *mimeview_create(MainWindow *mainwin)
{
	MimeView *mimeview;

	GtkWidget *paned;
	GtkWidget *scrolledwin;
	GtkWidget *ctree;
	GtkWidget *mime_notebook;
	GtkWidget *popupmenu;
	GtkWidget *ctree_mainbox;
	GtkWidget *vbox;
	GtkWidget *mime_toggle;
	GtkWidget *icon_mainbox;
	GtkWidget *icon_scroll;
	GtkWidget *icon_vbox;
	GtkWidget *arrow;
	GtkWidget *scrollbutton;
	GtkWidget *hbox;
	GtkTooltips *tooltips;
	GtkItemFactory *popupfactory;
	NoticeView *siginfoview;
	gchar *titles[N_MIMEVIEW_COLS];
	gint n_entries;
	gint i;

	debug_print("Creating MIME view...\n");
	mimeview = g_new0(MimeView, 1);

	titles[COL_MIMETYPE] = _("MIME Type");
	titles[COL_SIZE]     = _("Size");
	titles[COL_NAME]     = _("Name");

	scrolledwin = gtk_scrolled_window_new(NULL, NULL);
	gtk_widget_show(scrolledwin);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
				       GTK_POLICY_AUTOMATIC,
				       GTK_POLICY_ALWAYS);

	ctree = gtk_sctree_new_with_titles(N_MIMEVIEW_COLS, 0, titles);
	gtk_widget_show(ctree);
	gtk_clist_set_selection_mode(GTK_CLIST(ctree), GTK_SELECTION_BROWSE);
	gtk_ctree_set_line_style(GTK_CTREE(ctree), GTK_CTREE_LINES_NONE);
	gtk_clist_set_column_justification(GTK_CLIST(ctree), COL_SIZE,
					   GTK_JUSTIFY_RIGHT);
	gtk_clist_set_column_width(GTK_CLIST(ctree), COL_MIMETYPE, 240);
	gtk_clist_set_column_width(GTK_CLIST(ctree), COL_SIZE, 90);
	for (i = 0; i < N_MIMEVIEW_COLS; i++)
		GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(ctree)->column[i].button,
				       GTK_CAN_FOCUS);
	gtk_container_add(GTK_CONTAINER(scrolledwin), ctree);

	gtk_signal_connect(GTK_OBJECT(ctree), "tree_select_row",
			   GTK_SIGNAL_FUNC(mimeview_selected), mimeview);
	gtk_signal_connect(GTK_OBJECT(ctree), "button_release_event",
			   GTK_SIGNAL_FUNC(mimeview_button_pressed), mimeview);
	gtk_signal_connect(GTK_OBJECT(ctree), "key_press_event",
			   GTK_SIGNAL_FUNC(mimeview_key_pressed), mimeview);
	gtk_signal_connect(GTK_OBJECT (ctree),"start_drag",
			   GTK_SIGNAL_FUNC (mimeview_start_drag), mimeview);
	gtk_signal_connect(GTK_OBJECT(ctree), "drag_data_get",
			   GTK_SIGNAL_FUNC(mimeview_drag_data_get), mimeview);

	mime_notebook = gtk_notebook_new();
        gtk_widget_show(mime_notebook);
        GTK_WIDGET_UNSET_FLAGS(mime_notebook, GTK_CAN_FOCUS);
        gtk_notebook_set_show_tabs(GTK_NOTEBOOK(mime_notebook), FALSE);
        gtk_notebook_set_show_border(GTK_NOTEBOOK(mime_notebook), FALSE);
	
	icon_vbox = gtk_vbox_new(FALSE, 2);
	gtk_widget_show(icon_vbox);
	icon_scroll = gtk_layout_new(NULL, NULL);
	gtk_widget_show(icon_scroll);
	gtk_layout_put(GTK_LAYOUT(icon_scroll), icon_vbox, 0, 0);
	scrollbutton = gtk_vscrollbutton_new(gtk_layout_get_vadjustment(GTK_LAYOUT(icon_scroll)));
	gtk_widget_show(scrollbutton);

    	mime_toggle = gtk_toggle_button_new();
	gtk_widget_show(mime_toggle);
	arrow = gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_NONE);
	gtk_widget_show(arrow);
	gtk_container_add(GTK_CONTAINER(mime_toggle), arrow);
	gtk_signal_connect(GTK_OBJECT(mime_toggle), "toggled", 
			   GTK_SIGNAL_FUNC(mime_toggle_button_cb), mimeview);

	icon_mainbox = gtk_vbox_new(FALSE, 0);
	gtk_widget_show(icon_mainbox);
	gtk_box_pack_start(GTK_BOX(icon_mainbox), mime_toggle, FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX(icon_mainbox), icon_scroll, TRUE, TRUE, 3);
	gtk_box_pack_end(GTK_BOX(icon_mainbox), scrollbutton, FALSE, FALSE, 0);
	gtk_signal_connect(GTK_OBJECT(icon_mainbox), "size_allocate", 
			GTK_SIGNAL_FUNC(icon_scroll_size_allocate_cb), mimeview);
	
	ctree_mainbox = gtk_hbox_new(FALSE, 0);	
	gtk_box_pack_start(GTK_BOX(ctree_mainbox), scrolledwin, TRUE, TRUE, 0);

 	n_entries = sizeof(mimeview_popup_entries) /
 		sizeof(mimeview_popup_entries[0]);
 	popupmenu = menu_create_items(mimeview_popup_entries, n_entries,
 				      "<MimeView>", &popupfactory, mimeview);
	tooltips = gtk_tooltips_new();
	gtk_tooltips_set_delay(tooltips, 0); 

	vbox = gtk_vbox_new(FALSE, 0);
	gtk_widget_show(vbox);
	siginfoview = noticeview_create(mainwin);
	noticeview_hide(siginfoview);
	gtk_box_pack_start(GTK_BOX(vbox), mime_notebook, TRUE, TRUE, 0);
	gtk_box_pack_end(GTK_BOX(vbox), GTK_WIDGET_PTR(siginfoview), FALSE, FALSE, 0);

	paned = gtk_vpaned_new();
	gtk_widget_show(paned);
	gtk_paned_set_gutter_size(GTK_PANED(paned), 0);
	gtk_paned_pack1(GTK_PANED(paned), ctree_mainbox, FALSE, TRUE);
	gtk_paned_pack2(GTK_PANED(paned), vbox, TRUE, TRUE);
	
	hbox = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(hbox), paned, TRUE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(hbox), icon_mainbox, FALSE, FALSE, 0);

	gtk_widget_show(hbox);
	gtk_widget_hide(ctree_mainbox);

	mimeview->hbox          = hbox;
	mimeview->paned         = paned;
	mimeview->scrolledwin   = scrolledwin;
	mimeview->ctree         = ctree;
	mimeview->mime_notebook = mime_notebook;
	mimeview->popupmenu     = popupmenu;
	mimeview->popupfactory  = popupfactory;
	mimeview->type          = -1;
	mimeview->ctree_mainbox = ctree_mainbox;
	mimeview->icon_scroll   = icon_scroll;
	mimeview->icon_vbox     = icon_vbox;
	mimeview->icon_mainbox  = icon_mainbox;
	mimeview->icon_count    = 0;
	mimeview->mainwin       = mainwin;
	mimeview->tooltips      = tooltips;
	mimeview->oldsize       = 60;
	mimeview->mime_toggle   = mime_toggle;
	mimeview->siginfoview	= siginfoview;

	mimeview->target_list	= gtk_target_list_new(mimeview_mime_types, 1); 
	
	mimeviews = g_slist_prepend(mimeviews, mimeview);

	return mimeview;
}
示例#21
0
文件: gtk_glue.c 项目: Blei/rgtk
GtkLayout* cast_GtkLayout(GtkWidget* widget) {
    return GTK_LAYOUT(widget);
}
示例#22
0
int main( int    argc, char **argv )
{
    GtkBuilder *builder;
    GtkWidget  *window;
    GError     *error = NULL;
GtkLayout * layout;

    /* Init GTK+ */
    gtk_init( &argc, &argv );

    /* Create new GtkBuilder object */
    builder = gtk_builder_new();
    /* Load UI from file. If error occurs, report it and quit application.
     * Replace "tut.glade" with your saved project. */
    if( ! gtk_builder_add_from_file( builder, "sim.glade", &error ) )
    {
        g_warning( "%s", error->message );
        g_free( error );
        return( 1 );
    }

    	/* Get main window pointer from UI */
    	window = GTK_WIDGET( gtk_builder_get_object( builder, "window1" ) );

	layout = GTK_LAYOUT(gtk_builder_get_object (builder, "layout2"));

    populate(layout);
    

    /* Connect signals */
       gtk_builder_connect_signals( builder, NULL );


       /* this variable is our reference to the second thread */
       pthread_t inc_x_thread;
    pthread_t wr_x_thread;


    if(pthread_create(&wr_x_thread, NULL, write, layout)) {

          fprintf(stderr, "Error creating thread\n");
          return 1;

      }

       /* create a second thread which executes inc_x(&x) */
       if(pthread_create(&inc_x_thread, NULL, react, layout)) {

           fprintf(stderr, "Error creating thread\n");
           return 1;

       }


   	 /* Destroy builder, since we don't need it anymore */
       g_object_unref( G_OBJECT( builder ) );

       /* Show window. All other widgets are automatically shown by GtkBuilder */
       gtk_widget_show_all( window );




    /* Start main loop */
    gtk_main();


    return( 0 );
}
示例#23
0
static void
gnc_header_realized (GtkWidget *widget, gpointer data)
{
    gdk_window_set_back_pixmap (GTK_LAYOUT (widget)->bin_window,
                                NULL, FALSE);
}
示例#24
0
void vi_list_refresh(struct vi_list_t *list)
{
	int width;
	int height;

	int x;
	int y;

	int count;
	int i;

	GtkStyle *style;
	GList *child;

	/* Clear current item list and empty layout */
	while (list->item_list->count)
		vi_list_item_free(list_remove_at(list->item_list, 0));
	while ((child = gtk_container_get_children(GTK_CONTAINER(list->widget))))
		gtk_container_remove(GTK_CONTAINER(list->widget), child->data);

	/* Get 'list' widget size */
	width = gtk_widget_get_allocated_width(list->widget);
	height = gtk_widget_get_allocated_height(list->widget);
	list->width = width;
	list->height = height;

	/* Background color */
	GdkColor color;
	style = gtk_widget_get_style(list->widget);
	color = style->bg[GTK_STATE_NORMAL];

	/* Fill it with labels */
	x = 0;
	y = 0;
	count = list->elem_list->count;
	for (i = 0; i < count; i++)
	{
		int last;

		struct vi_list_item_t *item;
		void *elem;

		char str1[MAX_STRING_SIZE];
		char str2[MAX_STRING_SIZE];
		char *comma;

		GtkWidget *label;
		GtkWidget *event_box;

		PangoAttrList *attrs;
		PangoAttribute *size_attr;

		GtkRequisition req;

		/* Create list item */
		item = vi_list_item_create();

		/* Get current element */
		elem = list_get(list->elem_list, i);

		/* Create label */
		comma = i < count - 1 ? "," : "";
		if (list->get_elem_name)
			(*list->get_elem_name)(elem, str1, sizeof str1);
		else
			snprintf(str1, sizeof str1, "item-%d", i);
		snprintf(str2, sizeof str2, "%s%s", str1, comma);
		label = gtk_label_new(str2);
		gtk_label_set_use_markup(GTK_LABEL(label), TRUE);

		/* Set label font attributes */
		attrs = pango_attr_list_new();
		size_attr = pango_attr_size_new_absolute(list->text_size << 10);
		pango_attr_list_insert(attrs, size_attr);
		gtk_label_set_attributes(GTK_LABEL(label), attrs);

		/* Get position */
		gtk_widget_get_preferred_size(label, &req, NULL);
		last = 0;
		if (x > 0 && x + req.width >= width)
		{
			x = 0;
			y += req.height;
			if (y + 2 * req.height >= height && i < count - 1)
			{
				snprintf(str1, sizeof str1, "+ %d more", count - i);
				gtk_label_set_text(GTK_LABEL(label), str1);
				gtk_widget_get_preferred_size(label, &req, NULL);
				last = 1;
			}
		}

		/* Create event box */
		event_box = gtk_event_box_new();
		gtk_widget_modify_bg(event_box, GTK_STATE_NORMAL, &color);
		gtk_container_add(GTK_CONTAINER(event_box), label);
		gtk_widget_add_events(event_box, GDK_ENTER_NOTIFY_MASK |
			GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK);

		/* Events for event box */
		g_signal_connect(G_OBJECT(event_box), "enter-notify-event",
			G_CALLBACK(vi_list_item_enter_notify_event), item);
		g_signal_connect(G_OBJECT(event_box), "leave-notify-event",
			G_CALLBACK(vi_list_item_leave_notify_event), item);
		if (last)
			g_signal_connect(G_OBJECT(event_box), "button-press-event",
				G_CALLBACK(vi_list_item_more_press_event), item);
		else
			g_signal_connect(G_OBJECT(event_box), "button-press-event",
				G_CALLBACK(vi_list_item_button_press_event), item);

		/* Insert event box in 'list' layout */
		gtk_layout_put(GTK_LAYOUT(list->widget), event_box, x, y);

		/* Initialize item */
		item->list = list;
		item->elem = elem;
		item->event_box = event_box;
		item->label = label;
		list_add(list->item_list, item);

		/* Advance */
		x += req.width + 5;
		if (last)
			break;
	}

	/* Show all new widgets */
	gtk_widget_show_all(list->widget);
	gtk_container_check_resize(GTK_CONTAINER(list->widget));
}
示例#25
0
文件: window.c 项目: fmf/music-widget
gboolean set_widgets_defaults(GtkWidget *mvbox, track_t *t, GdkRGBA *color)
{
	GtkWidget *hbox, *vbox, *label, *hbox2,
						*sep, *button, *img, *eventBox;
	gint i = 0;
	GdkRGBA buttonNormal = {1, 1, 1, 0.2};
	GdkRGBA buttonSelected = {1, 1, 1, 0.6};


	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
	gtk_box_pack_start(GTK_BOX(mvbox), hbox, 0, 0, 1);

	/* album image */
	eventBox = gtk_event_box_new();
	gtk_event_box_set_visible_window(GTK_EVENT_BOX(eventBox), 0);
	gtk_widget_set_events(eventBox, GDK_BUTTON_PRESS_MASK);

	t->trackw.image = gtk_image_new();
	gtk_container_add(GTK_CONTAINER(eventBox), t->trackw.image);
	g_signal_connect(eventBox, "button_press_event", G_CALLBACK(show_player_callback), NULL);
	gtk_box_pack_start(GTK_BOX(hbox), eventBox, 0, 0, 0);


	/* track info: name, artist, album */
	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
	gtk_box_pack_start(GTK_BOX(hbox), vbox, 0, 0, 0);


	t->trackw.label.name = gtk_label_new(NULL);
	gtk_misc_set_alignment(GTK_MISC(t->trackw.label.name), 0, 0);
	/* create the layout to be able to scrol the label's contents */
	t->trackw.layout.name = gtk_layout_new(NULL, NULL);
	/* set size otherwise it won't show up */
	gtk_widget_set_size_request(t->trackw.layout.name, SCROLL_SIZE_W, SCROLL_SIZE_H);
	/* make layout's color the same as the window's */
	gtk_widget_override_background_color(t->trackw.layout.name, GTK_STATE_FLAG_NORMAL, color);
	gtk_layout_put(GTK_LAYOUT(t->trackw.layout.name), t->trackw.label.name, 0, 0);


	t->trackw.label.artist = gtk_label_new(NULL);
	gtk_misc_set_alignment(GTK_MISC(t->trackw.label.artist), 0, 0);
	t->trackw.layout.artist = gtk_layout_new(NULL, NULL);
	gtk_widget_set_size_request(t->trackw.layout.artist, SCROLL_SIZE_W-23, SCROLL_SIZE_H);
	gtk_widget_override_background_color(t->trackw.layout.artist, GTK_STATE_FLAG_NORMAL, color);
	gtk_layout_put(GTK_LAYOUT(t->trackw.layout.artist), t->trackw.label.artist, 0, 0);


	t->trackw.label.album = gtk_label_new(NULL);
	gtk_misc_set_alignment(GTK_MISC(t->trackw.label.album), 0, 0);
	t->trackw.layout.album = gtk_layout_new(NULL, NULL);
	gtk_widget_set_size_request(t->trackw.layout.album, SCROLL_SIZE_W-40, SCROLL_SIZE_H);
	gtk_widget_override_background_color(t->trackw.layout.album, GTK_STATE_FLAG_NORMAL, color);
	gtk_layout_put(GTK_LAYOUT(t->trackw.layout.album), t->trackw.label.album, 0, 0);


	/* put the name, artist and album at their places */
	gtk_box_pack_start(GTK_BOX(vbox), t->trackw.layout.name, 0, 0, 0);


	hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox2, 0, 0, 0);

	label = gtk_label_new(NULL);
	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
	gtk_label_set_markup(GTK_LABEL(label), "<span font='Sans 11' font_style='italic'"
												"color='#FFFFFF'>by </span>");
	gtk_box_pack_start(GTK_BOX(hbox2), label, 0, 0, 0);
	gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.layout.artist, 0, 0, 0);


	hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox2, 0, 0, 0);

	label = gtk_label_new(NULL);
	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
	gtk_label_set_markup(GTK_LABEL(label), "<span font='Sans 11' font_style='italic'"
												"color='#FFFFFF'>from </span>");
	gtk_box_pack_start(GTK_BOX(hbox2), label, 0, 0, 0);
	gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.layout.album, 0, 0, 0);


	/* puts the genre, rating, year, and playcount */
	hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox2, 0, 0, 0);

	t->trackw.genre = gtk_label_new(NULL);
	gtk_misc_set_alignment(GTK_MISC(t->trackw.genre), 0, 0);
	gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.genre, 0, 0, 0);


	sep = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
	gtk_box_pack_start(GTK_BOX(hbox2), sep, 0, 0, 3);


	for (i = 0; i < 5; i++) {
		t->trackw.stars[i] = gtk_image_new();
		gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.stars[i], 0, 0, 1);
	}


	sep = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
	gtk_box_pack_start(GTK_BOX(hbox2), sep, 0, 0, 3);


	t->trackw.year = gtk_label_new(NULL);
	gtk_misc_set_alignment(GTK_MISC(t->trackw.year), 0, 0);
	gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.year, 0, 0, 0);


	sep = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
	gtk_box_pack_start(GTK_BOX(hbox2), sep, 0, 0, 3);


	t->trackw.playcount = gtk_label_new(NULL);
	gtk_misc_set_alignment(GTK_MISC(t->trackw.playcount), 0, 0);
	gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.playcount, 0, 0, 0);


	/* puts the current position, the slider showing the progress
	 * and track length */
	hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox2, 0, 0, 0);


	t->trackw.position = gtk_label_new(NULL);
	gtk_misc_set_alignment(GTK_MISC(t->trackw.position), 0, 0);
	gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.position, 0, 0, 0);


	t->trackw.slider = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, NULL);
	gtk_widget_set_size_request(t->trackw.slider, 170, -1);
	gtk_scale_set_draw_value(GTK_SCALE(t->trackw.slider), 0);
	gtk_range_set_show_fill_level(GTK_RANGE(t->trackw.slider), 1);
	gtk_range_set_restrict_to_fill_level(GTK_RANGE(t->trackw.slider), 0);
	/*g_signal_connect(t->trackw.slider, "value-changed", G_CALLBACK(slider_value_changed), NULL);*/
	gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.slider, 0, 0, 0);


	t->trackw.length = gtk_label_new(NULL);
	gtk_misc_set_alignment(GTK_MISC(t->trackw.length), 0, 0);
	gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.length, 0, 0, 0);


	/* the player controls */
	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
	gtk_box_pack_start(GTK_BOX(mvbox), hbox, 0, 0, 0);


	img = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_xpm_data(prev_xpm));
	button = gtk_button_new();
	gtk_widget_override_background_color(button, GTK_STATE_FLAG_NORMAL, &buttonNormal);
	gtk_widget_override_background_color(button, GTK_STATE_FLAG_ACTIVE, &buttonSelected);
	gtk_container_add(GTK_CONTAINER(button), img);
	g_signal_connect(button, "clicked", G_CALLBACK(button_callback),
										GINT_TO_POINTER(BUTTON_PREV));
	gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);


	t->playerControls.playPause = gtk_image_new();
	button = gtk_button_new();
	gtk_widget_override_background_color(button, GTK_STATE_FLAG_NORMAL, &buttonNormal);
	gtk_widget_override_background_color(button, GTK_STATE_FLAG_ACTIVE, &buttonSelected);
	gtk_container_add(GTK_CONTAINER(button), t->playerControls.playPause);
	g_signal_connect(button, "clicked", G_CALLBACK(button_callback),
										GINT_TO_POINTER(BUTTON_PLAY_PAUSE));
	gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);


	img = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_xpm_data(next_xpm));
	button = gtk_button_new();
	gtk_widget_override_background_color(button, GTK_STATE_FLAG_NORMAL, &buttonNormal);
	gtk_widget_override_background_color(button, GTK_STATE_FLAG_ACTIVE, &buttonSelected);
	gtk_container_add(GTK_CONTAINER(button), img);
	g_signal_connect(button, "clicked", G_CALLBACK(button_callback),
										GINT_TO_POINTER(BUTTON_NEXT));
	gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);


	sep = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
	gtk_box_pack_start(GTK_BOX(hbox), sep, 0, 0, 2);

	t->playerControls.repeat = gtk_image_new();
	button = gtk_button_new();
	gtk_widget_override_background_color(button, GTK_STATE_FLAG_NORMAL, &buttonNormal);
	gtk_widget_override_background_color(button, GTK_STATE_FLAG_ACTIVE, &buttonSelected);
	gtk_container_add(GTK_CONTAINER(button), t->playerControls.repeat);
	g_signal_connect(button, "clicked", G_CALLBACK(button_callback),
										GINT_TO_POINTER(BUTTON_REPEAT));
	gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);


	t->playerControls.shuffle = gtk_image_new();
	button = gtk_button_new();
	gtk_widget_override_background_color(button, GTK_STATE_FLAG_NORMAL, &buttonNormal);
	gtk_widget_override_background_color(button, GTK_STATE_FLAG_ACTIVE, &buttonSelected);
	gtk_container_add(GTK_CONTAINER(button), t->playerControls.shuffle);
	g_signal_connect(button, "clicked", G_CALLBACK(button_callback),
										GINT_TO_POINTER(BUTTON_SHUFFLE));
	gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);

	return TRUE;
}
static void
app_resizer_size_allocate (GtkWidget * widget, GtkAllocation * allocation)
{
	/* printf("ENTER - app_resizer_size_allocate\n"); */
	AppResizer *resizer = APP_RESIZER (widget);
	GtkWidget *child = GTK_WIDGET (APP_RESIZER (resizer)->child);
	GtkAllocation widget_allocation;
	GtkRequisition child_requisition;

	static gboolean first_time = TRUE;
	gint new_num_cols;
	gint useable_area;

	gtk_widget_get_allocation (child, &widget_allocation);

	if (first_time)
	{
		/* we are letting the first show be the "natural" size of the child widget so do nothing. */
		if (GTK_WIDGET_CLASS (app_resizer_parent_class)->size_allocate)
			(*GTK_WIDGET_CLASS (app_resizer_parent_class)->size_allocate) (widget, allocation);

		first_time = FALSE;
		gtk_layout_set_size (GTK_LAYOUT (resizer), widget_allocation.width,
			widget_allocation.height);
		return;
	}

#if GTK_CHECK_VERSION (3, 0, 0)
	gtk_widget_get_preferred_size (child, &child_requisition, NULL);
#else
	child_requisition = child->requisition;
#endif

	if (!resizer->cached_tables_list)	/* if everthing is currently filtered out - just return */
	{
		GtkAllocation child_allocation;

		if (GTK_WIDGET_CLASS (app_resizer_parent_class)->size_allocate)
			(*GTK_WIDGET_CLASS (app_resizer_parent_class)->size_allocate) (widget, allocation);

		/* We want the message to center itself and only scroll if it's bigger than the available real size. */
		child_allocation.x = 0;
		child_allocation.y = 0;
		child_allocation.width = MAX (allocation->width, child_requisition.width);
		child_allocation.height = MAX (allocation->height, child_requisition.height);

		gtk_widget_size_allocate (child, &child_allocation);
		gtk_layout_set_size (GTK_LAYOUT (resizer), child_allocation.width,
			child_allocation.height);
		return;
	}
	GtkRequisition other_requisiton;
#if GTK_CHECK_VERSION (3, 0, 0)
	gtk_widget_get_preferred_size (GTK_WIDGET (resizer->cached_tables_list->data), &other_requisiton, NULL);
#else
	other_requisiton = GTK_WIDGET (resizer->cached_tables_list->data)->requisition;
#endif

	useable_area =
		allocation->width - (child_requisition.width -
		other_requisiton.width);
	new_num_cols =
		relayout_tables_if_needed (APP_RESIZER (resizer), useable_area,
		resizer->cur_num_cols);
	if (resizer->cur_num_cols != new_num_cols)
	{
		GtkRequisition req;

		/* Have to do this so that it requests, and thus gets allocated, new amount */
		gtk_widget_size_request (child, &req);

		resizer->cur_num_cols = new_num_cols;
	}

	if (GTK_WIDGET_CLASS (app_resizer_parent_class)->size_allocate)
		(*GTK_WIDGET_CLASS (app_resizer_parent_class)->size_allocate) (widget, allocation);
	gtk_layout_set_size (GTK_LAYOUT (resizer), widget_allocation.width,
		widget_allocation.height);
}
示例#27
0
/*
 * (Nearly) standard Gtk+ function
 */
static void Dw_gtk_viewport_paint (GtkWidget *widget,
                                   GdkRectangle *area,
                                   GdkEventExpose *event)
{
   GtkLayout *layout;
   DwRectangle parent_area, child_area, intersection;
   GtkDwViewport *viewport;
   gboolean new_back_pixmap;

   if (GTK_WIDGET_DRAWABLE (widget)) {
      layout = GTK_LAYOUT (widget);
      viewport = GTK_DW_VIEWPORT (widget);

      DEBUG_MSG (2, "Drawing (%d, %d), %d x %d\n",
                 area->x, area->y, area->width, area->height);

      /* Make sure the backing pixmap is large enough. */
      if (viewport->child) {
         if (viewport->back_pixmap)
            new_back_pixmap =
               (widget->allocation.width > viewport->back_width ||
                widget->allocation.height > viewport->back_height);
         else
            new_back_pixmap = TRUE;

         if (new_back_pixmap) {
            if (viewport->back_pixmap)
               gdk_pixmap_unref (viewport->back_pixmap);
            viewport->back_pixmap = gdk_pixmap_new (widget->window,
                                                    widget->allocation.width,
                                                    widget->allocation.height,
                                                    viewport->depth);
            viewport->back_width = widget->allocation.width;
            viewport->back_height = widget->allocation.height;
            DEBUG_MSG (1, "   Creating new pixmap, size = %d x %d\n",
                       widget->allocation.width, widget->allocation.height);
         }

         /* Draw top-level Dw widget. */
         parent_area.x =
            p_Dw_widget_x_viewport_to_world (viewport->child, area->x);
         parent_area.y =
            p_Dw_widget_y_viewport_to_world (viewport->child, area->y);
         parent_area.width = area->width;
         parent_area.height = area->height;

         child_area.x = viewport->child->allocation.x;
         child_area.y = viewport->child->allocation.y;
         child_area.width = viewport->child->allocation.width;
         child_area.height = DW_WIDGET_HEIGHT(viewport->child);

         if (p_Dw_rectangle_intersect (&parent_area, &child_area,
                                       &intersection)) {
            intersection.x -= viewport->child->allocation.x;
            intersection.y -= viewport->child->allocation.y;

            /* "Clear" backing pixmap. */
            gdk_draw_rectangle (viewport->back_pixmap,
                                viewport->child->style->background_color->gc,
                                TRUE, area->x, area->y,
                                area->width, area->height);
            /* Widgets draw in backing pixmap. */
            p_Dw_widget_draw (viewport->child, &intersection, event);
            /* Copy backing pixmap into window. */
            gdk_draw_pixmap (layout->bin_window, widget->style->black_gc,
                             viewport->back_pixmap, area->x, area->y,
                             area->x, area->y, area->width, area->height);
         }
      } else
         gdk_window_clear_area (layout->bin_window,
                                area->x, area->y, area->width, area->height);
   }
}
示例#28
0
static gboolean 
nsgtk_window_draw_event(GtkWidget *widget, cairo_t *cr, gpointer data)
{
	struct gui_window *gw = data;
	struct gui_window *z;
	struct rect clip;
	struct redraw_context ctx = {
		.interactive = true,
		.background_images = true,
		.plot = &nsgtk_plotters
	};

	double x1;
	double y1;
	double x2;
	double y2;

	assert(gw);
	assert(gw->bw);

	for (z = window_list; z && z != gw; z = z->next)
		continue;
	assert(z);
	assert(GTK_WIDGET(gw->layout) == widget);

	current_widget = (GtkWidget *)gw->layout;
	current_cr = cr;

	cairo_clip_extents(cr, &x1, &y1, &x2, &y2);

	clip.x0 = x1;
	clip.y0 = y1;
	clip.x1 = x2;
	clip.y1 = y2;

	browser_window_redraw(gw->bw, 0, 0, &clip, &ctx);

	if (gw->careth != 0) {
		nsgtk_plot_caret(gw->caretx, gw->carety, gw->careth);
	}

	current_widget = NULL;

	return FALSE;
}

#else

static gboolean 
nsgtk_window_draw_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
	struct gui_window *gw = data;
	struct gui_window *z;
	struct rect clip;
	struct redraw_context ctx = {
		.interactive = true,
		.background_images = true,
		.plot = &nsgtk_plotters
	};

	assert(gw);
	assert(gw->bw);

	for (z = window_list; z && z != gw; z = z->next)
		continue;
	assert(z);
	assert(GTK_WIDGET(gw->layout) == widget);

	current_widget = (GtkWidget *)gw->layout;
	current_cr = gdk_cairo_create(nsgtk_layout_get_bin_window(gw->layout));

	clip.x0 = event->area.x;
	clip.y0 = event->area.y;
	clip.x1 = event->area.x + event->area.width;
	clip.y1 = event->area.y + event->area.height;

	browser_window_redraw(gw->bw, 0, 0, &clip, &ctx);

	if (gw->careth != 0) {
		nsgtk_plot_caret(gw->caretx, gw->carety, gw->careth);
	}

	cairo_destroy(current_cr);

	current_widget = NULL;

	return FALSE;
}

#endif

static gboolean nsgtk_window_motion_notify_event(GtkWidget *widget,
					  GdkEventMotion *event, gpointer data)
{
	struct gui_window *g = data;
	bool shift = event->state & GDK_SHIFT_MASK;
	bool ctrl = event->state & GDK_CONTROL_MASK;

	if ((abs(event->x - g->last_x) < 5) &&
	    (abs(event->y - g->last_y) < 5)) {
		/* Mouse hasn't moved far enough from press coordinate for this
		 * to be considered a drag. */
		return FALSE;
	} else {
		/* This is a drag, ensure it's always treated as such, even if
		 * we drag back over the press location */
		g->last_x = INT_MIN;
		g->last_y = INT_MIN;
	}

	if (g->mouse.state & BROWSER_MOUSE_PRESS_1) {
		/* Start button 1 drag */
		browser_window_mouse_click(g->bw, BROWSER_MOUSE_DRAG_1,
				g->mouse.pressed_x, g->mouse.pressed_y);

		/* Replace PRESS with HOLDING and declare drag in progress */
		g->mouse.state ^= (BROWSER_MOUSE_PRESS_1 |
				BROWSER_MOUSE_HOLDING_1);
		g->mouse.state |= BROWSER_MOUSE_DRAG_ON;
	} else if (g->mouse.state & BROWSER_MOUSE_PRESS_2) {
		/* Start button 2 drag */
		browser_window_mouse_click(g->bw, BROWSER_MOUSE_DRAG_2,
				g->mouse.pressed_x, g->mouse.pressed_y);

		/* Replace PRESS with HOLDING and declare drag in progress */
		g->mouse.state ^= (BROWSER_MOUSE_PRESS_2 |
				BROWSER_MOUSE_HOLDING_2);
		g->mouse.state |= BROWSER_MOUSE_DRAG_ON;
	}

	/* Handle modifiers being removed */
	if (g->mouse.state & BROWSER_MOUSE_MOD_1 && !shift)
		g->mouse.state ^= BROWSER_MOUSE_MOD_1;
	if (g->mouse.state & BROWSER_MOUSE_MOD_2 && !ctrl)
		g->mouse.state ^= BROWSER_MOUSE_MOD_2;

	browser_window_mouse_track(g->bw, g->mouse.state,
			event->x / g->bw->scale, event->y / g->bw->scale);

	return TRUE;
}

static gboolean nsgtk_window_button_press_event(GtkWidget *widget,
					 GdkEventButton *event, gpointer data)
{
	struct gui_window *g = data;

	gtk_widget_grab_focus(GTK_WIDGET(g->layout));
	gtk_widget_hide(GTK_WIDGET(nsgtk_scaffolding_history_window(
			g->scaffold)->window));

	g->mouse.pressed_x = event->x / g->bw->scale;
	g->mouse.pressed_y = event->y / g->bw->scale;

	switch (event->button) {
	case 1:	/* Left button, usually. Pass to core as BUTTON 1. */
		g->mouse.state = BROWSER_MOUSE_PRESS_1;
		break;

	case 2:	/* Middle button, usually. Pass to core as BUTTON 2 */
		g->mouse.state = BROWSER_MOUSE_PRESS_2;
		break;

	case 3:	/* Right button, usually. Action button, context menu. */
		browser_window_remove_caret(g->bw);
		nsgtk_scaffolding_popup_menu(g->scaffold, g->mouse.pressed_x,
				g->mouse.pressed_y);
		return TRUE;

	default:
		return FALSE;
	}

	/* Handle the modifiers too */
	if (event->state & GDK_SHIFT_MASK)
		g->mouse.state |= BROWSER_MOUSE_MOD_1;
	if (event->state & GDK_CONTROL_MASK)
		g->mouse.state |= BROWSER_MOUSE_MOD_2;

	/* Record where we pressed, for use when determining whether to start
	 * a drag in motion notify events. */
	g->last_x = event->x;
	g->last_y = event->y;

	browser_window_mouse_click(g->bw, g->mouse.state, g->mouse.pressed_x,
			g->mouse.pressed_y);

	return TRUE;
}

static gboolean nsgtk_window_button_release_event(GtkWidget *widget,
					 GdkEventButton *event, gpointer data)
{
	struct gui_window *g = data;
	bool shift = event->state & GDK_SHIFT_MASK;
	bool ctrl = event->state & GDK_CONTROL_MASK;

	/* If the mouse state is PRESS then we are waiting for a release to emit
	 * a click event, otherwise just reset the state to nothing */
	if (g->mouse.state & BROWSER_MOUSE_PRESS_1)
		g->mouse.state ^= (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_CLICK_1);
	else if (g->mouse.state & BROWSER_MOUSE_PRESS_2)
		g->mouse.state ^= (BROWSER_MOUSE_PRESS_2 | BROWSER_MOUSE_CLICK_2);

	/* Handle modifiers being removed */
	if (g->mouse.state & BROWSER_MOUSE_MOD_1 && !shift)
		g->mouse.state ^= BROWSER_MOUSE_MOD_1;
	if (g->mouse.state & BROWSER_MOUSE_MOD_2 && !ctrl)
		g->mouse.state ^= BROWSER_MOUSE_MOD_2;

	if (g->mouse.state & (BROWSER_MOUSE_CLICK_1|BROWSER_MOUSE_CLICK_2)) {
		browser_window_mouse_click(g->bw, g->mouse.state,
				event->x / g->bw->scale,
				event->y / g->bw->scale);
	} else {
		browser_window_mouse_track(g->bw, 0, event->x / g->bw->scale,
				event->y / g->bw->scale);
	}

	g->mouse.state = 0;
	return TRUE;
}

static gboolean nsgtk_window_scroll_event(GtkWidget *widget,
				GdkEventScroll *event, gpointer data)
{
	struct gui_window *g = data;
	double value;
	GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(g->layout);
	GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(g->layout);
	GtkAllocation alloc;

	LOG(("%d", event->direction));
	switch (event->direction) {
	case GDK_SCROLL_LEFT:
		if (browser_window_scroll_at_point(g->bw,
				event->x / g->bw->scale,
				event->y / g->bw->scale,
				-100, 0) != true) {
			/* core did not handle event do horizontal scroll */

			value = gtk_adjustment_get_value(hscroll) -
				(nsgtk_adjustment_get_step_increment(hscroll) *2);

			if (value < nsgtk_adjustment_get_lower(hscroll)) {
				value = nsgtk_adjustment_get_lower(hscroll);
			}

			gtk_adjustment_set_value(hscroll, value);
		}
		break;

	case GDK_SCROLL_UP:
		if (browser_window_scroll_at_point(g->bw,
				event->x / g->bw->scale,
				event->y / g->bw->scale,
				0, -100) != true) {
			/* core did not handle event change vertical
			 * adjustment. 
			 */

			value = gtk_adjustment_get_value(vscroll) -
				(nsgtk_adjustment_get_step_increment(vscroll) * 2);

			if (value < nsgtk_adjustment_get_lower(vscroll)) {
				value = nsgtk_adjustment_get_lower(vscroll);
			}

			gtk_adjustment_set_value(vscroll, value);
		}
		break;

	case GDK_SCROLL_RIGHT:
		if (browser_window_scroll_at_point(g->bw,
				event->x / g->bw->scale,
				event->y / g->bw->scale,
				100, 0) != true) {

			/* core did not handle event change horizontal
			 * adjustment. 
			 */

			value = gtk_adjustment_get_value(hscroll) +
				(nsgtk_adjustment_get_step_increment(hscroll) * 2);

			/* @todo consider gtk_widget_get_allocated_width() */
			nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);

			if (value > nsgtk_adjustment_get_upper(hscroll) - alloc.width) {
				value = nsgtk_adjustment_get_upper(hscroll) - 
					alloc.width;
			}

			gtk_adjustment_set_value(hscroll, value);
		}
		break;

	case GDK_SCROLL_DOWN:
		if (browser_window_scroll_at_point(g->bw,
				event->x / g->bw->scale,
				event->y / g->bw->scale,
				0, 100) != true) {
			/* core did not handle event change vertical
			 * adjustment. 
			 */

			value = gtk_adjustment_get_value(vscroll) +
				(nsgtk_adjustment_get_step_increment(vscroll) * 2);
			/* @todo consider gtk_widget_get_allocated_height */
			nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);

			if (value > nsgtk_adjustment_get_upper(vscroll) - alloc.height) {
				value = nsgtk_adjustment_get_upper(vscroll) - 
					alloc.height;
			}

			gtk_adjustment_set_value(vscroll, value);
		}
		break;

	default:
		break;
	}

	return TRUE;
}

static gboolean nsgtk_window_keypress_event(GtkWidget *widget,
				GdkEventKey *event, gpointer data)
{
	struct gui_window *g = data;
	uint32_t nskey = gtk_gui_gdkkey_to_nskey(event);

	if (browser_window_key_press(g->bw, nskey))
		return TRUE;

	if ((event->state & 0x7) != 0) 
		return TRUE;

	double value;
	GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(g->layout);
	GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(g->layout);
	GtkAllocation alloc;

	/* @todo consider gtk_widget_get_allocated_width() */
	nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);

	switch (event->keyval) {

	case GDK_KEY(Home):
	case GDK_KEY(KP_Home):
		value = nsgtk_adjustment_get_lower(vscroll);
		gtk_adjustment_set_value(vscroll, value);
		break;

	case GDK_KEY(End):
	case GDK_KEY(KP_End):
		value = nsgtk_adjustment_get_upper(vscroll) - alloc.height;

		if (value < nsgtk_adjustment_get_lower(vscroll))
			value = nsgtk_adjustment_get_lower(vscroll);

		gtk_adjustment_set_value(vscroll, value);
		break;

	case GDK_KEY(Left):
	case GDK_KEY(KP_Left):
		value = gtk_adjustment_get_value(hscroll) -
			nsgtk_adjustment_get_step_increment(hscroll);

		if (value < nsgtk_adjustment_get_lower(hscroll))
			value = nsgtk_adjustment_get_lower(hscroll);

		gtk_adjustment_set_value(hscroll, value);
		break;

	case GDK_KEY(Up):
	case GDK_KEY(KP_Up):
		value = gtk_adjustment_get_value(vscroll) -
			nsgtk_adjustment_get_step_increment(vscroll);

		if (value < nsgtk_adjustment_get_lower(vscroll))
			value = nsgtk_adjustment_get_lower(vscroll);

		gtk_adjustment_set_value(vscroll, value);
		break;

	case GDK_KEY(Right):
	case GDK_KEY(KP_Right):
		value = gtk_adjustment_get_value(hscroll) +
			nsgtk_adjustment_get_step_increment(hscroll);

		if (value > nsgtk_adjustment_get_upper(hscroll) - alloc.width)
			value = nsgtk_adjustment_get_upper(hscroll) - alloc.width;

		gtk_adjustment_set_value(hscroll, value);
		break;

	case GDK_KEY(Down):
	case GDK_KEY(KP_Down):
		value = gtk_adjustment_get_value(vscroll) +
			nsgtk_adjustment_get_step_increment(vscroll);

		if (value > nsgtk_adjustment_get_upper(vscroll) - alloc.height)
			value = nsgtk_adjustment_get_upper(vscroll) - alloc.height;

		gtk_adjustment_set_value(vscroll, value);
		break;

	case GDK_KEY(Page_Up):
	case GDK_KEY(KP_Page_Up):
		value = gtk_adjustment_get_value(vscroll) -
			nsgtk_adjustment_get_page_increment(vscroll);

		if (value < nsgtk_adjustment_get_lower(vscroll))
			value = nsgtk_adjustment_get_lower(vscroll);

		gtk_adjustment_set_value(vscroll, value);
		break;

	case GDK_KEY(Page_Down):
	case GDK_KEY(KP_Page_Down):
		value = gtk_adjustment_get_value(vscroll) +
			nsgtk_adjustment_get_page_increment(vscroll);

		if (value > nsgtk_adjustment_get_upper(vscroll) - alloc.height)
			value = nsgtk_adjustment_get_upper(vscroll) - alloc.height;

		gtk_adjustment_set_value(vscroll, value);
		break;

	default:
		break;

	}

	return TRUE;
}

static gboolean nsgtk_window_size_allocate_event(GtkWidget *widget,
		GtkAllocation *allocation, gpointer data)
{
	struct gui_window *g = data;

	g->bw->reformat_pending = true;
	browser_reformat_pending = true;

	if (g->paned != NULL) {
		/* Set status bar / scroll bar proportion according to
		 * option_toolbar_status_width */
		/* TODO: Probably want to detect when the user adjusts the
		 *       status bar width, remember that proportion for the
		 *       window, and use that here. */
		gtk_paned_set_position(g->paned, 
				       (nsoption_int(toolbar_status_width) *
					allocation->width) / 10000);
	}

	return TRUE;
}

/* Core interface docuemnted in desktop/gui.h to create a gui_window */
struct gui_window *gui_create_browser_window(struct browser_window *bw,
					     struct browser_window *clone,
					     bool new_tab)
{
	struct gui_window *g; /**< what we're creating to return */

	g = calloc(1, sizeof(*g));
	if (!g) {
		warn_user("NoMemory", 0);
		return 0;
	}

	LOG(("Creating gui window %p for browser window %p", g, bw));

	g->bw = bw;
	g->paned = NULL;
	g->mouse.state = 0;
	g->current_pointer = GUI_POINTER_DEFAULT;
	if (clone != NULL) {
		bw->scale = clone->scale;
	} else {
		bw->scale = (float) nsoption_int(scale) / 100.0;
	}

	g->careth = 0;

	if (new_tab) {
		assert(clone != NULL);
		g->scaffold = clone->window->scaffold;
	} else {
		/* Now construct and attach a scaffold */
		g->scaffold = nsgtk_new_scaffolding(g);
	}

	if (g->scaffold == NULL) {
		warn_user("NoMemory", 0);
		free(g);
		return NULL;
	}

	/* Construct our primary elements */

	/* top-level document (not a frame) => create a new tab */
	GError* error = NULL;
	GtkBuilder* xml = gtk_builder_new();
	if (!gtk_builder_add_from_file(xml, 
				       glade_file_location->tabcontents, 
				       &error)) {
		g_warning ("Couldn't load builder file: %s", error->message);
		g_error_free(error);
		return 0;
	}

	g->layout = GTK_LAYOUT(gtk_builder_get_object(xml, "layout"));
	g->status_bar = GTK_LABEL(gtk_builder_get_object(xml, "status_bar"));
	g->paned = GTK_PANED(gtk_builder_get_object(xml, "hpaned1"));

	/* connect the scrollbars to the layout widget */
	nsgtk_layout_set_hadjustment(g->layout,
			gtk_range_get_adjustment(GTK_RANGE(
			gtk_builder_get_object(xml, "hscrollbar"))));
	nsgtk_layout_set_vadjustment(g->layout,
			gtk_range_get_adjustment(GTK_RANGE(
			gtk_builder_get_object(xml, "vscrollbar"))));

	/* add the tab to the scaffold */
	bool tempback = true;
	switch (temp_open_background) {
	case -1:
		tempback = !(nsoption_bool(focus_new));
		break;
	case 0:
		tempback = false;
		break;
	case 1:
		tempback = true;
		break;
	}

	GtkWidget *tab_contents = GTK_WIDGET(gtk_builder_get_object(xml, "tabContents"));
	g_object_set_data(G_OBJECT(tab_contents), "gui_window", g);
	nsgtk_tab_add(g, tab_contents, tempback);

	g_object_unref(xml);

	/* Attach ourselves to the list (push_top) */
	if (window_list)
		window_list->prev = g;
	g->next = window_list;
	g->prev = NULL;
	window_list = g;

	/* set the events we're interested in receiving from the browser's
	 * drawing area.
	 */
	gtk_widget_add_events(GTK_WIDGET(g->layout),
				GDK_EXPOSURE_MASK |
				GDK_LEAVE_NOTIFY_MASK |
				GDK_BUTTON_PRESS_MASK |
				GDK_BUTTON_RELEASE_MASK |
				GDK_POINTER_MOTION_MASK |
				GDK_POINTER_MOTION_HINT_MASK |
				GDK_KEY_PRESS_MASK |
				GDK_KEY_RELEASE_MASK |
				GDK_SCROLL_MASK);
	nsgtk_widget_set_can_focus(GTK_WIDGET(g->layout), TRUE);

	/* set the default background colour of the drawing area to white. */
	nsgtk_widget_override_background_color(GTK_WIDGET(g->layout), 
					       GTK_STATE_NORMAL, 0, 0xffff, 0xffff, 0xffff);


	nsgtk_connect_draw_event(GTK_WIDGET(g->layout), G_CALLBACK(nsgtk_window_draw_event), g);

#define CONNECT(obj, sig, callback, ptr) \
	g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))

	CONNECT(g->layout, "motion_notify_event",
			nsgtk_window_motion_notify_event, g);
	g->signalhandler[NSGTK_WINDOW_SIGNAL_CLICK] =
			CONNECT(g->layout, "button_press_event",
			nsgtk_window_button_press_event, g);
	CONNECT(g->layout, "button_release_event",
			nsgtk_window_button_release_event, g);
	CONNECT(g->layout, "key_press_event",
			nsgtk_window_keypress_event, g);
	CONNECT(g->layout, "size_allocate",
			nsgtk_window_size_allocate_event, g);
	CONNECT(g->layout, "scroll_event",
			nsgtk_window_scroll_event, g);
	return g;
}



void nsgtk_reflow_all_windows(void)
{
	for (struct gui_window *g = window_list; g; g = g->next) {
		nsgtk_tab_options_changed(
				nsgtk_scaffolding_notebook(g->scaffold));
		g->bw->reformat_pending = true;
	}

	browser_reformat_pending = true;
}


/**
 * Process pending reformats
 */

void nsgtk_window_process_reformats(void)
{
	struct gui_window *g;
	GtkAllocation alloc;

	browser_reformat_pending = false;
	for (g = window_list; g; g = g->next) {
		if (!g->bw->reformat_pending)
			continue;

		g->bw->reformat_pending = false;

		/* @todo consider gtk_widget_get_allocated_width() */
		nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);

		browser_window_reformat(g->bw, false, alloc.width, alloc.height);
	}
}


void nsgtk_window_destroy_browser(struct gui_window *g)
{
	browser_window_destroy(g->bw);
}

void gui_window_destroy(struct gui_window *g)
{
	if (g->prev)
		g->prev->next = g->next;
	else
		window_list = g->next;

	if (g->next)
		g->next->prev = g->prev;


	LOG(("Destroying gui_window %p", g));
	assert(g != NULL);
	assert(g->bw != NULL);
	LOG(("	   Scaffolding: %p", g->scaffold));
	LOG(("	   Window name: %s", g->bw->name));

	/* tab => remove tab */
	gtk_widget_destroy(gtk_widget_get_parent(GTK_WIDGET(g->layout)));
}

/**
 * set favicon
 */
void gui_window_set_icon(struct gui_window *gw, hlcache_handle *icon)
{
	struct bitmap *icon_bitmap = NULL;

	/* free any existing icon */
	if (gw->icon != NULL) {
		g_object_unref(gw->icon);
		gw->icon = NULL;
	}

	if (icon != NULL) {
		icon_bitmap = content_get_bitmap(icon);
		if (icon_bitmap != NULL) {
			LOG(("Using %p bitmap", icon_bitmap));
			gw->icon = nsgdk_pixbuf_get_from_surface(icon_bitmap->surface, 16, 16);
		} 
	} 

	if (gw->icon == NULL) {
		LOG(("Using default favicon"));
		g_object_ref(favicon_pixbuf);
		gw->icon = favicon_pixbuf;
	}

	nsgtk_scaffolding_set_icon(gw);
}

static void nsgtk_redraw_caret(struct gui_window *g)
{
	int sx, sy;

	if (g->careth == 0)
		return;

	gui_window_get_scroll(g, &sx, &sy);

	gtk_widget_queue_draw_area(GTK_WIDGET(g->layout),
			g->caretx - sx, g->carety - sy, 1, g->careth + 1);

}
示例#29
0
/*
 * See Dw_gtk_viewport_scroll_to.
 */
static gint Dw_gtk_viewport_update_anchor_idle (gpointer data)
{
   gint32 vp_width, vp_height, x = 0, y = 0;
   GtkScrolledWindow *scrolled;
   GtkDwViewport *viewport;
   GtkWidget *vwidget;
   GtkAdjustment *vadj, *hadj;
   gboolean change_x, change_y;

   DBG_MSG (data, "scrolling", 0, "Dw_gtk_viewport_update_anchor_idle");
   DBG_MSG_START (data);

   vwidget = GTK_WIDGET (data);
   viewport = GTK_DW_VIEWPORT (vwidget);
   scrolled = GTK_SCROLLED_WINDOW (vwidget->parent->parent);
   hadj = GTK_LAYOUT(viewport)->hadjustment;
   vadj = GTK_LAYOUT(viewport)->vadjustment;

   vp_width =
      vwidget->allocation.width - GTK_CONTAINER(viewport)->border_width;
   vp_height =
      vwidget->allocation.height - GTK_CONTAINER(viewport)->border_width;
   DBG_MSGF (viewport, "scrolling", 0, "vp_width = %d", vp_width);
   DBG_MSGF (viewport, "scrolling", 0, "vp_height = %d", vp_height);

   change_x = TRUE;
   switch (viewport->anchor_pos.hpos) {
   case DW_HPOS_LEFT:
      DBG_MSG (viewport, "scrolling", 0, "DW_HPOS_LEFT");
      x = viewport->anchor_pos.x;
      break;
   case DW_HPOS_CENTER:
      DBG_MSG (viewport, "scrolling", 0, "DW_HPOS_CENTER");
      x = viewport->anchor_pos.x - (vp_width - viewport->anchor_pos.width) / 2;
      break;
   case DW_HPOS_RIGHT:
      DBG_MSG (viewport, "scrolling", 0, "DW_HPOS_RIGHT");
      x = viewport->anchor_pos.x - (vp_width - viewport->anchor_pos.width);
      break;
   case DW_HPOS_INTO_VIEW:
      DBG_MSG (viewport, "scrolling", 0, "DW_HPOS_INTO_VIEW");
      change_x = Dw_gtk_viewport_calc_into (viewport->anchor_pos.x,
                                            viewport->anchor_pos.width,
                                            hadj->value, vp_width, &x);
      break;
   case DW_HPOS_NO_CHANGE:
      DBG_MSG (viewport, "scrolling", 0, "DW_HPOS_NO_CHANGE");
      change_x = FALSE;
      break;
   }

   change_y = TRUE;
   switch (viewport->anchor_pos.vpos) {
   case DW_VPOS_TOP:
      DBG_MSG (viewport, "scrolling", 0, "DW_VPOS_TOP");
      y = viewport->anchor_pos.y;
      break;
   case DW_VPOS_CENTER:
      DBG_MSG (viewport, "scrolling", 0, "DW_VPOS_CENTER");
      y = viewport->anchor_pos.y -
         (vp_height - viewport->anchor_pos.height) / 2;
      break;
   case DW_VPOS_BOTTOM:
      DBG_MSG (viewport, "scrolling", 0, "DW_VPOS_BOTTOM");
      y = viewport->anchor_pos.y - (vp_height - viewport->anchor_pos.height);
      break;
   case DW_VPOS_INTO_VIEW:
      DBG_MSG (viewport, "scrolling", 0, "DW_VPOS_INTO_VIEW");
      change_y = Dw_gtk_viewport_calc_into (viewport->anchor_pos.y,
                                            viewport->anchor_pos.height,
                                            vadj->value, vp_height, &y);
   case DW_VPOS_NO_CHANGE:
      DBG_MSG (viewport, "scrolling", 0, "DW_VPOS_NO_CHANGE");
      change_y = FALSE;
      break;
   }

   DBG_MSGF (viewport, "scrolling", 0, "scrolling to (%d, %d)\n", x, y);
   DBG_MSGF (viewport, "scrolling", 0,
             "hadj->upper = %g, hadj->page_size = %g",
             hadj->upper, hadj->page_size);
   DBG_MSGF (viewport, "scrolling", 0,
             "vadj->upper = %g, vadj->page_size = %g",
             vadj->upper, vadj->page_size);

   if (change_x) {
      if (x > hadj->upper - hadj->page_size)
         gtk_adjustment_set_value (hadj, hadj->upper - hadj->page_size);
      else
         gtk_adjustment_set_value (hadj, x);
   }

   if (change_y) {
      if (y > vadj->upper - vadj->page_size)
         gtk_adjustment_set_value (vadj, vadj->upper - vadj->page_size);
      else
         gtk_adjustment_set_value (vadj, y);
   }

   viewport->anchor_idle_id = 0;

   DBG_MSG_END (viewport);
   return FALSE;
}
示例#30
0
static gboolean
e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
{
	EReflow *reflow;
	int return_val = FALSE;

	reflow = E_REFLOW (item);

	switch( event->type )
		{
		case GDK_KEY_PRESS:
			return_val = e_selection_model_key_press(reflow->selection, (GdkEventKey *) event);
			break;
#if 0
			if (event->key.keyval == GDK_Tab ||
			    event->key.keyval == GDK_KP_Tab ||
			    event->key.keyval == GDK_ISO_Left_Tab) {
				int i;
				int count;
				count = reflow->count;
				for (i = 0; i < count; i++) {
					int unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i);
					GnomeCanvasItem *item = reflow->items[unsorted];
					EFocus has_focus;
					if (item) {
						g_object_get(item,
							     "has_focus", &has_focus,
							     NULL);
						if (has_focus) {
							if (event->key.state & GDK_SHIFT_MASK) {
								if (i == 0)
									return FALSE;
								i--;
							} else {
								if (i == count - 1)
									return FALSE;
								i++;
							}

							unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i);
							if (reflow->items[unsorted] == NULL) {
								reflow->items[unsorted] = e_reflow_model_incarnate (reflow->model, unsorted, GNOME_CANVAS_GROUP (reflow));
							}

							item = reflow->items[unsorted];
							gnome_canvas_item_set(item,
									      "has_focus", (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START,
									      NULL);
							return TRUE;
						}
					}
				}
			}
#endif
		case GDK_BUTTON_PRESS:
			switch(event->button.button)
				{
				case 1:
					{
						GdkEventButton *button = (GdkEventButton *) event;
						double n_x, max_x;
						n_x = button->x;
						n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH;
						n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER));

						max_x = E_REFLOW_BORDER_WIDTH;
						max_x += (reflow->column_width + E_REFLOW_FULL_GUTTER) * reflow->column_count;
						if ( button->y >= E_REFLOW_BORDER_WIDTH && button->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER && max_x > button->x ) {
							/* don't allow to drag the first line*/
							if (e_reflow_pick_line(reflow, button->x) == 0)
								return TRUE;
							reflow->which_column_dragged = e_reflow_pick_line(reflow, button->x);
							reflow->start_x = reflow->which_column_dragged * (reflow->column_width + E_REFLOW_FULL_GUTTER) - E_REFLOW_DIVIDER_WIDTH / 2;
							reflow->temp_column_width = reflow->column_width;
							reflow->column_drag = TRUE;

							gnome_canvas_item_grab (item,
										GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
										reflow->arrow_cursor,
										button->time);

							reflow->previous_temp_column_width = -1;
							reflow->need_column_resize = TRUE;
							gnome_canvas_item_request_update(item);
							return TRUE;
						}
					}
					break;
				case 4:
					{
						GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas));
						gdouble new_value = adjustment->value;
						new_value -= adjustment->step_increment;
						gtk_adjustment_set_value(adjustment, new_value);
					}
					break;
				case 5:
					{
						GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas));
						gdouble new_value = adjustment->value;
						new_value += adjustment->step_increment;
						if ( new_value > adjustment->upper - adjustment->page_size )
							new_value = adjustment->upper - adjustment->page_size;
						gtk_adjustment_set_value(adjustment, new_value);
					}
					break;
				}
			break;
		case GDK_BUTTON_RELEASE:
			if (reflow->column_drag) {
				gdouble old_width = reflow->column_width;
				GdkEventButton *button = (GdkEventButton *) event;
				GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas));
				reflow->temp_column_width = reflow->column_width +
					(button->x - reflow->start_x)/(reflow->which_column_dragged - e_reflow_pick_line(reflow, adjustment->value));
				if ( reflow->temp_column_width < 50 )
					reflow->temp_column_width = 50;
				reflow->column_drag = FALSE;
				if ( old_width != reflow->temp_column_width ) {
					gtk_adjustment_set_value(adjustment, adjustment->value + e_reflow_pick_line(reflow, adjustment->value) * (reflow->temp_column_width - reflow->column_width));
					reflow->column_width = reflow->temp_column_width;
					adjustment->step_increment = (reflow->column_width + E_REFLOW_FULL_GUTTER) / 2;
					adjustment->page_increment = adjustment->page_size - adjustment->step_increment;
					gtk_adjustment_changed(adjustment);
					e_reflow_resize_children(item);
					e_canvas_item_request_reflow(item);
					gnome_canvas_request_redraw(item->canvas, 0, 0, reflow->width, reflow->height);
					column_width_changed (reflow);
				}
				reflow->need_column_resize = TRUE;
				gnome_canvas_item_request_update(item);
				gnome_canvas_item_ungrab (item, button->time);
				return TRUE;
			}
			break;
		case GDK_MOTION_NOTIFY:
			if (reflow->column_drag) {
				double old_width = reflow->temp_column_width;
				GdkEventMotion *motion = (GdkEventMotion *) event;
				GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas));
				reflow->temp_column_width = reflow->column_width +
					(motion->x - reflow->start_x)/(reflow->which_column_dragged - e_reflow_pick_line(reflow, adjustment->value));
				if (reflow->temp_column_width < 50)
					reflow->temp_column_width = 50;
				if (old_width != reflow->temp_column_width) {
					reflow->need_column_resize = TRUE;
					gnome_canvas_item_request_update(item);
				}
				return TRUE;
			} else {
				GdkEventMotion *motion = (GdkEventMotion *) event;
				double n_x, max_x;

				n_x = motion->x;
				n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH;
				n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER));

				max_x = E_REFLOW_BORDER_WIDTH;
				max_x += (reflow->column_width + E_REFLOW_FULL_GUTTER) * reflow->column_count;

				if ( motion->y >= E_REFLOW_BORDER_WIDTH && motion->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER && max_x > motion->x) {
					if ( reflow->default_cursor_shown ) {
						gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->arrow_cursor);
						reflow->default_cursor_shown = FALSE;
					}
				} else
					if ( ! reflow->default_cursor_shown ) {
						gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->default_cursor);
						reflow->default_cursor_shown = TRUE;
					}

			}
			break;
		case GDK_ENTER_NOTIFY:
			if (!reflow->column_drag) {
				GdkEventCrossing *crossing = (GdkEventCrossing *) event;
				double n_x, max_x;
				n_x = crossing->x;
				n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH;
				n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER));

				max_x = E_REFLOW_BORDER_WIDTH;
				max_x += (reflow->column_width + E_REFLOW_FULL_GUTTER) * reflow->column_count;
				if ( crossing->y >= E_REFLOW_BORDER_WIDTH && crossing->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER && max_x > crossing->x) {
					if ( reflow->default_cursor_shown ) {
						gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->arrow_cursor);
						reflow->default_cursor_shown = FALSE;
					}
				}
			}
			break;
		case GDK_LEAVE_NOTIFY:
			if (!reflow->column_drag) {
				GdkEventCrossing *crossing = (GdkEventCrossing *) event;
				double n_x;
				n_x = crossing->x;
				n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH;
				n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER));
				if ( !( crossing->y >= E_REFLOW_BORDER_WIDTH && crossing->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER ) ) {
					if ( ! reflow->default_cursor_shown ) {
						gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->default_cursor);
						reflow->default_cursor_shown = TRUE;
					}
				}
			}
			break;
		default:
			break;
		}
	if (return_val)
		return return_val;
	else if (GNOME_CANVAS_ITEM_CLASS( e_reflow_parent_class )->event)
		return (* GNOME_CANVAS_ITEM_CLASS( e_reflow_parent_class )->event) (item, event);
	else
		return FALSE;
}