/* 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); }
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); }
/* * 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; }
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; }
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; }
/* * 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); } }
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); }
void ygtk_html_wrap_scroll (GtkWidget *widget, gboolean top) { ygutils_scrollAdj (GTK_LAYOUT (widget)->vadjustment, top); }
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); } }
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); }
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)); }
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); }
/* 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); }
/* 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; }
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; }
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); }
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; }
GtkLayout* cast_GtkLayout(GtkWidget* widget) { return GTK_LAYOUT(widget); }
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 ); }
static void gnc_header_realized (GtkWidget *widget, gpointer data) { gdk_window_set_back_pixmap (GTK_LAYOUT (widget)->bin_window, NULL, FALSE); }
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)); }
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); }
/* * (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); } }
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); }
/* * 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; }
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; }