]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/groupdialog.cpp
reformat code! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / radiant / groupdialog.cpp
1 /*
2    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 //
23 // Floating dialog that contains a notebook with at least Entities and Group tabs
24 // I merged the 2 MS Windows dialogs in a single class
25 //
26 // Leonardo Zide (leo@lokigames.com)
27 //
28
29 #include "groupdialog.h"
30 #include "globaldefs.h"
31
32 #include "debugging/debugging.h"
33
34 #include <vector>
35 #include <gtk/gtk.h>
36
37 #include "gtkutil/widget.h"
38 #include "gtkutil/accelerator.h"
39 #include "entityinspector.h"
40 #include "gtkmisc.h"
41 #include "multimon.h"
42 #include "console.h"
43 #include "commands.h"
44
45
46 #include "gtkutil/window.h"
47
48 class GroupDlg {
49 public:
50     ui::Widget m_pNotebook{ui::null};
51     ui::Window m_window{ui::null};
52
53     GroupDlg();
54
55     void Create(ui::Window parent);
56
57     void Show()
58     {
59         // workaround for strange gtk behaviour - modifying the contents of a window while it is not visible causes the window position to change without sending a configure_event
60         m_position_tracker.sync(m_window);
61         m_window.show();
62     }
63
64     void Hide()
65     {
66         m_window.hide();
67     }
68
69     WindowPositionTracker m_position_tracker;
70 };
71
72 namespace {
73     GroupDlg g_GroupDlg;
74
75     std::size_t g_current_page;
76     std::vector<Callback<void(const Callback<void(const char *)> &)>> g_pages;
77 }
78
79 void GroupDialog_updatePageTitle(ui::Window window, std::size_t pageIndex)
80 {
81     if (pageIndex < g_pages.size()) {
82         g_pages[pageIndex](PointerCaller<GtkWindow, void(const char *), gtk_window_set_title>(window));
83     }
84 }
85
86 static gboolean switch_page(GtkNotebook *notebook, gpointer page, guint page_num, gpointer data)
87 {
88     GroupDialog_updatePageTitle(ui::Window::from(data), page_num);
89     g_current_page = page_num;
90
91     return FALSE;
92 }
93
94 GroupDlg::GroupDlg() : m_window(ui::null)
95 {
96     m_position_tracker.setPosition(c_default_window_pos);
97 }
98
99 void GroupDlg::Create(ui::Window parent)
100 {
101     ASSERT_MESSAGE(!m_window, "dialog already created");
102
103     auto window = ui::Window(create_persistent_floating_window("Entities", parent));
104
105     global_accel_connect_window(window);
106
107     window_connect_focus_in_clear_focus_widget(window);
108
109     m_window = window;
110
111 #if GDEF_OS_WINDOWS
112     if ( g_multimon_globals.m_bStartOnPrimMon ) {
113         WindowPosition pos( m_position_tracker.getPosition() );
114         PositionWindowOnPrimaryScreen( pos );
115         m_position_tracker.setPosition( pos );
116     }
117 #endif
118     m_position_tracker.connect(window);
119
120     {
121         ui::Widget notebook = ui::Widget::from(gtk_notebook_new());
122         notebook.show();
123         window.add(notebook);
124         gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_BOTTOM);
125         m_pNotebook = notebook;
126
127         notebook.connect("switch_page", G_CALLBACK(switch_page), (gpointer) window);
128     }
129 }
130
131
132 ui::Widget GroupDialog_addPage(const char *tabLabel, ui::Widget widget,
133                                const Callback<void(const Callback<void(const char *)> &)> &title)
134 {
135     ui::Widget w = ui::Label(tabLabel);
136     w.show();
137     auto page = ui::Widget::from(gtk_notebook_get_nth_page(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook),
138                                                            gtk_notebook_insert_page(
139                                                                    GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), widget, w,
140                                                                    -1)));
141     g_pages.push_back(title);
142
143     return page;
144 }
145
146
147 bool GroupDialog_isShown()
148 {
149     return g_GroupDlg.m_window.visible();
150 }
151
152 void GroupDialog_setShown(bool shown)
153 {
154     shown ? g_GroupDlg.Show() : g_GroupDlg.Hide();
155 }
156
157 void GroupDialog_ToggleShow()
158 {
159     GroupDialog_setShown(!GroupDialog_isShown());
160 }
161
162 void GroupDialog_constructWindow(ui::Window main_window)
163 {
164     g_GroupDlg.Create(main_window);
165 }
166
167 void GroupDialog_destroyWindow()
168 {
169     ASSERT_TRUE(g_GroupDlg.m_window);
170     destroy_floating_window(g_GroupDlg.m_window);
171     g_GroupDlg.m_window = ui::Window{ui::null};
172 }
173
174
175 ui::Window GroupDialog_getWindow()
176 {
177     return ui::Window(g_GroupDlg.m_window);
178 }
179
180 void GroupDialog_show()
181 {
182     g_GroupDlg.Show();
183 }
184
185 ui::Widget GroupDialog_getPage()
186 {
187     return ui::Widget::from(gtk_notebook_get_nth_page(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), gint(g_current_page)));
188 }
189
190 void GroupDialog_setPage(ui::Widget page)
191 {
192     g_current_page = gtk_notebook_page_num(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), page);
193     gtk_notebook_set_current_page(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), gint(g_current_page));
194 }
195
196 void GroupDialog_showPage(ui::Widget page)
197 {
198     if (GroupDialog_getPage() == page) {
199         GroupDialog_ToggleShow();
200     } else {
201         g_GroupDlg.m_window.show();
202         GroupDialog_setPage(page);
203     }
204 }
205
206 void GroupDialog_cycle()
207 {
208     g_current_page = (g_current_page + 1) % g_pages.size();
209     gtk_notebook_set_current_page(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), gint(g_current_page));
210 }
211
212 void GroupDialog_updatePageTitle(ui::Widget page)
213 {
214     if (GroupDialog_getPage() == page) {
215         GroupDialog_updatePageTitle(g_GroupDlg.m_window, g_current_page);
216     }
217 }
218
219
220 #include "preferencesystem.h"
221
222 void GroupDialog_Construct()
223 {
224     GlobalPreferenceSystem().registerPreference("EntityWnd", make_property<WindowPositionTracker_String>(
225             g_GroupDlg.m_position_tracker));
226
227     GlobalCommands_insert("ViewEntityInfo", makeCallbackF(GroupDialog_ToggleShow), Accelerator('N'));
228 }
229
230 void GroupDialog_Destroy()
231 {
232 }