]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/minifram.cpp
Filename correction.
[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
b2b3ccc5 13#include "wx/minifram.h"
dcf924a3
RR
14
15#if wxUSE_MINIFRAME
16
b2b3ccc5
RR
17#include "wx/dcscreen.h"
18
83624f79
RR
19#include "gtk/gtk.h"
20#include "wx/gtk/win_gtk.h"
fab591c5 21#include "wx/gtk/private.h"
83624f79 22
5e7e9e1b
RR
23#include <gdk/gdk.h>
24#include <gdk/gdkprivate.h>
25#include <gdk/gdkx.h>
32a95f9f 26
acfd422a
RR
27//-----------------------------------------------------------------------------
28// idle system
29//-----------------------------------------------------------------------------
30
31extern void wxapp_install_idle_handler();
32extern bool g_isIdle;
33
32a95f9f
RR
34//-----------------------------------------------------------------------------
35// data
36//-----------------------------------------------------------------------------
37
8480b297
RR
38extern bool g_blockEventsOnDrag;
39extern bool g_blockEventsOnScroll;
c2fa61e8 40extern GtkWidget *wxGetRootWindow();
32a95f9f 41
b2b3ccc5 42//-----------------------------------------------------------------------------
32a95f9f
RR
43// local functions
44//-----------------------------------------------------------------------------
45
46/* draw XOR rectangle when moving mine frame around */
47
48static void DrawFrame( GtkWidget *widget, int x, int y, int w, int h )
49{
c2fa61e8 50 int org_x = 0;
32a95f9f
RR
51 int org_y = 0;
52 gdk_window_get_origin( widget->window, &org_x, &org_y );
53 x += org_x;
54 y += org_y;
55
56 GdkGC *gc = gdk_gc_new( GDK_ROOT_PARENT() );
57 gdk_gc_set_subwindow( gc, GDK_INCLUDE_INFERIORS );
58 gdk_gc_set_function( gc, GDK_INVERT );
c2fa61e8 59
32a95f9f
RR
60 gdk_draw_rectangle( GDK_ROOT_PARENT(), gc, FALSE, x, y, w, h );
61 gdk_gc_unref( gc );
62}
63
64//-----------------------------------------------------------------------------
65// "expose_event" of m_mainWidget
66//-----------------------------------------------------------------------------
67
865bb325 68extern "C" {
32a95f9f
RR
69static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxFrame *win )
70{
acfd422a
RR
71 if (g_isIdle) wxapp_install_idle_handler();
72
a2053b27 73 if (!win->m_hasVMT) return;
32a95f9f 74 if (gdk_event->count > 0) return;
c2fa61e8 75
da048e3d 76 GtkPizza *pizza = GTK_PIZZA(widget);
c2fa61e8
RD
77
78 gtk_draw_shadow( widget->style,
da048e3d 79 pizza->bin_window,
f03fc89f
VZ
80 GTK_STATE_NORMAL,
81 GTK_SHADOW_OUT,
82 0, 0,
a2053b27 83 win->m_width, win->m_height );
b9a535f5 84
340bfb43 85 if (!win->GetTitle().empty() &&
c2fa61e8
RD
86 ((win->GetWindowStyle() & wxCAPTION) ||
87 (win->GetWindowStyle() & wxTINY_CAPTION_HORIZ) ||
f03fc89f 88 (win->GetWindowStyle() & wxTINY_CAPTION_VERT)))
b9a535f5 89 {
ba718523
RR
90 wxClientDC dc(win);
91 dc.SetFont( *wxSMALL_FONT );
92 int height = dc.GetCharHeight();
340bfb43 93
da048e3d 94 GdkGC *gc = gdk_gc_new( pizza->bin_window );
b9a535f5 95 gdk_gc_set_foreground( gc, &widget->style->bg[GTK_STATE_SELECTED] );
c2fa61e8
RD
96 gdk_draw_rectangle( pizza->bin_window, gc, TRUE,
97 3,
98 3,
5d5b3a40 99 win->m_width - 7,
ba718523 100 height+1 );
b9a535f5 101 gdk_gc_unref( gc );
ba718523
RR
102
103 // Hack alert
104 dc.m_window = pizza->bin_window;
105 dc.SetTextForeground( *wxWHITE );
106 dc.DrawText( win->GetTitle(), 6, 3 );
b9a535f5 107 }
32a95f9f 108}
865bb325 109}
32a95f9f 110
32a95f9f
RR
111//-----------------------------------------------------------------------------
112// "button_press_event" of m_mainWidget
113//-----------------------------------------------------------------------------
114
865bb325 115extern "C" {
32a95f9f
RR
116static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
117{
acfd422a
RR
118 if (g_isIdle) wxapp_install_idle_handler();
119
a2053b27 120 if (!win->m_hasVMT) return FALSE;
32a95f9f
RR
121 if (g_blockEventsOnDrag) return TRUE;
122 if (g_blockEventsOnScroll) return TRUE;
123
124 if (win->m_isDragging) return TRUE;
125
2c990ec0
RR
126 GtkPizza *pizza = GTK_PIZZA(widget);
127 if (gdk_event->window != pizza->bin_window) return TRUE;
ba718523
RR
128
129 wxClientDC dc(win);
130 dc.SetFont( *wxSMALL_FONT );
131 int height = dc.GetCharHeight() + 1;
340bfb43 132
2c990ec0 133 if (gdk_event->y > height) return TRUE;
340bfb43 134
4dcaf11a 135 gdk_window_raise( win->m_widget->window );
c2fa61e8 136
32a95f9f
RR
137 gdk_pointer_grab( widget->window, FALSE,
138 (GdkEventMask)
139 (GDK_BUTTON_PRESS_MASK |
140 GDK_BUTTON_RELEASE_MASK |
f03fc89f 141 GDK_POINTER_MOTION_MASK |
32a95f9f 142 GDK_POINTER_MOTION_HINT_MASK |
f03fc89f 143 GDK_BUTTON_MOTION_MASK |
32a95f9f
RR
144 GDK_BUTTON1_MOTION_MASK),
145 (GdkWindow *) NULL,
146 (GdkCursor *) NULL,
7941ba11 147 (unsigned int) GDK_CURRENT_TIME );
c2fa61e8 148
32a95f9f
RR
149 win->m_diffX = (int)gdk_event->x;
150 win->m_diffY = (int)gdk_event->y;
a2053b27 151 DrawFrame( widget, 0, 0, win->m_width, win->m_height );
32a95f9f
RR
152 win->m_oldX = 0;
153 win->m_oldY = 0;
c2fa61e8 154
340bfb43 155 win->m_isDragging = true;
32a95f9f
RR
156
157 return TRUE;
158}
865bb325 159}
32a95f9f
RR
160
161//-----------------------------------------------------------------------------
162// "button_release_event" of m_mainWidget
163//-----------------------------------------------------------------------------
164
865bb325 165extern "C" {
32a95f9f
RR
166static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
167{
acfd422a
RR
168 if (g_isIdle) wxapp_install_idle_handler();
169
a2053b27 170 if (!win->m_hasVMT) return FALSE;
32a95f9f
RR
171 if (g_blockEventsOnDrag) return TRUE;
172 if (g_blockEventsOnScroll) return TRUE;
173
174 if (!win->m_isDragging) return TRUE;
c2fa61e8 175
32a95f9f 176 win->m_isDragging = FALSE;
c2fa61e8 177
32a95f9f
RR
178 int x = (int)gdk_event->x;
179 int y = (int)gdk_event->y;
c2fa61e8 180
a2053b27 181 DrawFrame( widget, win->m_oldX, win->m_oldY, win->m_width, win->m_height );
13111b2a 182 gdk_pointer_ungrab ( (guint32)GDK_CURRENT_TIME );
c2fa61e8 183 int org_x = 0;
32a95f9f
RR
184 int org_y = 0;
185 gdk_window_get_origin( widget->window, &org_x, &org_y );
186 x += org_x - win->m_diffX;
187 y += org_y - win->m_diffY;
121a3581
RR
188 win->m_x = x;
189 win->m_y = y;
a2053b27 190 gtk_widget_set_uposition( win->m_widget, x, y );
32a95f9f
RR
191
192 return TRUE;
193}
865bb325 194}
32a95f9f
RR
195
196//-----------------------------------------------------------------------------
197// "motion_notify_event" of m_mainWidget
198//-----------------------------------------------------------------------------
199
865bb325 200extern "C" {
32a95f9f
RR
201static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxMiniFrame *win )
202{
acfd422a
RR
203 if (g_isIdle) wxapp_install_idle_handler();
204
a2053b27 205 if (!win->m_hasVMT) return FALSE;
32a95f9f
RR
206 if (g_blockEventsOnDrag) return TRUE;
207 if (g_blockEventsOnScroll) return TRUE;
208
209 if (!win->m_isDragging) return TRUE;
c2fa61e8 210
32a95f9f
RR
211 if (gdk_event->is_hint)
212 {
213 int x = 0;
214 int y = 0;
215 GdkModifierType state;
216 gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
217 gdk_event->x = x;
218 gdk_event->y = y;
219 gdk_event->state = state;
220 }
221
a2053b27 222 DrawFrame( widget, win->m_oldX, win->m_oldY, win->m_width, win->m_height );
32a95f9f
RR
223 win->m_oldX = (int)gdk_event->x - win->m_diffX;
224 win->m_oldY = (int)gdk_event->y - win->m_diffY;
a2053b27 225 DrawFrame( widget, win->m_oldX, win->m_oldY, win->m_width, win->m_height );
c2fa61e8 226
32a95f9f
RR
227 return TRUE;
228}
865bb325 229}
32a95f9f
RR
230
231//-----------------------------------------------------------------------------
232// "clicked" of X system button
b2b3ccc5
RR
233//-----------------------------------------------------------------------------
234
865bb325 235extern "C" {
b2b3ccc5
RR
236static void gtk_button_clicked_callback( GtkWidget *WXUNUSED(widget), wxMiniFrame *mf )
237{
acfd422a
RR
238 if (g_isIdle) wxapp_install_idle_handler();
239
b2b3ccc5
RR
240 mf->Close();
241}
865bb325 242}
b2b3ccc5
RR
243
244//-----------------------------------------------------------------------------
245// wxMiniFrame
246//-----------------------------------------------------------------------------
247
90350682 248static const char *cross_xpm[] = {
5d5b3a40
RR
249/* columns rows colors chars-per-pixel */
250"5 5 16 1",
251" c Gray0",
252". c #bf0000",
253"X c #00bf00",
254"o c #bfbf00",
255"O c #0000bf",
256"+ c #bf00bf",
257"@ c #00bfbf",
258"# c None",
259"$ c #808080",
260"% c Red",
261"& c Green",
262"* c Yellow",
263"= c Blue",
264"- c Magenta",
265"; c Cyan",
266": c Gray100",
267/* pixels */
268" ### ",
269"# # #",
270"## ##",
271"# # #",
272" ### ",
273};
274
b2b3ccc5
RR
275IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame,wxFrame)
276
277bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title,
278 const wxPoint &pos, const wxSize &size,
279 long style, const wxString &name )
280{
2c990ec0 281 style = style | wxCAPTION;
b9a535f5
RR
282
283 if ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT))
284 m_miniTitle = 13;
c2fa61e8 285
b2b3ccc5 286 m_miniEdge = 3;
340bfb43 287 m_isDragging = false;
b2b3ccc5
RR
288 m_oldX = -1;
289 m_oldY = -1;
290 m_diffX = 0;
291 m_diffY = 0;
c2fa61e8 292
b2b3ccc5
RR
293 wxFrame::Create( parent, id, title, pos, size, style, name );
294
2c990ec0
RR
295 if (m_parent && (GTK_IS_WINDOW(m_parent->m_widget)))
296 {
297 gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) );
298 }
340bfb43 299
b9a535f5
RR
300 if ((style & wxSYSTEM_MENU) &&
301 ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT)))
302 {
5d5b3a40 303 GdkBitmap *mask = (GdkBitmap*) NULL;
90350682
VZ
304 GdkPixmap *pixmap = gdk_pixmap_create_from_xpm_d
305 (
306 wxGetRootWindow()->window,
307 &mask,
308 NULL,
309 (char **)cross_xpm
310 );
c2fa61e8 311
5d5b3a40
RR
312 GtkWidget *pw = gtk_pixmap_new( pixmap, mask );
313 gdk_bitmap_unref( mask );
314 gdk_pixmap_unref( pixmap );
315 gtk_widget_show( pw );
c2fa61e8 316
5d5b3a40
RR
317 GtkWidget *close_button = gtk_button_new();
318 gtk_container_add( GTK_CONTAINER(close_button), pw );
c2fa61e8
RD
319
320 gtk_pizza_put( GTK_PIZZA(m_mainWidget),
321 close_button,
5d5b3a40 322 size.x-16, 4, 11, 11 );
c2fa61e8 323
b9a535f5 324 gtk_widget_show( close_button );
c2fa61e8 325
9fa72bd2
MR
326 g_signal_connect (close_button, "clicked",
327 G_CALLBACK (gtk_button_clicked_callback),
328 this);
b9a535f5 329 }
c2fa61e8 330
32a95f9f 331 /* these are called when the borders are drawn */
9fa72bd2
MR
332 g_signal_connect (m_mainWidget, "expose_event",
333 G_CALLBACK (gtk_window_own_expose_callback), this );
b2b3ccc5 334
32a95f9f 335 /* these are required for dragging the mini frame around */
9fa72bd2
MR
336 g_signal_connect (m_mainWidget, "button_press_event",
337 G_CALLBACK (gtk_window_button_press_callback), this);
338 g_signal_connect (m_mainWidget, "button_release_event",
339 G_CALLBACK (gtk_window_button_release_callback), this);
340 g_signal_connect (m_mainWidget, "motion_notify_event",
341 G_CALLBACK (gtk_window_motion_notify_callback), this);
b2b3ccc5 342
340bfb43 343 return true;
b2b3ccc5 344}
dcf924a3 345
400be137
RR
346void wxMiniFrame::SetTitle( const wxString &title )
347{
348 wxFrame::SetTitle( title );
340bfb43 349
400be137 350 gdk_window_invalidate_rect( GTK_PIZZA(m_mainWidget)->bin_window, NULL, true );
400be137
RR
351}
352
dcf924a3 353#endif