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