~ubuntu-dev/wxwidgets2.6/upstream-debian

« back to all changes in this revision

Viewing changes to src/gtk/minifram.cpp

  • Committer: Daniel T Chen
  • Date: 2006-06-26 10:15:11 UTC
  • Revision ID: crimsun@ubuntu.com-20060626101511-a4436cec4c6d9b35
ImportĀ DebianĀ 2.6.3.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/////////////////////////////////////////////////////////////////////////////
 
2
// Name:        minifram.cpp
 
3
// Purpose:
 
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
/////////////////////////////////////////////////////////////////////////////
 
9
 
 
10
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
 
11
    #pragma implementation "minifram.h"
 
12
#endif
 
13
 
 
14
// For compilers that support precompilation, includes "wx.h".
 
15
#include "wx/wxprec.h"
 
16
 
 
17
#include "wx/minifram.h"
 
18
 
 
19
#if wxUSE_MINIFRAME
 
20
 
 
21
#include "wx/dcscreen.h"
 
22
 
 
23
#include "gtk/gtk.h"
 
24
#include "wx/gtk/win_gtk.h"
 
25
#include "wx/gtk/private.h"
 
26
 
 
27
#include <gdk/gdk.h>
 
28
#include <gdk/gdkprivate.h>
 
29
#include <gdk/gdkx.h>
 
30
 
 
31
//-----------------------------------------------------------------------------
 
32
// idle system
 
33
//-----------------------------------------------------------------------------
 
34
 
 
35
extern void wxapp_install_idle_handler();
 
36
extern bool g_isIdle;
 
37
 
 
38
//-----------------------------------------------------------------------------
 
39
// data
 
40
//-----------------------------------------------------------------------------
 
41
 
 
42
extern bool        g_blockEventsOnDrag;
 
43
extern bool        g_blockEventsOnScroll;
 
44
extern GtkWidget  *wxGetRootWindow();
 
45
 
 
46
//-----------------------------------------------------------------------------
 
47
// local functions
 
48
//-----------------------------------------------------------------------------
 
49
 
 
50
/* draw XOR rectangle when moving mine frame around */
 
51
 
 
52
static void DrawFrame( GtkWidget *widget, int x, int y, int w, int h )
 
53
{
 
54
    int org_x = 0;
 
55
    int org_y = 0;
 
56
    gdk_window_get_origin( widget->window, &org_x, &org_y );
 
57
    x += org_x;
 
58
    y += org_y;
 
59
 
 
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 );
 
63
 
 
64
    gdk_draw_rectangle( GDK_ROOT_PARENT(), gc, FALSE, x, y, w, h );
 
65
    gdk_gc_unref( gc );
 
66
}
 
67
 
 
68
//-----------------------------------------------------------------------------
 
69
// "expose_event" of m_mainWidget
 
70
//-----------------------------------------------------------------------------
 
71
 
 
72
extern "C" {
 
73
static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxFrame *win )
 
74
{
 
75
    if (g_isIdle) wxapp_install_idle_handler();
 
76
 
 
77
    if (!win->m_hasVMT) return;
 
78
    if (gdk_event->count > 0) return;
 
79
 
 
80
    GtkPizza *pizza = GTK_PIZZA(widget);
 
81
 
 
82
    gtk_draw_shadow( widget->style,
 
83
                     pizza->bin_window,
 
84
                     GTK_STATE_NORMAL,
 
85
                     GTK_SHADOW_OUT,
 
86
                     0, 0,
 
87
                     win->m_width, win->m_height );
 
88
 
 
89
    if (!win->GetTitle().IsEmpty() &&
 
90
        ((win->GetWindowStyle() & wxCAPTION) ||
 
91
         (win->GetWindowStyle() & wxTINY_CAPTION_HORIZ) ||
 
92
         (win->GetWindowStyle() & wxTINY_CAPTION_VERT)))
 
93
    {
 
94
        wxClientDC dc(win);
 
95
        dc.SetFont( *wxSMALL_FONT );
 
96
        int height = dc.GetCharHeight();
 
97
        
 
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,
 
101
                            3,
 
102
                            3,
 
103
                            win->m_width - 7,
 
104
                            height+1 );
 
105
        gdk_gc_unref( gc );
 
106
 
 
107
        // Hack alert
 
108
        dc.m_window = pizza->bin_window;
 
109
        dc.SetTextForeground( *wxWHITE );
 
110
        dc.DrawText( win->GetTitle(), 6, 3 );
 
111
    }
 
112
}
 
113
}
 
114
 
 
115
//-----------------------------------------------------------------------------
 
116
// "draw" of m_mainWidget
 
117
//-----------------------------------------------------------------------------
 
118
 
 
119
#ifndef __WXGTK20__
 
120
extern "C" {
 
121
static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxFrame *win )
 
