77
78
static void setup_tab_dnd(void);
80
static void focus_sci(GtkWidget *widget, gpointer user_data)
82
gint idx = document_get_cur_idx();
84
if (! DOC_IDX_VALID(idx)) return;
86
gtk_widget_grab_focus(GTK_WIDGET(doc_list[idx].sci));
81
static gboolean focus_sci(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
83
GeanyDocument *doc = document_get_current();
86
gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci));
92
static gboolean gtk_notebook_show_arrows(GtkNotebook *notebook)
94
return notebook->scrollable;
96
/* To get this working we would need to define at least the first two fields of
97
* GtkNotebookPage since it is a private field. The better way would be to
98
* subclass GtkNotebook.
99
struct _FakeGtkNotebookPage
102
GtkWidget *tab_label;
105
gboolean show_arrow = FALSE;
108
if (! notebook->scrollable)
111
children = notebook->children;
114
struct _FakeGtkNotebookPage *page = children->data;
116
if (page->tab_label && ! gtk_widget_get_child_visible(page->tab_label))
119
children = children->next;
126
static gboolean is_position_on_tab_bar(GtkNotebook *notebook, GdkEventButton *event)
131
GtkPositionType tab_pos;
132
gint scroll_arrow_hlength, scroll_arrow_vlength;
135
page = gtk_notebook_get_nth_page(notebook, 0);
136
g_return_val_if_fail(page != NULL, FALSE);
138
tab = gtk_notebook_get_tab_label(notebook, page);
139
g_return_val_if_fail(tab != NULL, FALSE);
141
tab_pos = gtk_notebook_get_tab_pos(notebook);
142
nb = GTK_WIDGET(notebook);
144
#if GTK_CHECK_VERSION(2, 10, 0)
145
gtk_widget_style_get(GTK_WIDGET(notebook), "scroll-arrow-hlength", &scroll_arrow_hlength,
146
"scroll-arrow-vlength", &scroll_arrow_vlength, NULL);
148
scroll_arrow_hlength = scroll_arrow_vlength = 16;
151
if (! gdk_event_get_coords((GdkEvent*) event, &x, &y))
162
if (event->y >= 0 && event->y <= tab->allocation.height)
164
if (! gtk_notebook_show_arrows(notebook) || (
165
x > scroll_arrow_hlength &&
166
x < nb->allocation.width - scroll_arrow_hlength))
174
if (event->x >= 0 && event->x <= tab->allocation.width)
176
if (! gtk_notebook_show_arrows(notebook) || (
177
y > scroll_arrow_vlength &&
178
y < nb->allocation.height - scroll_arrow_vlength))
188
static gboolean notebook_tab_bar_click_cb(GtkWidget *widget, GdkEventButton *event,
191
if (event->type == GDK_2BUTTON_PRESS)
193
/* accessing ::event_window is a little hacky but we need to make sure the click
194
* was in the tab bar and not inside the child */
195
if (event->window != GTK_NOTEBOOK(main_widgets.notebook)->event_window)
198
if (is_position_on_tab_bar(GTK_NOTEBOOK(widget), event))
200
document_new_file(NULL, NULL, NULL);
90
208
void notebook_init()
210
g_signal_connect_after(main_widgets.notebook, "button-press-event",
211
G_CALLBACK(notebook_tab_bar_click_cb), NULL);
92
213
/* focus the current document after clicking on a tab */
93
g_signal_connect_after(G_OBJECT(app->notebook), "button-release-event",
214
g_signal_connect_after(main_widgets.notebook, "button-release-event",
94
215
G_CALLBACK(focus_sci), NULL);
96
g_signal_connect(G_OBJECT(app->notebook), "drag-data-received",
217
g_signal_connect(main_widgets.notebook, "drag-data-received",
97
218
G_CALLBACK(on_window_drag_data_received), NULL);
112
233
if (gtk_check_version(2, 10, 0) == NULL) /* null means version ok */
114
235
#if GTK_CHECK_VERSION(2, 10, 0)
115
g_signal_connect(G_OBJECT(notebook), "page-reordered",
116
G_CALLBACK(notebook_page_reordered_cb), NULL);
236
g_signal_connect(notebook, "page-reordered", G_CALLBACK(notebook_page_reordered_cb), NULL);
121
241
/* Set up drag movement callback */
122
g_signal_connect(G_OBJECT(notebook), "drag-motion",
123
G_CALLBACK(notebook_drag_motion_cb), NULL);
242
g_signal_connect(notebook, "drag-motion", G_CALLBACK(notebook_drag_motion_cb), NULL);
125
244
/* There is a bug on GTK 2.6 with drag reordering of notebook tabs.
126
245
* Clicking (not dragging) on a notebook tab, then making a selection in the
263
382
/* subtract notebook pos to remove possible border padding */
264
max_x = tab->allocation.x + tab->allocation.width -
265
GTK_WIDGET(notebook)->allocation.x;
266
max_y = tab->allocation.y + tab->allocation.height -
267
GTK_WIDGET(notebook)->allocation.y;
383
max_x = tab->allocation.x + tab->allocation.width - GTK_WIDGET(notebook)->allocation.x;
384
max_y = tab->allocation.y + tab->allocation.height - GTK_WIDGET(notebook)->allocation.y;
269
if (((tab_pos == GTK_POS_TOP)
270
|| (tab_pos == GTK_POS_BOTTOM))
271
&&(x<=max_x)) return page_num;
272
else if (((tab_pos == GTK_POS_LEFT)
273
|| (tab_pos == GTK_POS_RIGHT))
274
&& (y<=max_y)) return page_num;
386
if (((tab_pos == GTK_POS_TOP) || (tab_pos == GTK_POS_BOTTOM)) && (x<=max_x))
388
else if (((tab_pos == GTK_POS_LEFT) || (tab_pos == GTK_POS_RIGHT)) && (y<=max_y))
282
/* call this after the number of tabs in app->notebook changes. */
397
/* call this after the number of tabs in main_widgets.notebook changes. */
283
398
static void tab_count_changed(void)
285
switch (gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)))
400
switch (gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)))
288
403
/* Enables DnD for dropping files into the empty notebook widget */
289
gtk_drag_dest_set(app->notebook, GTK_DEST_DEFAULT_ALL,
404
gtk_drag_dest_set(main_widgets.notebook, GTK_DEST_DEFAULT_ALL,
290
405
files_drop_targets, G_N_ELEMENTS(files_drop_targets),
291
406
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK);
295
410
/* Disables DnD for dropping files into the notebook widget and enables the DnD for moving file
296
411
* tabs. Files can still be dropped into the notebook widget because it will be handled by the
297
412
* active Scintilla Widget (only dropping to the tab bar is not possible but it should be ok) */
298
gtk_drag_dest_set(app->notebook, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
413
gtk_drag_dest_set(main_widgets.notebook, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
299
414
drag_targets, G_N_ELEMENTS(drag_targets), GDK_ACTION_MOVE);
304
gboolean notebook_tab_label_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
420
static gboolean notebook_tab_label_cb(GtkWidget *widget, GdkEventButton *event, gpointer data)
306
422
/* toggle additional widgets on double click */
307
423
if (event->type == GDK_2BUTTON_PRESS)
308
425
on_menu_toggle_all_additional_widgets1_activate(NULL, NULL);
426
return TRUE; /* stop other handlers like notebook_tab_bar_click_cb() */
309
428
/* close tab on middle click */
310
429
if (event->button == 2)
311
document_remove(gtk_notebook_page_num(GTK_NOTEBOOK(app->notebook), GTK_WIDGET(user_data)));
431
document_remove_page(gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook),
433
return TRUE; /* stop other handlers like notebook_tab_bar_click_cb() */
317
440
/* Returns page number of notebook page, or -1 on error */
318
gint notebook_new_tab(gint doc_idx)
441
gint notebook_new_tab(GeanyDocument *this)
320
443
GtkWidget *hbox, *ebox;
323
document *this = &(doc_list[doc_idx]);
326
g_return_val_if_fail(doc_idx >= 0 && this != NULL, -1);
328
page = GTK_WIDGET(this->sci);
329
title = g_path_get_basename(DOC_FILENAME(doc_idx));
331
this->tab_label = gtk_label_new(title);
448
g_return_val_if_fail(this != NULL, -1);
450
page = GTK_WIDGET(this->editor->sci);
451
title = g_path_get_basename(DOC_FILENAME(this));
453
this->priv->tab_label = gtk_label_new(title);
333
455
ebox = gtk_event_box_new();
334
456
GTK_WIDGET_SET_FLAGS(ebox, GTK_NO_WINDOW);
335
g_signal_connect(G_OBJECT(ebox), "button-press-event",
336
G_CALLBACK(notebook_tab_label_cb), page);
457
g_signal_connect(ebox, "button-press-event", G_CALLBACK(notebook_tab_label_cb), page);
338
459
hbox = gtk_hbox_new(FALSE, 2);
339
gtk_container_add(GTK_CONTAINER(ebox), this->tab_label);
460
gtk_container_add(GTK_CONTAINER(ebox), this->priv->tab_label);
340
461
gtk_box_pack_start(GTK_BOX(hbox), ebox, FALSE, FALSE, 0);
342
if (prefs.show_tab_cross)
463
if (file_prefs.show_tab_cross)
344
465
GtkWidget *image, *btn, *align;
345
466
GtkRcStyle *rcstyle;
368
489
gtk_box_pack_start(GTK_BOX(hbox), align, TRUE, TRUE, 0);
370
g_signal_connect(G_OBJECT(btn), "clicked",
371
G_CALLBACK(notebook_tab_close_clicked_cb), page);
491
g_signal_connect(btn, "clicked", G_CALLBACK(notebook_tab_close_clicked_cb), page);
374
494
gtk_widget_show_all(hbox);
376
this->tabmenu_label = gtk_label_new(title);
377
gtk_misc_set_alignment(GTK_MISC(this->tabmenu_label), 0.0, 0);
496
this->priv->tabmenu_label = gtk_label_new(title);
497
gtk_misc_set_alignment(GTK_MISC(this->priv->tabmenu_label), 0.0, 0);
379
if (prefs.tab_order_ltr)
380
tabnum = gtk_notebook_append_page_menu(GTK_NOTEBOOK(app->notebook), page,
381
hbox, this->tabmenu_label);
499
if (file_prefs.tab_order_ltr)
500
tabnum = gtk_notebook_append_page_menu(GTK_NOTEBOOK(main_widgets.notebook), page,
501
hbox, this->priv->tabmenu_label);
383
tabnum = gtk_notebook_insert_page_menu(GTK_NOTEBOOK(app->notebook), page,
384
hbox, this->tabmenu_label, 0);
503
tabnum = gtk_notebook_insert_page_menu(GTK_NOTEBOOK(main_widgets.notebook), page,
504
hbox, this->priv->tabmenu_label, 0);
386
506
tab_count_changed();
401
521
notebook_tab_close_clicked_cb(GtkButton *button, gpointer user_data)
403
gint cur_page = gtk_notebook_page_num(GTK_NOTEBOOK(app->notebook),
523
gint cur_page = gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook),
404
524
GTK_WIDGET(user_data));
405
document_remove(cur_page);
526
document_remove_page(cur_page);
409
530
/* Always use this instead of gtk_notebook_remove_page(). */
410
531
void notebook_remove_page(gint page_num)
412
gint curpage = gtk_notebook_get_current_page(GTK_NOTEBOOK(app->notebook));
533
gint curpage = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.notebook));
414
535
/* Focus the next page, not the previous */
415
if (curpage == page_num && prefs.tab_order_ltr)
536
if (curpage == page_num && file_prefs.tab_order_ltr)
417
gtk_notebook_set_current_page(GTK_NOTEBOOK(app->notebook), curpage + 1);
538
gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), curpage + 1);
420
541
/* now remove the page (so we don't temporarily switch to the previous page) */
421
gtk_notebook_remove_page(GTK_NOTEBOOK(app->notebook), page_num);
542
gtk_notebook_remove_page(GTK_NOTEBOOK(main_widgets.notebook), page_num);
423
544
tab_count_changed();