1
/////////////////////////////////////////////////////////////////////////////
4
// Author: Robert Roebling
5
// Id: $Id: minifram.cpp,v 1.35 2005/03/21 23:42:18 VZ Exp $
6
// Copyright: (c) 1998 Robert Roebling
7
// Licence: wxWindows licence
8
/////////////////////////////////////////////////////////////////////////////
10
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
11
#pragma implementation "minifram.h"
14
// For compilers that support precompilation, includes "wx.h".
15
#include "wx/wxprec.h"
17
#include "wx/minifram.h"
21
#include "wx/dcscreen.h"
24
#include "wx/gtk/win_gtk.h"
25
#include "wx/gtk/private.h"
28
#include <gdk/gdkprivate.h>
31
//-----------------------------------------------------------------------------
33
//-----------------------------------------------------------------------------
35
extern void wxapp_install_idle_handler();
38
//-----------------------------------------------------------------------------
40
//-----------------------------------------------------------------------------
42
extern bool g_blockEventsOnDrag;
43
extern bool g_blockEventsOnScroll;
44
extern GtkWidget *wxGetRootWindow();
46
//-----------------------------------------------------------------------------
48
//-----------------------------------------------------------------------------
50
/* draw XOR rectangle when moving mine frame around */
52
static void DrawFrame( GtkWidget *widget, int x, int y, int w, int h )
56
gdk_window_get_origin( widget->window, &org_x, &org_y );
60
GdkGC *gc = gdk_gc_new( GDK_ROOT_PARENT() );
61
gdk_gc_set_subwindow( gc, GDK_INCLUDE_INFERIORS );
62
gdk_gc_set_function( gc, GDK_INVERT );
64
gdk_draw_rectangle( GDK_ROOT_PARENT(), gc, FALSE, x, y, w, h );
68
//-----------------------------------------------------------------------------
69
// "expose_event" of m_mainWidget
70
//-----------------------------------------------------------------------------
73
static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxFrame *win )
75
if (g_isIdle) wxapp_install_idle_handler();
77
if (!win->m_hasVMT) return;
78
if (gdk_event->count > 0) return;
80
GtkPizza *pizza = GTK_PIZZA(widget);
82
gtk_draw_shadow( widget->style,
87
win->m_width, win->m_height );
89
if (!win->GetTitle().IsEmpty() &&
90
((win->GetWindowStyle() & wxCAPTION) ||
91
(win->GetWindowStyle() & wxTINY_CAPTION_HORIZ) ||
92
(win->GetWindowStyle() & wxTINY_CAPTION_VERT)))
95
dc.SetFont( *wxSMALL_FONT );
96
int height = dc.GetCharHeight();
98
GdkGC *gc = gdk_gc_new( pizza->bin_window );
99
gdk_gc_set_foreground( gc, &widget->style->bg[GTK_STATE_SELECTED] );
100
gdk_draw_rectangle( pizza->bin_window, gc, TRUE,
108
dc.m_window = pizza->bin_window;
109
dc.SetTextForeground( *wxWHITE );
110
dc.DrawText( win->GetTitle(), 6, 3 );
115
//-----------------------------------------------------------------------------
116
// "draw" of m_mainWidget
117
//-----------------------------------------------------------------------------
121
static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxFrame *win )
123
if (g_isIdle) wxapp_install_idle_handler();
125
if (!win->m_hasVMT) return;
127
GtkPizza *pizza = GTK_PIZZA(widget);
129
gtk_draw_shadow( widget->style,
134
win->m_width, win->m_height );
136
if (!win->m_title.IsEmpty() &&
137
((win->GetWindowStyle() & wxCAPTION) ||
138
(win->GetWindowStyle() & wxTINY_CAPTION_HORIZ) ||
139
(win->GetWindowStyle() & wxTINY_CAPTION_VERT)))
142
dc.SetFont( *wxSMALL_FONT );
143
int height = dc.GetCharHeight();
145
GdkGC *gc = gdk_gc_new( pizza->bin_window );
146
gdk_gc_set_foreground( gc, &widget->style->bg[GTK_STATE_SELECTED] );
147
gdk_draw_rectangle( pizza->bin_window, gc, TRUE,
155
dc.m_window = pizza->bin_window;
156
dc.SetTextForeground( *wxWHITE );
157
dc.DrawText( win->GetTitle(), 6, 3 );
163
//-----------------------------------------------------------------------------
164
// "button_press_event" of m_mainWidget
165
//-----------------------------------------------------------------------------
168
static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
170
if (g_isIdle) wxapp_install_idle_handler();
172
if (!win->m_hasVMT) return FALSE;
173
if (g_blockEventsOnDrag) return TRUE;
174
if (g_blockEventsOnScroll) return TRUE;
176
if (win->m_isDragging) return TRUE;
178
GtkPizza *pizza = GTK_PIZZA(widget);
179
if (gdk_event->window != pizza->bin_window) return TRUE;
182
dc.SetFont( *wxSMALL_FONT );
183
int height = dc.GetCharHeight() + 1;
185
if (gdk_event->y > height) return TRUE;
187
gdk_window_raise( win->m_widget->window );
189
gdk_pointer_grab( widget->window, FALSE,
191
(GDK_BUTTON_PRESS_MASK |
192
GDK_BUTTON_RELEASE_MASK |
193
GDK_POINTER_MOTION_MASK |
194
GDK_POINTER_MOTION_HINT_MASK |
195
GDK_BUTTON_MOTION_MASK |
196
GDK_BUTTON1_MOTION_MASK),
199
(unsigned int) GDK_CURRENT_TIME );
201
win->m_diffX = (int)gdk_event->x;
202
win->m_diffY = (int)gdk_event->y;
203
DrawFrame( widget, 0, 0, win->m_width, win->m_height );
207
win->m_isDragging = TRUE;
213
//-----------------------------------------------------------------------------
214
// "button_release_event" of m_mainWidget
215
//-----------------------------------------------------------------------------
218
static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
220
if (g_isIdle) wxapp_install_idle_handler();
222
if (!win->m_hasVMT) return FALSE;
223
if (g_blockEventsOnDrag) return TRUE;
224
if (g_blockEventsOnScroll) return TRUE;
226
if (!win->m_isDragging) return TRUE;
228
win->m_isDragging = FALSE;
230
int x = (int)gdk_event->x;
231
int y = (int)gdk_event->y;
233
DrawFrame( widget, win->m_oldX, win->m_oldY, win->m_width, win->m_height );
234
gdk_pointer_ungrab ( (guint32)GDK_CURRENT_TIME );
237
gdk_window_get_origin( widget->window, &org_x, &org_y );
238
x += org_x - win->m_diffX;
239
y += org_y - win->m_diffY;
242
gtk_widget_set_uposition( win->m_widget, x, y );
248
//-----------------------------------------------------------------------------
249
// "motion_notify_event" of m_mainWidget
250
//-----------------------------------------------------------------------------
253
static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxMiniFrame *win )
255
if (g_isIdle) wxapp_install_idle_handler();
257
if (!win->m_hasVMT) return FALSE;
258
if (g_blockEventsOnDrag) return TRUE;
259
if (g_blockEventsOnScroll) return TRUE;
261
if (!win->m_isDragging) return TRUE;
263
if (gdk_event->is_hint)
267
GdkModifierType state;
268
gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
271
gdk_event->state = state;
274
DrawFrame( widget, win->m_oldX, win->m_oldY, win->m_width, win->m_height );
275
win->m_oldX = (int)gdk_event->x - win->m_diffX;
276
win->m_oldY = (int)gdk_event->y - win->m_diffY;
277
DrawFrame( widget, win->m_oldX, win->m_oldY, win->m_width, win->m_height );
283
//-----------------------------------------------------------------------------
284
// "clicked" of X system button
285
//-----------------------------------------------------------------------------
288
static void gtk_button_clicked_callback( GtkWidget *WXUNUSED(widget), wxMiniFrame *mf )
290
if (g_isIdle) wxapp_install_idle_handler();
296
//-----------------------------------------------------------------------------
298
//-----------------------------------------------------------------------------
300
static const char *cross_xpm[] = {
301
/* columns rows colors chars-per-pixel */
327
IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame,wxFrame)
329
bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title,
330
const wxPoint &pos, const wxSize &size,
331
long style, const wxString &name )
333
style = style | wxCAPTION;
335
if ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT))
339
m_isDragging = FALSE;
345
wxFrame::Create( parent, id, title, pos, size, style, name );
347
if (m_parent && (GTK_IS_WINDOW(m_parent->m_widget)))
349
gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) );
352
if ((style & wxSYSTEM_MENU) &&
353
((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT)))
355
GdkBitmap *mask = (GdkBitmap*) NULL;
356
GdkPixmap *pixmap = gdk_pixmap_create_from_xpm_d
358
wxGetRootWindow()->window,
364
GtkWidget *pw = gtk_pixmap_new( pixmap, mask );
365
gdk_bitmap_unref( mask );
366
gdk_pixmap_unref( pixmap );
367
gtk_widget_show( pw );
369
GtkWidget *close_button = gtk_button_new();
370
gtk_container_add( GTK_CONTAINER(close_button), pw );
372
gtk_pizza_put( GTK_PIZZA(m_mainWidget),
374
size.x-16, 4, 11, 11 );
376
gtk_widget_show( close_button );
378
gtk_signal_connect( GTK_OBJECT(close_button), "clicked",
379
GTK_SIGNAL_FUNC(gtk_button_clicked_callback), (gpointer*)this );
382
/* these are called when the borders are drawn */
383
gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event",
384
GTK_SIGNAL_FUNC(gtk_window_own_expose_callback), (gpointer)this );
387
gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw",
388
GTK_SIGNAL_FUNC(gtk_window_own_draw_callback), (gpointer)this );
391
/* these are required for dragging the mini frame around */
392
gtk_signal_connect( GTK_OBJECT(m_mainWidget), "button_press_event",
393
GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
395
gtk_signal_connect( GTK_OBJECT(m_mainWidget), "button_release_event",
396
GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
398
gtk_signal_connect( GTK_OBJECT(m_mainWidget), "motion_notify_event",
399
GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
404
void wxMiniFrame::SetTitle( const wxString &title )
406
wxFrame::SetTitle( title );
409
gdk_window_invalidate_rect( GTK_PIZZA(m_mainWidget)->bin_window, NULL, true );
411
gtk_widget_draw( m_mainWidget, (GdkRectangle*) NULL );