122
{
 
123
    if (g_isIdle) wxapp_install_idle_handler();
 
124
 
 
125
    if (!win->m_hasVMT) return;
 
126
 
 
127
    GtkPizza *pizza = GTK_PIZZA(widget);
 
128
 
 
129
    gtk_draw_shadow( widget->style,
 
130
                     pizza->bin_window,
 
131
                     GTK_STATE_NORMAL,
 
132
                     GTK_SHADOW_OUT,
 
133
                     0, 0,
 
134
                     win->m_width, win->m_height );
 
135
 
 
136
    if (!win->m_title.IsEmpty() &&
 
137
        ((win->GetWindowStyle() & wxCAPTION) ||
 
138
         (win->GetWindowStyle() & wxTINY_CAPTION_HORIZ) ||
 
139
         (win->GetWindowStyle() & wxTINY_CAPTION_VERT)))
 
140
    {
 
141
        wxClientDC dc(win);
 
142
        dc.SetFont( *wxSMALL_FONT );
 
143
        int height = dc.GetCharHeight();
 
144
        
 
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,
 
148
                            3,
 
149
                            3,
 
150
                            win->m_width - 7,
 
151
                            height+1 );
 
152
        gdk_gc_unref( gc );
 
153
 
 
154
        // Hack alert
 
155
        dc.m_window = pizza->bin_window;
 
156
        dc.SetTextForeground( *wxWHITE );
 
157
        dc.DrawText( win->GetTitle(), 6, 3 );
 
158
    }
 
159
}
 
160
}
 
161
#endif
 
162
 
 
163
//-----------------------------------------------------------------------------
 
164
// "button_press_event" of m_mainWidget
 
165
//-----------------------------------------------------------------------------
 
166
 
 
167
extern "C" {
 
168
static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
 
169
{
 
170
    if (g_isIdle) wxapp_install_idle_handler();
 
171
 
 
172
    if (!win->m_hasVMT) return FALSE;
 
173
    if (g_blockEventsOnDrag) return TRUE;
 
174
    if (g_blockEventsOnScroll) return TRUE;
 
175
 
 
176
    if (win->m_isDragging) return TRUE;
 
177
 
 
178
    GtkPizza *pizza = GTK_PIZZA(widget);
 
179
    if (gdk_event->window != pizza->bin_window) return TRUE;
 
180
 
 
181
    wxClientDC dc(win);
 
182
    dc.SetFont( *wxSMALL_FONT );
 
183
    int height = dc.GetCharHeight() + 1;
 
184
    
 
185
    if (gdk_event->y > height) return TRUE;
 
186
        
 
187
    gdk_window_raise( win->m_widget->window );
 
188
 
 
189
    gdk_pointer_grab( widget->window, FALSE,
 
190
                      (GdkEventMask)
 
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),
 
197
                      (GdkWindow *) NULL,
 
198
                      (GdkCursor *) NULL,
 
199
                      (unsigned int) GDK_CURRENT_TIME );
 
200
 
 
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 );
 
204
    win->m_oldX = 0;
 
205
    win->m_oldY = 0;
 
206
 
 
207
    win->m_isDragging = TRUE;
 
208
 
 
209
    return TRUE;
 
210
}
 
211
}
 
212
 
 
213
//-----------------------------------------------------------------------------
 
214
// "button_release_event" of m_mainWidget
 
215
//-----------------------------------------------------------------------------
 
216
 
 
217
extern "C" {
 
218
static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxMiniFrame *win )
 
219
{
 
220
    if (g_isIdle) wxapp_install_idle_handler();
 
221
 
 
222
    if (!win->m_hasVMT) return FALSE;
 
223
    if (g_blockEventsOnDrag) return TRUE;
 
224
    if (g_blockEventsOnScroll) return TRUE;
 
225
 
 
226
    if (!win->m_isDragging) return TRUE;
 
227
 
 
228
    win->m_isDragging = FALSE;
 
229
 
 
230
    int x = (int)gdk_event->x;
 
231
    int y = (int)gdk_event->y;
 
232
 
 
233
    DrawFrame( widget, win->m_oldX, win->m_oldY, win->m_width, win->m_height );
 
234
    gdk_pointer_ungrab ( (guint32)GDK_CURRENT_TIME );
 
235
    int org_x = 0;
 
236
    int org_y = 0;
 
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;
 
240
    win->m_x = x;
 
241
    win->m_y = y;
 
242
    gtk_widget_set_uposition( win->m_widget, x, y );
 
243
 
 
244
    return TRUE;
 
245
}
 
246
}
 
247
 
 
248
//-----------------------------------------------------------------------------
 
249
// "motion_notify_event" of m_mainWidget
 
250
//-----------------------------------------------------------------------------
 
251
 
 
252
extern "C" {
 
253
static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxMiniFrame *win )
 
254
{
 
255
    if (g_isIdle) wxapp_install_idle_handler();
 
256
 
 
257
    if (!win->m_hasVMT) return FALSE;
 
258
    if (g_blockEventsOnDrag) return TRUE;
 
259
    if (g_blockEventsOnScroll) return TRUE;
 
260
 
 
261
    if (!win->m_isDragging) return TRUE;
 
262
 
 
263
    if (gdk_event->is_hint)
 
264
    {
 
265
       int x = 0;
 
266
       int y = 0;
 
267
       GdkModifierType state;
 
268
       gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
 
269
       gdk_event->x = x;
 
270
       gdk_event->y = y;
 
271
       gdk_event->state = state;
 
272
    }
 
273
 
 
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 );
 
