]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/minifram.cpp
Warning fix.
[wxWidgets.git] / src / gtk / minifram.cpp
CommitLineData
b2b3ccc5 1/////////////////////////////////////////////////////////////////////////////
340bfb43 2// Name: src/gtk/minifram.cpp
b2b3ccc5
RR
3// Purpose:
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
65571936 7// Licence: wxWindows licence
b2b3ccc5
RR
8/////////////////////////////////////////////////////////////////////////////
9
14f355c2
VS
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
dcf924a3
RR
13#if wxUSE_MINIFRAME
14
11dbb4bf 15#include "wx/minifram.h"
6d976005 16#include "wx/settings.h"
11dbb4bf
WS
17
18#ifndef WX_PRECOMP
19 #include "wx/dcscreen.h"
20#endif
b2b3ccc5 21
83624f79
RR
22#include "gtk/gtk.h"
23#include "wx/gtk/win_gtk.h"
fab591c5 24#include "wx/gtk/private.h"
83624f79 25
5e7e9e1b
RR
26#include <gdk/gdk.h>
27#include <gdk/gdkprivate.h>
28#include <gdk/gdkx.h>
32a95f9f
RR
29
30//-----------------------------------------------------------------------------
31// data
32//-----------------------------------------------------------------------------
33
8480b297
RR
34extern bool g_blockEventsOnDrag;
35extern bool g_blockEventsOnScroll;
c2fa61e8 36extern GtkWidget *wxGetRootWindow();
32a95f9f 37
32a95f9f
RR
38//-----------------------------------------------------------------------------
39// "expose_event" of m_mainWidget
40//-----------------------------------------------------------------------------
41
6d976005
RR
42// StepColour() it a utility function that simply darkens
43// or lightens a color, based on the specified percentage
44static wxColor StepColour(const wxColor& c, int percent)
45{
46 int r = c.Red(), g = c.Green(), b = c.Blue();
47 return wxColour((unsigned char)wxMin((r*percent)/100,255),
48 (unsigned char)wxMin((g*percent)/100,255),
49 (unsigned char)wxMin((b*percent)/100,255));
50}
51
52static wxColor LightContrastColour(const wxColour& c)
53{
54 int amount = 120;
55
56 // if the color is especially dark, then
57 // make the contrast even lighter
58 if (c.Red() < 128 && c.Green() < 128 && c.Blue() < 128)
59 amount = 160;
60
61 return StepColour(c, amount);
62}
63
865bb325 64extern "C" {
00e4ffbc 65static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxMiniFrame *win )
32a95f9f 66{
acfd422a
RR
67 if (g_isIdle) wxapp_install_idle_handler();
68
a2053b27 69 if (!win->m_hasVMT) return;
32a95f9f 70 if (gdk_event->count > 0) return;
c2fa61e8 71
da048e3d 72 GtkPizza *pizza = GTK_PIZZA(widget);
c2fa61e8 73
67b73b9a
MR
74 gtk_paint_shadow (widget->style,
75 pizza->bin_window,
76 GTK_STATE_NORMAL,
77 GTK_SHADOW_OUT,
78 NULL, NULL, NULL, // FIXME: No clipping?
79 0, 0,
80 win->m_width, win->m_height);
b9a535f5 81
00e4ffbc
RR
82 int style = win->GetWindowStyle();
83
85a0a12a
RR
84 wxClientDC dc(win);
85 // Hack alert
86 dc.m_window = pizza->bin_window;
87
88 if (style & wxRESIZE_BORDER)
89 {
90 dc.SetBrush( *wxGREY_BRUSH );
91 dc.SetPen( *wxTRANSPARENT_PEN );
92 dc.DrawRectangle( win->m_width - 14, win->m_height-14, 14, 14 );
93 }
94
340bfb43 95 if (!win->GetTitle().empty() &&
00e4ffbc
RR
96 ((style & wxCAPTION) ||
97 (style & wxTINY_CAPTION_HORIZ) ||
98 (style & wxTINY_CAPTION_VERT)))
b9a535f5 99 {
ba718523
RR
100 dc.SetFont( *wxSMALL_FONT );
101 int height = dc.GetCharHeight();
340bfb43 102
6d976005
RR
103 wxBrush brush( LightContrastColour( wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT) ) );
104 dc.SetBrush( brush );
105 dc.SetPen( *wxTRANSPARENT_PEN );
106 dc.DrawRectangle( 3, 3, win->m_width - 7, height-2 );
ba718523 107
ba718523
RR
108 dc.SetTextForeground( *wxWHITE );
109 dc.DrawText( win->GetTitle(), 6, 3 );
00e4ffbc
RR
110
111 if (style & wxCLOSE_BOX)
112 dc.DrawBitmap( win->m_closeButton, win->m_width-19, 3, true );
b9a535f5 113 }
32a95f9f 114}
865bb325 115}
32a95f9f 116
32a95f9f
RR
117//-----------------------------------------------------------------------------
118// "button_press_event" of m_mainWidget
119//-----------------------------------------------------------------------------
120
865bb325 121extern "C" {
32a95f9f
RR
122static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
123{
acfd422a
RR
124 if (g_isIdle) wxapp_install_idle_handler();
125
a2053b27 126 if (!win->m_hasVMT) return FALSE;
32a95f9f
RR
127 if (g_blockEventsOnDrag) return TRUE;
128 if (g_blockEventsOnScroll) return TRUE;
129
130 if (win->m_isDragging) return TRUE;
131
2c990ec0
RR
132 GtkPizza *pizza = GTK_PIZZA(widget);
133 if (gdk_event->window != pizza->bin_window) return TRUE;
ba718523 134
85a0a12a
RR
135 int style = win->GetWindowStyle();
136
00e4ffbc
RR
137 int y = (int)gdk_event->y;
138 int x = (int)gdk_event->x;
85a0a12a
RR
139
140 if ((style & wxRESIZE_BORDER) &&
141 (x > win->m_width-14) && (y > win->m_height-14))
142 {
143 GtkWidget *ancestor = gtk_widget_get_toplevel( widget );
144
145 GdkWindow *source = GTK_PIZZA(widget)->bin_window;
146
147 int org_x = 0;
148 int org_y = 0;
149 gdk_window_get_origin( source, &org_x, &org_y );
150
151 gtk_window_begin_resize_drag (GTK_WINDOW (ancestor),
152 GDK_WINDOW_EDGE_SOUTH_EAST,
153 1,
154 org_x + x,
155 org_y + y,
156 0);
157
158 return TRUE;
159 }
00e4ffbc 160
00e4ffbc
RR
161 if ((style & wxCLOSE_BOX) &&
162 ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT)))
163 {
164 if ((y > 3) && (y < 19) && (x > win->m_width-19) && (x < win->m_width-3))
165 {
166 win->Close();
167 return TRUE;
168 }
169 }
170
ba718523
RR
171 wxClientDC dc(win);
172 dc.SetFont( *wxSMALL_FONT );
173 int height = dc.GetCharHeight() + 1;
340bfb43 174
00e4ffbc
RR
175
176 if (y > height) return TRUE;
340bfb43 177
4dcaf11a 178 gdk_window_raise( win->m_widget->window );
c2fa61e8 179
32a95f9f
RR
180 gdk_pointer_grab( widget->window, FALSE,
181 (GdkEventMask)
182 (GDK_BUTTON_PRESS_MASK |
183 GDK_BUTTON_RELEASE_MASK |
f03fc89f 184 GDK_POINTER_MOTION_MASK |
32a95f9f 185 GDK_POINTER_MOTION_HINT_MASK |
f03fc89f 186 GDK_BUTTON_MOTION_MASK |
32a95f9f
RR
187 GDK_BUTTON1_MOTION_MASK),
188 (GdkWindow *) NULL,
189 (GdkCursor *) NULL,
7941ba11 190 (unsigned int) GDK_CURRENT_TIME );
c2fa61e8 191
00e4ffbc
RR
192 win->m_diffX = x;
193 win->m_diffY = y;
32a95f9f
RR
194 win->m_oldX = 0;
195 win->m_oldY = 0;
c2fa61e8 196
340bfb43 197 win->m_isDragging = true;
32a95f9f
RR
198
199 return TRUE;
200}
865bb325 201}
32a95f9f
RR
202
203//-----------------------------------------------------------------------------
204// "button_release_event" of m_mainWidget
205//-----------------------------------------------------------------------------
206
865bb325 207extern "C" {
32a95f9f
RR
208static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
209{
acfd422a
RR
210 if (g_isIdle) wxapp_install_idle_handler();
211
a2053b27 212 if (!win->m_hasVMT) return FALSE;
32a95f9f
RR
213 if (g_blockEventsOnDrag) return TRUE;
214 if (g_blockEventsOnScroll) return TRUE;
215
216 if (!win->m_isDragging) return TRUE;
c2fa61e8 217
11dbb4bf 218 win->m_isDragging = false;
c2fa61e8 219
32a95f9f
RR
220 int x = (int)gdk_event->x;
221 int y = (int)gdk_event->y;
c2fa61e8 222
13111b2a 223 gdk_pointer_ungrab ( (guint32)GDK_CURRENT_TIME );
c2fa61e8 224 int org_x = 0;
32a95f9f
RR
225 int org_y = 0;
226 gdk_window_get_origin( widget->window, &org_x, &org_y );
227 x += org_x - win->m_diffX;
228 y += org_y - win->m_diffY;
121a3581
RR
229 win->m_x = x;
230 win->m_y = y;
9adb9063 231 gtk_window_move( GTK_WINDOW(win->m_widget), x, y );
32a95f9f
RR
232
233 return TRUE;
234}
865bb325 235}
32a95f9f 236
85a0a12a
RR
237//-----------------------------------------------------------------------------
238// "leave_notify_event" of m_mainWidget
239//-----------------------------------------------------------------------------
240
241extern "C" {
242static gboolean
243gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxMiniFrame *win )
244{
245 if (g_isIdle)
246 wxapp_install_idle_handler();
247
248 if (!win->m_hasVMT) return FALSE;
249 if (g_blockEventsOnDrag) return FALSE;
250
251 gdk_window_set_cursor( widget->window, NULL );
252
253 return FALSE;
254}
255}
256
32a95f9f
RR
257//-----------------------------------------------------------------------------
258// "motion_notify_event" of m_mainWidget
259//-----------------------------------------------------------------------------
260
865bb325 261extern "C" {
85a0a12a
RR
262static gint
263gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxMiniFrame *win )
32a95f9f 264{
85a0a12a
RR
265 if (g_isIdle)
266 wxapp_install_idle_handler();
acfd422a 267
a2053b27 268 if (!win->m_hasVMT) return FALSE;
32a95f9f
RR
269 if (g_blockEventsOnDrag) return TRUE;
270 if (g_blockEventsOnScroll) return TRUE;
271
32a95f9f
RR
272 if (gdk_event->is_hint)
273 {
274 int x = 0;
275 int y = 0;
276 GdkModifierType state;
277 gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
278 gdk_event->x = x;
279 gdk_event->y = y;
280 gdk_event->state = state;
281 }
282
85a0a12a
RR
283 int style = win->GetWindowStyle();
284
d02d8b4c
RR
285 int x = (int)gdk_event->x;
286 int y = (int)gdk_event->y;
287
85a0a12a
RR
288 if (!win->m_isDragging)
289 {
290 if (style & wxRESIZE_BORDER)
291 {
292 if ((x > win->m_width-14) && (y > win->m_height-14))
293 gdk_window_set_cursor( widget->window, gdk_cursor_new( GDK_BOTTOM_RIGHT_CORNER ) );
294 else
295 gdk_window_set_cursor( widget->window, NULL );
296 }
297 return TRUE;
298 }
299
300 win->m_oldX = x - win->m_diffX;
301 win->m_oldY = y - win->m_diffY;
302
d02d8b4c
RR
303 int org_x = 0;
304 int org_y = 0;
305 gdk_window_get_origin( widget->window, &org_x, &org_y );
306 x += org_x - win->m_diffX;
307 y += org_y - win->m_diffY;
308 win->m_x = x;
309 win->m_y = y;
310 gtk_window_move( GTK_WINDOW(win->m_widget), x, y );
311
c2fa61e8 312
32a95f9f
RR
313 return TRUE;
314}
865bb325 315}
32a95f9f 316
b2b3ccc5
RR
317//-----------------------------------------------------------------------------
318// wxMiniFrame
319//-----------------------------------------------------------------------------
320
00e4ffbc
RR
321static unsigned char close_bits[]={
322 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
323 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
324 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
325
5d5b3a40 326
b2b3ccc5
RR
327IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame,wxFrame)
328
329bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title,
330 const wxPoint &pos, const wxSize &size,
331 long style, const wxString &name )
332{
2c990ec0 333 style = style | wxCAPTION;
b9a535f5
RR
334
335 if ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT))
00e4ffbc 336 m_miniTitle = 16;
c2fa61e8 337
6d976005 338 if (style & wxRESIZE_BORDER)
85a0a12a 339 m_miniEdge = 4;
6d976005
RR
340 else
341 m_miniEdge = 3;
340bfb43 342 m_isDragging = false;
b2b3ccc5
RR
343 m_oldX = -1;
344 m_oldY = -1;
345 m_diffX = 0;
346 m_diffY = 0;
c2fa61e8 347
b2b3ccc5
RR
348 wxFrame::Create( parent, id, title, pos, size, style, name );
349
2c990ec0
RR
350 if (m_parent && (GTK_IS_WINDOW(m_parent->m_widget)))
351 {
352 gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) );
353 }
340bfb43 354
00e4ffbc 355 if ((style & wxCLOSE_BOX) &&
b9a535f5
RR
356 ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT)))
357 {
00e4ffbc 358 wxImage img = wxBitmap((const char*)close_bits, 16, 16).ConvertToImage();
c4d39711 359 img.Replace(0,0,0,123,123,123);
00e4ffbc
RR
360 img.SetMaskColour(123,123,123);
361 m_closeButton = wxBitmap( img );
b9a535f5 362 }
c2fa61e8 363
32a95f9f 364 /* these are called when the borders are drawn */
9fa72bd2
MR
365 g_signal_connect (m_mainWidget, "expose_event",
366 G_CALLBACK (gtk_window_own_expose_callback), this );
b2b3ccc5 367
32a95f9f 368 /* these are required for dragging the mini frame around */
9fa72bd2
MR
369 g_signal_connect (m_mainWidget, "button_press_event",
370 G_CALLBACK (gtk_window_button_press_callback), this);
371 g_signal_connect (m_mainWidget, "button_release_event",
372 G_CALLBACK (gtk_window_button_release_callback), this);
373 g_signal_connect (m_mainWidget, "motion_notify_event",
374 G_CALLBACK (gtk_window_motion_notify_callback), this);
85a0a12a
RR
375 g_signal_connect (m_mainWidget, "leave_notify_event",
376 G_CALLBACK (gtk_window_leave_callback), this);
340bfb43 377 return true;
b2b3ccc5 378}
dcf924a3 379
400be137
RR
380void wxMiniFrame::SetTitle( const wxString &title )
381{
382 wxFrame::SetTitle( title );
340bfb43 383
c67e060d
RR
384 if (GTK_PIZZA(m_mainWidget)->bin_window)
385 gdk_window_invalidate_rect( GTK_PIZZA(m_mainWidget)->bin_window, NULL, true );
400be137
RR
386}
387
11dbb4bf 388#endif // wxUSE_MINIFRAME