]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/minifram.cpp
Another attempts at getting dialog positions right
[wxWidgets.git] / src / gtk / 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
24//-----------------------------------------------------------------------------
25// data
26//-----------------------------------------------------------------------------
27
28extern bool g_blockEventsOnDrag;
29extern bool g_blockEventsOnScroll;
30
b2b3ccc5 31//-----------------------------------------------------------------------------
32a95f9f
RR
32// local functions
33//-----------------------------------------------------------------------------
34
35/* draw XOR rectangle when moving mine frame around */
36
37static void DrawFrame( GtkWidget *widget, int x, int y, int w, int h )
38{
39 int org_x = 0;
40 int org_y = 0;
41 gdk_window_get_origin( widget->window, &org_x, &org_y );
42 x += org_x;
43 y += org_y;
44
45 GdkGC *gc = gdk_gc_new( GDK_ROOT_PARENT() );
46 gdk_gc_set_subwindow( gc, GDK_INCLUDE_INFERIORS );
47 gdk_gc_set_function( gc, GDK_INVERT );
48
49 gdk_draw_rectangle( GDK_ROOT_PARENT(), gc, FALSE, x, y, w, h );
50 gdk_gc_unref( gc );
51}
52
53//-----------------------------------------------------------------------------
54// "expose_event" of m_mainWidget
55//-----------------------------------------------------------------------------
56
57static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxFrame *win )
58{
59 if (!win->HasVMT()) return;
60 if (gdk_event->count > 0) return;
61
62 gtk_draw_shadow( widget->style,
63 widget->window,
64 GTK_STATE_NORMAL,
65 GTK_SHADOW_OUT,
66 0, 0,
67 win->m_width, win->m_height );
68}
69
70//-----------------------------------------------------------------------------
71// "draw" of m_mainWidget
72//-----------------------------------------------------------------------------
73
74static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxFrame *win )
75{
76 if (!win->HasVMT()) return;
77
78 gtk_draw_shadow( widget->style,
79 widget->window,
80 GTK_STATE_NORMAL,
81 GTK_SHADOW_OUT,
82 0, 0,
83 win->m_width, win->m_height );
84}
85
86//-----------------------------------------------------------------------------
87// "button_press_event" of m_mainWidget
88//-----------------------------------------------------------------------------
89
90static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
91{
92 if (!win->HasVMT()) return FALSE;
93 if (g_blockEventsOnDrag) return TRUE;
94 if (g_blockEventsOnScroll) return TRUE;
95
96 if (win->m_isDragging) return TRUE;
97
98 gdk_pointer_grab( widget->window, FALSE,
99 (GdkEventMask)
100 (GDK_BUTTON_PRESS_MASK |
101 GDK_BUTTON_RELEASE_MASK |
102 GDK_POINTER_MOTION_MASK |
103 GDK_POINTER_MOTION_HINT_MASK |
104 GDK_BUTTON_MOTION_MASK |
105 GDK_BUTTON1_MOTION_MASK),
106 (GdkWindow *) NULL,
107 (GdkCursor *) NULL,
108 GDK_CURRENT_TIME );
109
110 win->m_diffX = (int)gdk_event->x;
111 win->m_diffY = (int)gdk_event->y;
112 DrawFrame( widget, 0, 0, win->m_width, win->m_height );
113 win->m_oldX = 0;
114 win->m_oldY = 0;
115
116 win->m_isDragging = TRUE;
117
118 return TRUE;
119}
120
121//-----------------------------------------------------------------------------
122// "button_release_event" of m_mainWidget
123//-----------------------------------------------------------------------------
124
125static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
126{
127 if (!win->HasVMT()) return FALSE;
128 if (g_blockEventsOnDrag) return TRUE;
129 if (g_blockEventsOnScroll) return TRUE;
130
131 if (!win->m_isDragging) return TRUE;
132
133 win->m_isDragging = FALSE;
134
135 int x = (int)gdk_event->x;
136 int y = (int)gdk_event->y;
137
138 DrawFrame( widget, win->m_oldX, win->m_oldY, win->m_width, win->m_height );
139 gdk_pointer_ungrab ( GDK_CURRENT_TIME );
140 int org_x = 0;
141 int org_y = 0;
142 gdk_window_get_origin( widget->window, &org_x, &org_y );
143 x += org_x - win->m_diffX;
144 y += org_y - win->m_diffY;
145 win->m_x = x;
146 win->m_y = y;
147 gtk_widget_set_uposition( win->m_widget, x, y );
148
149 return TRUE;
150}
151
152//-----------------------------------------------------------------------------
153// "motion_notify_event" of m_mainWidget
154//-----------------------------------------------------------------------------
155
156static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxMiniFrame *win )
157{
158 if (!win->HasVMT()) return FALSE;
159 if (g_blockEventsOnDrag) return TRUE;
160 if (g_blockEventsOnScroll) return TRUE;
161
162 if (!win->m_isDragging) return TRUE;
163
164 if (gdk_event->is_hint)
165 {
166 int x = 0;
167 int y = 0;
168 GdkModifierType state;
169 gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
170 gdk_event->x = x;
171 gdk_event->y = y;
172 gdk_event->state = state;
173 }
174
175 DrawFrame( widget, win->m_oldX, win->m_oldY, win->m_width, win->m_height );
176 win->m_oldX = (int)gdk_event->x - win->m_diffX;
177 win->m_oldY = (int)gdk_event->y - win->m_diffY;
178 DrawFrame( widget, win->m_oldX, win->m_oldY, win->m_width, win->m_height );
179
180 return TRUE;
181}
182
183//-----------------------------------------------------------------------------
184// "clicked" of X system button
b2b3ccc5
RR
185//-----------------------------------------------------------------------------
186
187static void gtk_button_clicked_callback( GtkWidget *WXUNUSED(widget), wxMiniFrame *mf )
188{
189 mf->Close();
190}
191
192//-----------------------------------------------------------------------------
193// wxMiniFrame
194//-----------------------------------------------------------------------------
195
b2b3ccc5
RR
196IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame,wxFrame)
197
198bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title,
199 const wxPoint &pos, const wxSize &size,
200 long style, const wxString &name )
201{
202 style = style | wxSIMPLE_BORDER;
203
204 m_miniEdge = 3;
205 m_miniTitle = 13;
206 m_isDragging = FALSE;
207 m_oldX = -1;
208 m_oldY = -1;
209 m_diffX = 0;
210 m_diffY = 0;
211
212 wxFrame::Create( parent, id, title, pos, size, style, name );
213
214 GtkWidget *close_button = gtk_button_new_with_label( "x" );
215
32a95f9f 216 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget), close_button, 4, 4 );
b2b3ccc5
RR
217 gtk_widget_set_usize( close_button, 12, 11 );
218
219 gtk_widget_show( close_button );
220
221 gtk_signal_connect( GTK_OBJECT(close_button), "clicked",
222 GTK_SIGNAL_FUNC(gtk_button_clicked_callback), (gpointer*)this );
223
32a95f9f
RR
224 /* these are called when the borders are drawn */
225 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event",
226 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback), (gpointer)this );
b2b3ccc5 227
32a95f9f
RR
228 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw",
229 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback), (gpointer)this );
230
231 /* these are required for dragging the mini frame around */
232 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "button_press_event",
233 GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
b2b3ccc5 234
32a95f9f
RR
235 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "button_release_event",
236 GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
b2b3ccc5 237
32a95f9f
RR
238 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "motion_notify_event",
239 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
b2b3ccc5 240
32a95f9f 241 return TRUE;
b2b3ccc5 242}