278
 
 
279
    return TRUE;
 
280
}
 
281
}
 
282
 
 
283
//-----------------------------------------------------------------------------
 
284
// "clicked" of X system button
 
285
//-----------------------------------------------------------------------------
 
286
 
 
287
extern "C" {
 
288
static void gtk_button_clicked_callback( GtkWidget *WXUNUSED(widget), wxMiniFrame *mf )
 
289
{
 
290
    if (g_isIdle) wxapp_install_idle_handler();
 
291
 
 
292
    mf->Close();
 
293
}
 
294
}
 
295
 
 
296
//-----------------------------------------------------------------------------
 
297
// wxMiniFrame
 
298
//-----------------------------------------------------------------------------
 
299
 
 
300
static const char *cross_xpm[] = {
 
301
/* columns rows colors chars-per-pixel */
 
302
"5 5 16 1",
 
303
"  c Gray0",
 
304
". c #bf0000",
 
305
"X c #00bf00",
 
306
"o c #bfbf00",
 
307
"O c #0000bf",
 
308
"+ c #bf00bf",
 
309
"@ c #00bfbf",
 
310
"# c None",
 
311
"$ c #808080",
 
312
"% c Red",
 
313
"& c Green",
 
314
"* c Yellow",
 
315
"= c Blue",
 
316
"- c Magenta",
 
317
"; c Cyan",
 
318
": c Gray100",
 
319
/* pixels */
 
320
" ### ",
 
321
"# # #",
 
322
"## ##",
 
323
"# # #",
 
324
" ### ",
 
325
};
 
326
 
 
327
IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame,wxFrame)
 
328
 
 
329
bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title,
 
330
      const wxPoint &pos, const wxSize &size,
 
331
      long style, const wxString &name )
 
332
{
 
333
    style = style | wxCAPTION;
 
334
 
 
335
    if ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT))
 
336
        m_miniTitle = 13;
 
337
 
 
338
    m_miniEdge = 3;
 
339
    m_isDragging = FALSE;
 
340
    m_oldX = -1;
 
341
    m_oldY = -1;
 
342
    m_diffX = 0;
 
343
    m_diffY = 0;
 
344
 
 
345
    wxFrame::Create( parent, id, title, pos, size, style, name );
 
346
 
 
347
    if (m_parent && (GTK_IS_WINDOW(m_parent->m_widget)))
 
348
    {
 
349
        gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) );
 
350
    }
 
351
    
 
352
    if ((style & wxSYSTEM_MENU) &&
 
353
        ((style & wxCAPTION) || (style & wxTINY_CAPTION_HORIZ) || (style & wxTINY_CAPTION_VERT)))
 
354
    {
 
355
        GdkBitmap *mask = (GdkBitmap*) NULL;
 
356
        GdkPixmap *pixmap = gdk_pixmap_create_from_xpm_d
 
357
                            (
 
358
                                wxGetRootWindow()->window,
 
359
                                &mask,
 
360
                                NULL,
 
361
                                (char **)cross_xpm
 
362
                            );
 
363
 
 
364
        GtkWidget *pw = gtk_pixmap_new( pixmap, mask );
 
365
        gdk_bitmap_unref( mask );
 
366
        gdk_pixmap_unref( pixmap );
 
367
        gtk_widget_show( pw );
 
368
 
 
369
        GtkWidget *close_button = gtk_button_new();
 
370
        gtk_container_add( GTK_CONTAINER(close_button), pw );
 
371
 
 
372
        gtk_pizza_put( GTK_PIZZA(m_mainWidget),
 
373
                         close_button,
 
374
                         size.x-16, 4, 11, 11 );
 
375
 
 
376
        gtk_widget_show( close_button );
 
377
 
 
378
        gtk_signal_connect( GTK_OBJECT(close_button), "clicked",
 
379
          GTK_SIGNAL_FUNC(gtk_button_clicked_callback), (gpointer*)this );
 
380
    }
 
381
 
 
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 );
 
385
 
 
386
#ifndef __WXGTK20__
 
387
    gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw",
 
388
       GTK_SIGNAL_FUNC(gtk_window_own_draw_callback), (gpointer)this );
 
389
#endif
 
390
 
 
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 );
 
394
 
 
395
    gtk_signal_connect( GTK_OBJECT(m_mainWidget), "button_release_event",
 
396
      GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
 
397
 
 
398
    gtk_signal_connect( GTK_OBJECT(m_mainWidget), "motion_notify_event",
 
399
      GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
 
400
 
 
401
    return TRUE;
 
402
}
 
403
 
 
404
void wxMiniFrame::SetTitle( const wxString &title )
 
405
{
 
406
    wxFrame::SetTitle( title );
 
407
    
 
408
#ifdef __WXGTK20__
 
409
    gdk_window_invalidate_rect( GTK_PIZZA(m_mainWidget)->bin_window, NULL, true );
 
410
#else
 
411
    gtk_widget_draw( m_mainWidget, (GdkRectangle*) NULL );
 
412
#endif
 
413
}
 
414
 
 
415
#endif