]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/minifram.cpp
Updated for Mahogany.
[wxWidgets.git] / src / gtk1 / minifram.cpp
CommitLineData
b2b3ccc5
RR
1/////////////////////////////////////////////////////////////////////////////
2// Name: minifram.cpp
3// Purpose:
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "minifram.h"
12#endif
13
14#include "wx/minifram.h"
15#include "wx/dcscreen.h"
16
83624f79
RR
17#include "gtk/gtk.h"
18#include "wx/gtk/win_gtk.h"
19
32a95f9f
RR
20#include "gdk/gdk.h"
21#include "gdk/gdkprivate.h"
22#include "gdk/gdkx.h"
23
acfd422a
RR
24//-----------------------------------------------------------------------------
25// idle system
26//-----------------------------------------------------------------------------
27
28extern void wxapp_install_idle_handler();
29extern bool g_isIdle;
30
32a95f9f
RR
31//-----------------------------------------------------------------------------
32// data
33//-----------------------------------------------------------------------------
34
35extern bool g_blockEventsOnDrag;
36extern bool g_blockEventsOnScroll;
37
b2b3ccc5 38//-----------------------------------------------------------------------------
32a95f9f
RR
39// local functions
40//-----------------------------------------------------------------------------
41
42/* draw XOR rectangle when moving mine frame around */
43
44static void DrawFrame( GtkWidget *widget, int x, int y, int w, int h )
45{
46 int org_x = 0;
47 int org_y = 0;
48 gdk_window_get_origin( widget->window, &org_x, &org_y );
49 x += org_x;
50 y += org_y;
51
52 GdkGC *gc = gdk_gc_new( GDK_ROOT_PARENT() );
53 gdk_gc_set_subwindow( gc, GDK_INCLUDE_INFERIORS );
54 gdk_gc_set_function( gc, GDK_INVERT );
55
56 gdk_draw_rectangle( GDK_ROOT_PARENT(), gc, FALSE, x, y, w, h );
57 gdk_gc_unref( gc );
58}
59
60//-----------------------------------------------------------------------------
61// "expose_event" of m_mainWidget
62//-----------------------------------------------------------------------------
63
64static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxFrame *win )
65{
acfd422a
RR
66 if (g_isIdle) wxapp_install_idle_handler();
67
32a95f9f
RR
68 if (!win->HasVMT()) return;
69 if (gdk_event->count > 0) return;
70
71 gtk_draw_shadow( widget->style,
72 widget->window,
f03fc89f
VZ
73 GTK_STATE_NORMAL,
74 GTK_SHADOW_OUT,
75 0, 0,
76 win->GetWidth(), win->GetHeight() );
b9a535f5
RR
77
78 if (!win->m_title.IsEmpty() &&
f03fc89f
VZ
79 ((win->GetWindowStyle() & wxCAPTION) ||
80 (win->GetWindowStyle() & wxTINY_CAPTION_HORIZ) ||
81 (win->GetWindowStyle() & wxTINY_CAPTION_VERT)))
b9a535f5
RR
82 {
83 GdkGC *gc = gdk_gc_new( widget->window );
f03fc89f
VZ
84 GdkFont *font = wxSMALL_FONT->GetInternalFont(1.0);
85 int x = 2;
86 if (win->GetWindowStyle() & wxSYSTEM_MENU) x = 18;
87
b9a535f5 88 gdk_gc_set_foreground( gc, &widget->style->bg[GTK_STATE_SELECTED] );
f03fc89f
VZ
89 gdk_draw_rectangle( widget->window, gc, TRUE,
90 x,
91 3,
92 win->GetWidth() - 4 - x,
93 font->ascent + font->descent+1 );
94
b9a535f5
RR
95 gdk_gc_set_foreground( gc, &widget->style->white );
96 gdk_draw_string( widget->window, font, gc,
f03fc89f
VZ
97 x+2,
98 3+font->ascent,
99 win->m_title.mb_str() );
100
b9a535f5
RR
101 gdk_gc_unref( gc );
102 }
32a95f9f
RR
103}
104
105//-----------------------------------------------------------------------------
106// "draw" of m_mainWidget
107//-----------------------------------------------------------------------------
108
109static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxFrame *win )
110{
acfd422a
RR
111 if (g_isIdle) wxapp_install_idle_handler();
112
32a95f9f
RR
113 if (!win->HasVMT()) return;
114
115 gtk_draw_shadow( widget->style,
116 widget->window,
f03fc89f
VZ
117 GTK_STATE_NORMAL,
118 GTK_SHADOW_OUT,
119 0, 0,
120 win->GetWidth(), win->GetHeight() );
121
b9a535f5 122 if (!win->m_title.IsEmpty() &&
f03fc89f
VZ
123 ((win->GetWindowStyle() & wxCAPTION) ||
124 (win->GetWindowStyle() & wxTINY_CAPTION_HORIZ) ||
125 (win->GetWindowStyle() & wxTINY_CAPTION_VERT)))
b9a535f5
RR
126 {
127 GdkGC *gc = gdk_gc_new( widget->window );
f03fc89f
VZ
128 GdkFont *font = wxSMALL_FONT->GetInternalFont(1.0);
129 int x = 2;
130 if (win->GetWindowStyle() & wxSYSTEM_MENU) x = 17;
131
b9a535f5 132 gdk_gc_set_foreground( gc, &widget->style->bg[GTK_STATE_SELECTED] );
f03fc89f
VZ
133 gdk_draw_rectangle( widget->window, gc, TRUE,
134 x,
135 3,
136 win->GetWidth() - 4 - x,
137 font->ascent + font->descent+1 );
138
b9a535f5
RR
139 gdk_gc_set_foreground( gc, &widget->style->white );
140 gdk_draw_string( widget->window, font, gc,
f03fc89f
VZ
141 x+2,
142 3+font->ascent,
143 win->m_title.mb_str() );
144
b9a535f5
RR
145 gdk_gc_unref( gc );
146 }
32a95f9f
RR
147}
148
149//-----------------------------------------------------------------------------
150// "button_press_event" of m_mainWidget
151//-----------------------------------------------------------------------------
152
153static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
154{
acfd422a
RR
155 if (g_isIdle) wxapp_install_idle_handler();
156
32a95f9f
RR
157 if (!win->HasVMT()) return FALSE;
158 if (g_blockEventsOnDrag) return TRUE;
159 if (g_blockEventsOnScroll) return TRUE;
160
161 if (win->m_isDragging) return TRUE;
162
163 gdk_pointer_grab( widget->window, FALSE,
164 (GdkEventMask)
165 (GDK_BUTTON_PRESS_MASK |
166 GDK_BUTTON_RELEASE_MASK |
f03fc89f 167 GDK_POINTER_MOTION_MASK |
32a95f9f 168 GDK_POINTER_MOTION_HINT_MASK |
f03fc89f 169 GDK_BUTTON_MOTION_MASK |
32a95f9f
RR
170 GDK_BUTTON1_MOTION_MASK),
171 (GdkWindow *) NULL,
172 (GdkCursor *) NULL,
173 GDK_CURRENT_TIME );
f03fc89f 174
32a95f9f
RR
175 win->m_diffX = (int)gdk_event->x;
176 win->m_diffY = (int)gdk_event->y;
f03fc89f 177 DrawFrame( widget, 0, 0, win->GetWidth(), win->GetHeight() );
32a95f9f
RR
178 win->m_oldX = 0;
179 win->m_oldY = 0;
180
181 win->m_isDragging = TRUE;
182
183 return TRUE;
184}
185
186//-----------------------------------------------------------------------------
187// "button_release_event" of m_mainWidget
188//-----------------------------------------------------------------------------
189
190static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
191{
acfd422a
RR
192 if (g_isIdle) wxapp_install_idle_handler();
193
32a95f9f
RR
194 if (!win->HasVMT()) return FALSE;
195 if (g_blockEventsOnDrag) return TRUE;
196 if (g_blockEventsOnScroll) return TRUE;
197
198 if (!win->m_isDragging) return TRUE;
199
200 win->m_isDragging = FALSE;
201
202 int x = (int)gdk_event->x;
203 int y = (int)gdk_event->y;
204
f03fc89f 205 DrawFrame( widget, win->m_oldX, win->m_oldY, win->GetWidth(), win->GetHeight() );
32a95f9f
RR
206 gdk_pointer_ungrab ( GDK_CURRENT_TIME );
207 int org_x = 0;
208 int org_y = 0;
209 gdk_window_get_origin( widget->window, &org_x, &org_y );
210 x += org_x - win->m_diffX;
211 y += org_y - win->m_diffY;
f03fc89f
VZ
212 win->InternalSetPosition(x, y);
213 gtk_widget_set_uposition( win->GetWidget(), x, y );
32a95f9f
RR
214
215 return TRUE;
216}
217
218//-----------------------------------------------------------------------------
219// "motion_notify_event" of m_mainWidget
220//-----------------------------------------------------------------------------
221
222static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxMiniFrame *win )
223{
acfd422a
RR
224 if (g_isIdle) wxapp_install_idle_handler();
225
32a95f9f
RR
226 if (!win->HasVMT()) return FALSE;
227 if (g_blockEventsOnDrag) return TRUE;
228 if (g_blockEventsOnScroll) return TRUE;
229
230 if (!win->m_isDragging) return TRUE;
231
232 if (gdk_event->is_hint)
233 {
234 int x = 0;
235 int y = 0;
236 GdkModifierType state;
237 gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
238 gdk_event->x = x;
239 gdk_event->y = y;
240 gdk_event->state = state;
241 }
242
f03fc89f 243 DrawFrame( widget, win->m_oldX, win->m_oldY, win->GetWidth(), win->GetHeight() );
32a95f9f
RR
244 win->m_oldX = (int)gdk_event->x - win->m_diffX;
245 win->m_oldY = (int)gdk_event->y - win->m_diffY;
f03fc89f 246 DrawFrame( widget, win->m_oldX, win->m_oldY, win->GetWidth(), win->GetHeight() );
32a95f9f
RR
247
248 return TRUE;
249}
250
251//-----------------------------------------------------------------------------
252// "clicked" of X system button
b2b3ccc5
RR
253//-----------------------------------------------------------------------------
254
255static void gtk_button_clicked_callback( GtkWidget *WXUNUSED(widget), wxMiniFrame *mf )
256{
acfd422a
RR
257 if (g_isIdle) wxapp_install_idle_handler();
258
b2b3ccc5
RR
259 mf->Close();
260}
261
262//-----------------------------------------------------------------------------
263// wxMiniFrame
264//-----------------------------------------------------------------------------
265
b2b3ccc5
RR
266IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame,wxFrame)
267
268bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title,
269 const wxPoint &pos, const wxSize &size,
270 long style, const wxString &name )
271{
272 style = style | wxSIMPLE_BORDER;
b9a535f5
RR
273
274 if ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT))
275 m_miniTitle = 13;
f03fc89f 276
b2b3ccc5 277 m_miniEdge = 3;
b2b3ccc5
RR
278 m_isDragging = FALSE;
279 m_oldX = -1;
280 m_oldY = -1;
281 m_diffX = 0;
282 m_diffY = 0;
283
284 wxFrame::Create( parent, id, title, pos, size, style, name );
285
b9a535f5
RR
286 if ((style & wxSYSTEM_MENU) &&
287 ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT)))
288 {
289 GtkWidget *close_button = gtk_button_new_with_label( "x" );
b2b3ccc5 290
fdd3ed7a 291 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget),
f03fc89f
VZ
292 close_button,
293 4, 4, 12, 11 );
b2b3ccc5 294
b9a535f5 295 gtk_widget_show( close_button );
b2b3ccc5 296
b9a535f5
RR
297 gtk_signal_connect( GTK_OBJECT(close_button), "clicked",
298 GTK_SIGNAL_FUNC(gtk_button_clicked_callback), (gpointer*)this );
299 }
b2b3ccc5 300
32a95f9f
RR
301 /* these are called when the borders are drawn */
302 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event",
303 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback), (gpointer)this );
b2b3ccc5 304
32a95f9f
RR
305 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw",
306 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback), (gpointer)this );
307
308 /* these are required for dragging the mini frame around */
309 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "button_press_event",
310 GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
b2b3ccc5 311
32a95f9f
RR
312 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "button_release_event",
313 GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
b2b3ccc5 314
32a95f9f
RR
315 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "motion_notify_event",
316 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
b2b3ccc5 317
32a95f9f 318 return TRUE;
b2b3ccc5 319}