]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/minifram.cpp
6769171a693a5ed8aef2f929d311324f3c07c230
[wxWidgets.git] / src / gtk / minifram.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/minifram.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #if wxUSE_MINIFRAME
14
15 #include "wx/minifram.h"
16
17 #ifndef WX_PRECOMP
18 #include "wx/dcscreen.h"
19 #endif
20
21 #include "gtk/gtk.h"
22 #include "wx/gtk/win_gtk.h"
23 #include "wx/gtk/private.h"
24
25 #include <gdk/gdk.h>
26 #include <gdk/gdkprivate.h>
27 #include <gdk/gdkx.h>
28
29 //-----------------------------------------------------------------------------
30 // data
31 //-----------------------------------------------------------------------------
32
33 extern bool g_blockEventsOnDrag;
34 extern bool g_blockEventsOnScroll;
35 extern GtkWidget *wxGetRootWindow();
36
37 //-----------------------------------------------------------------------------
38 // "expose_event" of m_mainWidget
39 //-----------------------------------------------------------------------------
40
41 extern "C" {
42 static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxMiniFrame *win )
43 {
44 if (g_isIdle) wxapp_install_idle_handler();
45
46 if (!win->m_hasVMT) return;
47 if (gdk_event->count > 0) return;
48
49 GtkPizza *pizza = GTK_PIZZA(widget);
50
51 gtk_paint_shadow (widget->style,
52 pizza->bin_window,
53 GTK_STATE_NORMAL,
54 GTK_SHADOW_OUT,
55 NULL, NULL, NULL, // FIXME: No clipping?
56 0, 0,
57 win->m_width, win->m_height);
58
59 int style = win->GetWindowStyle();
60
61 if (!win->GetTitle().empty() &&
62 ((style & wxCAPTION) ||
63 (style & wxTINY_CAPTION_HORIZ) ||
64 (style & wxTINY_CAPTION_VERT)))
65 {
66 wxClientDC dc(win);
67 dc.SetFont( *wxSMALL_FONT );
68 int height = dc.GetCharHeight();
69
70 GdkGC *gc = gdk_gc_new( pizza->bin_window );
71 gdk_gc_set_foreground( gc, &widget->style->bg[GTK_STATE_SELECTED] );
72 gdk_draw_rectangle( pizza->bin_window, gc, TRUE,
73 3,
74 3,
75 win->m_width - 7,
76 height+1 );
77 g_object_unref (gc);
78
79 // Hack alert
80 dc.m_window = pizza->bin_window;
81 dc.SetTextForeground( *wxWHITE );
82 dc.DrawText( win->GetTitle(), 6, 3 );
83
84 if (style & wxCLOSE_BOX)
85 dc.DrawBitmap( win->m_closeButton, win->m_width-19, 3, true );
86 }
87 }
88 }
89
90 //-----------------------------------------------------------------------------
91 // "button_press_event" of m_mainWidget
92 //-----------------------------------------------------------------------------
93
94 extern "C" {
95 static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
96 {
97 if (g_isIdle) wxapp_install_idle_handler();
98
99 if (!win->m_hasVMT) return FALSE;
100 if (g_blockEventsOnDrag) return TRUE;
101 if (g_blockEventsOnScroll) return TRUE;
102
103 if (win->m_isDragging) return TRUE;
104
105 GtkPizza *pizza = GTK_PIZZA(widget);
106 if (gdk_event->window != pizza->bin_window) return TRUE;
107
108 int y = (int)gdk_event->y;
109 int x = (int)gdk_event->x;
110
111 int style = win->GetWindowStyle();
112 if ((style & wxCLOSE_BOX) &&
113 ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT)))
114 {
115 if ((y > 3) && (y < 19) && (x > win->m_width-19) && (x < win->m_width-3))
116 {
117 win->Close();
118 return TRUE;
119 }
120 }
121
122 wxClientDC dc(win);
123 dc.SetFont( *wxSMALL_FONT );
124 int height = dc.GetCharHeight() + 1;
125
126
127 if (y > height) return TRUE;
128
129 gdk_window_raise( win->m_widget->window );
130
131 gdk_pointer_grab( widget->window, FALSE,
132 (GdkEventMask)
133 (GDK_BUTTON_PRESS_MASK |
134 GDK_BUTTON_RELEASE_MASK |
135 GDK_POINTER_MOTION_MASK |
136 GDK_POINTER_MOTION_HINT_MASK |
137 GDK_BUTTON_MOTION_MASK |
138 GDK_BUTTON1_MOTION_MASK),
139 (GdkWindow *) NULL,
140 (GdkCursor *) NULL,
141 (unsigned int) GDK_CURRENT_TIME );
142
143 win->m_diffX = x;
144 win->m_diffY = y;
145 win->m_oldX = 0;
146 win->m_oldY = 0;
147
148 win->m_isDragging = true;
149
150 return TRUE;
151 }
152 }
153
154 //-----------------------------------------------------------------------------
155 // "button_release_event" of m_mainWidget
156 //-----------------------------------------------------------------------------
157
158 extern "C" {
159 static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
160 {
161 if (g_isIdle) wxapp_install_idle_handler();
162
163 if (!win->m_hasVMT) return FALSE;
164 if (g_blockEventsOnDrag) return TRUE;
165 if (g_blockEventsOnScroll) return TRUE;
166
167 if (!win->m_isDragging) return TRUE;
168
169 win->m_isDragging = false;
170
171 int x = (int)gdk_event->x;
172 int y = (int)gdk_event->y;
173
174 gdk_pointer_ungrab ( (guint32)GDK_CURRENT_TIME );
175 int org_x = 0;
176 int org_y = 0;
177 gdk_window_get_origin( widget->window, &org_x, &org_y );
178 x += org_x - win->m_diffX;
179 y += org_y - win->m_diffY;
180 win->m_x = x;
181 win->m_y = y;
182 gtk_window_move( GTK_WINDOW(win->m_widget), x, y );
183
184 return TRUE;
185 }
186 }
187
188 //-----------------------------------------------------------------------------
189 // "motion_notify_event" of m_mainWidget
190 //-----------------------------------------------------------------------------
191
192 extern "C" {
193 static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxMiniFrame *win )
194 {
195 if (g_isIdle) wxapp_install_idle_handler();
196
197 if (!win->m_hasVMT) return FALSE;
198 if (g_blockEventsOnDrag) return TRUE;
199 if (g_blockEventsOnScroll) return TRUE;
200
201 if (!win->m_isDragging) return TRUE;
202
203 if (gdk_event->is_hint)
204 {
205 int x = 0;
206 int y = 0;
207 GdkModifierType state;
208 gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
209 gdk_event->x = x;
210 gdk_event->y = y;
211 gdk_event->state = state;
212 }
213
214 win->m_oldX = (int)gdk_event->x - win->m_diffX;
215 win->m_oldY = (int)gdk_event->y - win->m_diffY;
216
217 int x = (int)gdk_event->x;
218 int y = (int)gdk_event->y;
219
220 int org_x = 0;
221 int org_y = 0;
222 gdk_window_get_origin( widget->window, &org_x, &org_y );
223 x += org_x - win->m_diffX;
224 y += org_y - win->m_diffY;
225 win->m_x = x;
226 win->m_y = y;
227 gtk_window_move( GTK_WINDOW(win->m_widget), x, y );
228
229
230 return TRUE;
231 }
232 }
233
234 //-----------------------------------------------------------------------------
235 // wxMiniFrame
236 //-----------------------------------------------------------------------------
237
238 static unsigned char close_bits[]={
239 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
240 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
241 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
242
243
244 IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame,wxFrame)
245
246 bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title,
247 const wxPoint &pos, const wxSize &size,
248 long style, const wxString &name )
249 {
250 style = style | wxCAPTION;
251
252 if ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT))
253 m_miniTitle = 16;
254
255 m_miniEdge = 3;
256 m_isDragging = false;
257 m_oldX = -1;
258 m_oldY = -1;
259 m_diffX = 0;
260 m_diffY = 0;
261
262 wxFrame::Create( parent, id, title, pos, size, style, name );
263
264 if (m_parent && (GTK_IS_WINDOW(m_parent->m_widget)))
265 {
266 gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) );
267 }
268
269 if ((style & wxCLOSE_BOX) &&
270 ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT)))
271 {
272 wxImage img = wxBitmap((const char*)close_bits, 16, 16).ConvertToImage();
273 img.Replace(255,255,255,123,123,123);
274 img.Replace(0,0,0,255,255,255);
275 img.SetMaskColour(123,123,123);
276 m_closeButton = wxBitmap( img );
277 }
278
279 /* these are called when the borders are drawn */
280 g_signal_connect (m_mainWidget, "expose_event",
281 G_CALLBACK (gtk_window_own_expose_callback), this );
282
283 /* these are required for dragging the mini frame around */
284 g_signal_connect (m_mainWidget, "button_press_event",
285 G_CALLBACK (gtk_window_button_press_callback), this);
286 g_signal_connect (m_mainWidget, "button_release_event",
287 G_CALLBACK (gtk_window_button_release_callback), this);
288 g_signal_connect (m_mainWidget, "motion_notify_event",
289 G_CALLBACK (gtk_window_motion_notify_callback), this);
290
291 return true;
292 }
293
294 void wxMiniFrame::SetTitle( const wxString &title )
295 {
296 wxFrame::SetTitle( title );
297
298 gdk_window_invalidate_rect( GTK_PIZZA(m_mainWidget)->bin_window, NULL, true );
299 }
300
301 #endif // wxUSE_MINIFRAME