]> icculus.org git repositories - divverent/netradiant.git/blob - libs/gtkutil/window.cpp
correctly support [ and ] keys
[divverent/netradiant.git] / libs / gtkutil / window.cpp
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
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 #include "window.h"
23
24 #include <gtk/gtkscrolledwindow.h>
25
26 #include "pointer.h"
27 #include "accelerator.h"
28
29 inline void CHECK_RESTORE(GtkWidget* w)
30 {
31   if(gpointer_to_int(g_object_get_data(G_OBJECT(w), "was_mapped")) != 0)
32   {
33     gtk_widget_show(w);
34   }
35 }
36
37 inline void CHECK_MINIMIZE(GtkWidget* w)
38 {
39   g_object_set_data(G_OBJECT(w), "was_mapped", gint_to_pointer(GTK_WIDGET_VISIBLE(w)));
40   gtk_widget_hide(w);
41 }
42
43 static gboolean main_window_iconified(GtkWidget* widget, GdkEventWindowState* event, gpointer data)
44 {
45   if((event->changed_mask & (GDK_WINDOW_STATE_ICONIFIED|GDK_WINDOW_STATE_WITHDRAWN)) != 0)
46   {
47     if((event->new_window_state & (GDK_WINDOW_STATE_ICONIFIED|GDK_WINDOW_STATE_WITHDRAWN)) != 0)
48     {
49       CHECK_MINIMIZE(GTK_WIDGET(data));
50     }
51     else
52     {
53       CHECK_RESTORE(GTK_WIDGET(data));
54     }
55   }
56   return FALSE;
57 }
58
59 unsigned int connect_floating(GtkWindow* main_window, GtkWindow* floating)
60 {
61   return g_signal_connect(G_OBJECT(main_window), "window_state_event", G_CALLBACK(main_window_iconified), floating);
62 }
63
64 gboolean destroy_disconnect_floating(GtkWindow* widget, gpointer data)
65 {
66   g_signal_handler_disconnect(G_OBJECT(data), gpointer_to_int(g_object_get_data(G_OBJECT(widget), "floating_handler")));
67   return FALSE;
68 }
69
70 gboolean floating_window_delete_present(GtkWindow* floating, GdkEventFocus *event, GtkWindow* main_window)
71 {
72   if(gtk_window_is_active(floating) || gtk_window_is_active(main_window))
73   {
74     gtk_window_present(main_window);
75   }
76   return FALSE;
77 }
78
79 guint connect_floating_window_delete_present(GtkWindow* floating, GtkWindow* main_window)
80 {
81   return g_signal_connect(G_OBJECT(floating), "delete_event", G_CALLBACK(floating_window_delete_present), main_window);
82 }
83
84 gboolean floating_window_destroy_present(GtkWindow* floating, GtkWindow* main_window)
85 {
86   if(gtk_window_is_active(floating) || gtk_window_is_active(main_window))
87   {
88     gtk_window_present(main_window);
89   }
90   return FALSE;
91 }
92
93 guint connect_floating_window_destroy_present(GtkWindow* floating, GtkWindow* main_window)
94 {
95   return g_signal_connect(G_OBJECT(floating), "destroy", G_CALLBACK(floating_window_destroy_present), main_window);
96 }
97
98 GtkWindow* create_floating_window(const char* title, GtkWindow* parent)
99 {
100   GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
101   gtk_window_set_title(window, title);
102
103   if(parent != 0)
104   {
105     gtk_window_set_transient_for(window, parent);
106     connect_floating_window_destroy_present(window, parent);
107     g_object_set_data(G_OBJECT(window), "floating_handler", gint_to_pointer(connect_floating(parent, window)));
108     g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy_disconnect_floating), parent);
109   }
110
111   return window;
112 }
113
114 void destroy_floating_window(GtkWindow* window)
115 {
116   gtk_widget_destroy(GTK_WIDGET(window));
117 }
118
119 gint window_realize_remove_sysmenu(GtkWidget* widget, gpointer data)
120 {
121   gdk_window_set_decorations(widget->window, (GdkWMDecoration)(GDK_DECOR_ALL|GDK_DECOR_MENU));
122   return FALSE;
123 }
124
125 gboolean persistent_floating_window_delete(GtkWindow* floating, GdkEvent *event, GtkWindow* main_window)
126 {
127   gtk_widget_hide(GTK_WIDGET(floating));
128   return TRUE;
129 }
130
131 GtkWindow* create_persistent_floating_window(const char* title, GtkWindow* main_window)
132 {
133   GtkWindow* window = GTK_WINDOW(create_floating_window(title, main_window));
134
135   gtk_widget_set_events(GTK_WIDGET(window), GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
136
137   connect_floating_window_delete_present(window, main_window);
138   g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(persistent_floating_window_delete), 0);
139
140 #if 0
141   if(g_multimon_globals.m_bStartOnPrimMon && g_multimon_globals.m_bNoSysMenuPopups)
142     g_signal_connect(G_OBJECT(window), "realize", G_CALLBACK(window_realize_remove_sysmenu), 0);
143 #endif
144
145   return window;
146 }
147
148 gint window_realize_remove_minmax(GtkWidget* widget, gpointer data)
149 {
150   gdk_window_set_decorations(widget->window, (GdkWMDecoration)(GDK_DECOR_ALL|GDK_DECOR_MINIMIZE|GDK_DECOR_MAXIMIZE));
151   return FALSE;
152 }
153
154 void window_remove_minmax(GtkWindow* window)
155 {
156   g_signal_connect(G_OBJECT(window), "realize", G_CALLBACK(window_realize_remove_minmax), 0);
157 }
158
159
160 GtkScrolledWindow* create_scrolled_window(GtkPolicyType hscrollbar_policy, GtkPolicyType vscrollbar_policy, int border)
161 {
162   GtkScrolledWindow* scr = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(0, 0));
163   gtk_widget_show(GTK_WIDGET(scr));
164   gtk_scrolled_window_set_policy(scr, hscrollbar_policy, vscrollbar_policy);
165   gtk_scrolled_window_set_shadow_type(scr, GTK_SHADOW_IN);
166   gtk_container_set_border_width(GTK_CONTAINER(scr), border);
167   return scr;
168 }
169
170