+ui::Widget TextureBrowser_constructWindow(ui::Window toplevel)
+{
+ // The gl_widget and the tag assignment frame should be packed into a GtkVPaned with the slider
+ // position stored in local.pref. gtk_paned_get_position() and gtk_paned_set_position() don't
+ // seem to work in gtk 2.4 and the arrow buttons don't handle GTK_FILL, so here's another thing
+ // for the "once-the-gtk-libs-are-updated-TODO-list" :x
+
+ TextureBrowser_checkTagFile();
+ TextureBrowser_SetNotex();
+
+ GlobalShaderSystem().setActiveShadersChangedNotify(
+ ReferenceCaller<TextureBrowser, void(), TextureBrowser_activeShadersChanged>(g_TextureBrowser));
+
+ g_TextureBrowser.m_parent = toplevel;
+
+ auto table = ui::Table(3, 3, FALSE);
+ auto vbox = ui::VBox(FALSE, 0);
+ table.attach(vbox, {0, 1, 1, 3}, {GTK_FILL, GTK_FILL});
+ vbox.show();
+
+ ui::Widget menu_bar{ui::null};
+
+ { // menu bar
+ menu_bar = ui::Widget::from(gtk_menu_bar_new());
+ auto menu_view = ui::Menu(ui::New);
+ auto view_item = TextureBrowser_constructViewMenu(menu_view);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(view_item), menu_view);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), view_item);
+
+ auto menu_tools = ui::Menu(ui::New);
+ auto tools_item = TextureBrowser_constructToolsMenu(menu_tools);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(tools_item), menu_tools);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), tools_item);
+
+ table.attach(menu_bar, {0, 3, 0, 1}, {GTK_FILL, GTK_SHRINK});
+ menu_bar.show();
+ }
+ { // Texture TreeView
+ g_TextureBrowser.m_scr_win_tree = ui::ScrolledWindow(ui::New);
+ gtk_container_set_border_width(GTK_CONTAINER(g_TextureBrowser.m_scr_win_tree), 0);
+
+ // vertical only scrolling for treeview
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(g_TextureBrowser.m_scr_win_tree), GTK_POLICY_NEVER,
+ GTK_POLICY_ALWAYS);
+
+ g_TextureBrowser.m_scr_win_tree.show();
+
+ TextureBrowser_createTreeViewTree();
+
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(g_TextureBrowser.m_scr_win_tree),
+ g_TextureBrowser.m_treeViewTree);
+ g_TextureBrowser.m_treeViewTree.show();
+ }
+ { // gl_widget scrollbar
+ auto w = ui::Widget::from(gtk_vscrollbar_new(ui::Adjustment(0, 0, 0, 1, 1, 0)));
+ table.attach(w, {2, 3, 1, 2}, {GTK_SHRINK, GTK_FILL});
+ w.show();
+ g_TextureBrowser.m_texture_scroll = w;
+
+ auto vadjustment = ui::Adjustment::from(gtk_range_get_adjustment(GTK_RANGE(g_TextureBrowser.m_texture_scroll)));
+ vadjustment.connect("value_changed", G_CALLBACK(TextureBrowser_verticalScroll), &g_TextureBrowser);
+
+ g_TextureBrowser.m_texture_scroll.visible(g_TextureBrowser.m_showTextureScrollbar);
+ }
+ { // gl_widget
+ g_TextureBrowser.m_gl_widget = glwidget_new(FALSE);
+ g_object_ref(g_TextureBrowser.m_gl_widget._handle);
+
+ gtk_widget_set_events(g_TextureBrowser.m_gl_widget,
+ GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK);
+ gtk_widget_set_can_focus(g_TextureBrowser.m_gl_widget, true);
+
+ table.attach(g_TextureBrowser.m_gl_widget, {1, 2, 1, 2});
+ g_TextureBrowser.m_gl_widget.show();
+
+ g_TextureBrowser.m_sizeHandler = g_TextureBrowser.m_gl_widget.connect("size_allocate",
+ G_CALLBACK(TextureBrowser_size_allocate),
+ &g_TextureBrowser);
+ g_TextureBrowser.m_exposeHandler = g_TextureBrowser.m_gl_widget.on_render(G_CALLBACK(TextureBrowser_expose),
+ &g_TextureBrowser);
+
+ g_TextureBrowser.m_gl_widget.connect("button_press_event", G_CALLBACK(TextureBrowser_button_press),
+ &g_TextureBrowser);
+ g_TextureBrowser.m_gl_widget.connect("button_release_event", G_CALLBACK(TextureBrowser_button_release),
+ &g_TextureBrowser);
+ g_TextureBrowser.m_gl_widget.connect("motion_notify_event", G_CALLBACK(TextureBrowser_motion),
+ &g_TextureBrowser);
+ g_TextureBrowser.m_gl_widget.connect("scroll_event", G_CALLBACK(TextureBrowser_scroll), &g_TextureBrowser);
+ }
+
+ // tag stuff
+ if (g_TextureBrowser.m_tags) {
+ { // fill tag GtkListStore
+ g_TextureBrowser.m_all_tags_list = ui::ListStore::from(gtk_list_store_new(N_COLUMNS, G_TYPE_STRING));
+ auto sortable = GTK_TREE_SORTABLE(g_TextureBrowser.m_all_tags_list);
+ gtk_tree_sortable_set_sort_column_id(sortable, TAG_COLUMN, GTK_SORT_ASCENDING);
+
+ TagBuilder.GetAllTags(g_TextureBrowser.m_all_tags);
+ TextureBrowser_buildTagList();
+ }
+ { // tag menu bar
+ auto menu_tags = ui::Menu(ui::New);
+ auto tags_item = TextureBrowser_constructTagsMenu(menu_tags);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(tags_item), menu_tags);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), tags_item);
+ }
+ { // Tag TreeView
+ g_TextureBrowser.m_scr_win_tags = ui::ScrolledWindow(ui::New);
+ gtk_container_set_border_width(GTK_CONTAINER(g_TextureBrowser.m_scr_win_tags), 0);
+
+ // vertical only scrolling for treeview
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(g_TextureBrowser.m_scr_win_tags), GTK_POLICY_NEVER,
+ GTK_POLICY_ALWAYS);
+
+ TextureBrowser_createTreeViewTags();
+
+ auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags);
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
+
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(g_TextureBrowser.m_scr_win_tags),
+ g_TextureBrowser.m_treeViewTags);
+ g_TextureBrowser.m_treeViewTags.show();
+ }
+ { // Texture/Tag notebook
+ TextureBrowser_constructTagNotebook();
+ vbox.pack_start(g_TextureBrowser.m_tag_notebook, TRUE, TRUE, 0);
+ }
+ { // Tag search button
+ TextureBrowser_constructSearchButton();
+ vbox.pack_end(g_TextureBrowser.m_search_button, FALSE, FALSE, 0);
+ }
+ auto frame_table = ui::Table(3, 3, FALSE);
+ { // Tag frame
+
+ g_TextureBrowser.m_tag_frame = ui::Frame("Tag assignment");
+ gtk_frame_set_label_align(GTK_FRAME(g_TextureBrowser.m_tag_frame), 0.5, 0.5);
+ gtk_frame_set_shadow_type(GTK_FRAME(g_TextureBrowser.m_tag_frame), GTK_SHADOW_NONE);
+
+ table.attach(g_TextureBrowser.m_tag_frame, {1, 3, 2, 3}, {GTK_FILL, GTK_SHRINK});
+
+ frame_table.show();
+
+ g_TextureBrowser.m_tag_frame.add(frame_table);
+ }
+ { // assigned tag list
+ ui::Widget scrolled_win = ui::ScrolledWindow(ui::New);
+ gtk_container_set_border_width(GTK_CONTAINER(scrolled_win), 0);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+
+ g_TextureBrowser.m_assigned_store = ui::ListStore::from(gtk_list_store_new(N_COLUMNS, G_TYPE_STRING));
+
+ auto sortable = GTK_TREE_SORTABLE(g_TextureBrowser.m_assigned_store);
+ gtk_tree_sortable_set_sort_column_id(sortable, TAG_COLUMN, GTK_SORT_ASCENDING);
+
+ auto renderer = ui::CellRendererText(ui::New);
+
+ g_TextureBrowser.m_assigned_tree = ui::TreeView(
+ ui::TreeModel::from(g_TextureBrowser.m_assigned_store._handle));
+ g_TextureBrowser.m_assigned_store.unref();
+ g_TextureBrowser.m_assigned_tree.connect("row-activated", (GCallback) TextureBrowser_removeTags, NULL);
+ gtk_tree_view_set_headers_visible(g_TextureBrowser.m_assigned_tree, FALSE);
+
+ auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_assigned_tree);
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
+
+ auto column = ui::TreeViewColumn("", renderer, {{"text", TAG_COLUMN}});
+ gtk_tree_view_append_column(g_TextureBrowser.m_assigned_tree, column);
+ g_TextureBrowser.m_assigned_tree.show();
+
+ scrolled_win.show();
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_win), g_TextureBrowser.m_assigned_tree);
+
+ frame_table.attach(scrolled_win, {0, 1, 1, 3}, {GTK_FILL, GTK_FILL});
+ }
+ { // available tag list
+ ui::Widget scrolled_win = ui::ScrolledWindow(ui::New);
+ gtk_container_set_border_width(GTK_CONTAINER(scrolled_win), 0);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+
+ g_TextureBrowser.m_available_store = ui::ListStore::from(gtk_list_store_new(N_COLUMNS, G_TYPE_STRING));
+ auto sortable = GTK_TREE_SORTABLE(g_TextureBrowser.m_available_store);
+ gtk_tree_sortable_set_sort_column_id(sortable, TAG_COLUMN, GTK_SORT_ASCENDING);
+
+ auto renderer = ui::CellRendererText(ui::New);
+
+ g_TextureBrowser.m_available_tree = ui::TreeView(
+ ui::TreeModel::from(g_TextureBrowser.m_available_store._handle));
+ g_TextureBrowser.m_available_store.unref();
+ g_TextureBrowser.m_available_tree.connect("row-activated", (GCallback) TextureBrowser_assignTags, NULL);
+ gtk_tree_view_set_headers_visible(g_TextureBrowser.m_available_tree, FALSE);
+
+ auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree);
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
+
+ auto column = ui::TreeViewColumn("", renderer, {{"text", TAG_COLUMN}});
+ gtk_tree_view_append_column(g_TextureBrowser.m_available_tree, column);
+ g_TextureBrowser.m_available_tree.show();
+
+ scrolled_win.show();
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_win), g_TextureBrowser.m_available_tree);
+
+ frame_table.attach(scrolled_win, {2, 3, 1, 3}, {GTK_FILL, GTK_FILL});
+ }
+ { // tag arrow buttons
+ auto m_btn_left = ui::Button(ui::New);
+ auto m_btn_right = ui::Button(ui::New);
+ auto m_arrow_left = ui::Widget::from(gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_OUT));
+ auto m_arrow_right = ui::Widget::from(gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_OUT));
+ m_btn_left.add(m_arrow_left);
+ m_btn_right.add(m_arrow_right);
+
+ // workaround. the size of the tag frame depends of the requested size of the arrow buttons.
+ m_arrow_left.dimensions(-1, 68);
+ m_arrow_right.dimensions(-1, 68);
+
+ frame_table.attach(m_btn_left, {1, 2, 1, 2}, {GTK_SHRINK, GTK_EXPAND});
+ frame_table.attach(m_btn_right, {1, 2, 2, 3}, {GTK_SHRINK, GTK_EXPAND});
+
+ m_btn_left.connect("clicked", G_CALLBACK(TextureBrowser_assignTags), NULL);
+ m_btn_right.connect("clicked", G_CALLBACK(TextureBrowser_removeTags), NULL);
+
+ m_btn_left.show();
+ m_btn_right.show();
+ m_arrow_left.show();
+ m_arrow_right.show();
+ }
+ { // tag fram labels
+ ui::Widget m_lbl_assigned = ui::Label("Assigned");
+ ui::Widget m_lbl_unassigned = ui::Label("Available");
+
+ frame_table.attach(m_lbl_assigned, {0, 1, 0, 1}, {GTK_EXPAND, GTK_SHRINK});
+ frame_table.attach(m_lbl_unassigned, {2, 3, 0, 1}, {GTK_EXPAND, GTK_SHRINK});