1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  11 #pragma implementation "minifram.h" 
  14 #include "wx/minifram.h" 
  18 #include "wx/dcscreen.h" 
  21 #include "wx/gtk/win_gtk.h" 
  24 #include <gdk/gdkprivate.h> 
  27 //----------------------------------------------------------------------------- 
  29 //----------------------------------------------------------------------------- 
  31 extern void wxapp_install_idle_handler(); 
  34 //----------------------------------------------------------------------------- 
  36 //----------------------------------------------------------------------------- 
  38 extern bool        g_blockEventsOnDrag
; 
  39 extern bool        g_blockEventsOnScroll
; 
  40 extern GtkWidget  
*wxGetRootWindow(); 
  42 //----------------------------------------------------------------------------- 
  44 //----------------------------------------------------------------------------- 
  46 /* draw XOR rectangle when moving mine frame around */ 
  48 static void DrawFrame( GtkWidget 
*widget
, int x
, int y
, int w
, int h 
) 
  52     gdk_window_get_origin( widget
->window
, &org_x
, &org_y 
); 
  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 
); 
  60     gdk_draw_rectangle( GDK_ROOT_PARENT(), gc
, FALSE
, x
, y
, w
, h 
); 
  64 //----------------------------------------------------------------------------- 
  65 // "expose_event" of m_mainWidget 
  66 //----------------------------------------------------------------------------- 
  68 static void gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxFrame 
*win 
) 
  70     if (g_isIdle
) wxapp_install_idle_handler(); 
  72     if (!win
->m_hasVMT
) return; 
  73     if (gdk_event
->count 
> 0) return; 
  75     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
  77     gtk_draw_shadow( widget
->style
, 
  82                      win
->m_width
, win
->m_height 
); 
  84     if (!win
->m_title
.IsEmpty() && 
  85         ((win
->GetWindowStyle() & wxCAPTION
) || 
  86          (win
->GetWindowStyle() & wxTINY_CAPTION_HORIZ
) || 
  87          (win
->GetWindowStyle() & wxTINY_CAPTION_VERT
))) 
  89         GdkGC 
*gc 
= gdk_gc_new( pizza
->bin_window 
); 
  90         GdkFont 
*font 
= wxSMALL_FONT
->GetInternalFont(1.0); 
  92         gdk_gc_set_foreground( gc
, &widget
->style
->bg
[GTK_STATE_SELECTED
] ); 
  93         gdk_draw_rectangle( pizza
->bin_window
, gc
, TRUE
, 
  97                             font
->ascent 
+ font
->descent
+1 ); 
  99         gdk_gc_set_foreground( gc
, &widget
->style
->fg
[GTK_STATE_SELECTED
] ); 
 100         gdk_draw_string( pizza
->bin_window
, font
, gc
, 
 103                          win
->m_title
.mb_str() ); 
 109 //----------------------------------------------------------------------------- 
 110 // "draw" of m_mainWidget 
 111 //----------------------------------------------------------------------------- 
 113 static void gtk_window_own_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*WXUNUSED(rect
), wxFrame 
*win 
) 
 115     if (g_isIdle
) wxapp_install_idle_handler(); 
 117     if (!win
->m_hasVMT
) return; 
 119     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 121     gtk_draw_shadow( widget
->style
, 
 126                      win
->m_width
, win
->m_height 
); 
 128     if (!win
->m_title
.IsEmpty() && 
 129         ((win
->GetWindowStyle() & wxCAPTION
) || 
 130          (win
->GetWindowStyle() & wxTINY_CAPTION_HORIZ
) || 
 131          (win
->GetWindowStyle() & wxTINY_CAPTION_VERT
))) 
 133         GdkGC 
*gc 
= gdk_gc_new( pizza
->bin_window 
); 
 134         GdkFont 
*font 
= wxSMALL_FONT
->GetInternalFont(1.0); 
 136         gdk_gc_set_foreground( gc
, &widget
->style
->bg
[GTK_STATE_SELECTED
] ); 
 137         gdk_draw_rectangle( pizza
->bin_window
, gc
, TRUE
, 
 141                             font
->ascent 
+ font
->descent
+1 ); 
 143         gdk_gc_set_foreground( gc
, &widget
->style
->fg
[GTK_STATE_SELECTED
] ); 
 144         gdk_draw_string( pizza
->bin_window
, font
, gc
, 
 147                          win
->m_title
.mb_str() ); 
 153 //----------------------------------------------------------------------------- 
 154 // "button_press_event" of m_mainWidget 
 155 //----------------------------------------------------------------------------- 
 157 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxMiniFrame 
*win 
) 
 159     if (g_isIdle
) wxapp_install_idle_handler(); 
 161     if (!win
->m_hasVMT
) return FALSE
; 
 162     if (g_blockEventsOnDrag
) return TRUE
; 
 163     if (g_blockEventsOnScroll
) return TRUE
; 
 165     if (win
->m_isDragging
) return TRUE
; 
 167     gdk_window_raise( win
->m_widget
->window 
); 
 169     gdk_pointer_grab( widget
->window
, FALSE
, 
 171                          (GDK_BUTTON_PRESS_MASK 
| 
 172                           GDK_BUTTON_RELEASE_MASK 
| 
 173                           GDK_POINTER_MOTION_MASK        
| 
 174                           GDK_POINTER_MOTION_HINT_MASK  
| 
 175                           GDK_BUTTON_MOTION_MASK        
| 
 176                           GDK_BUTTON1_MOTION_MASK
), 
 179                       (unsigned int) GDK_CURRENT_TIME 
); 
 181     win
->m_diffX 
= (int)gdk_event
->x
; 
 182     win
->m_diffY 
= (int)gdk_event
->y
; 
 183     DrawFrame( widget
, 0, 0, win
->m_width
, win
->m_height 
); 
 187     win
->m_isDragging 
= TRUE
; 
 192 //----------------------------------------------------------------------------- 
 193 // "button_release_event" of m_mainWidget 
 194 //----------------------------------------------------------------------------- 
 196 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxMiniFrame 
*win 
) 
 198     if (g_isIdle
) wxapp_install_idle_handler(); 
 200     if (!win
->m_hasVMT
) return FALSE
; 
 201     if (g_blockEventsOnDrag
) return TRUE
; 
 202     if (g_blockEventsOnScroll
) return TRUE
; 
 204     if (!win
->m_isDragging
) return TRUE
; 
 206     win
->m_isDragging 
= FALSE
; 
 208     int x 
= (int)gdk_event
->x
; 
 209     int y 
= (int)gdk_event
->y
; 
 211     DrawFrame( widget
, win
->m_oldX
, win
->m_oldY
, win
->m_width
, win
->m_height 
); 
 212     gdk_pointer_ungrab ( (guint32
)GDK_CURRENT_TIME 
); 
 215     gdk_window_get_origin( widget
->window
, &org_x
, &org_y 
); 
 216     x 
+= org_x 
- win
->m_diffX
; 
 217     y 
+= org_y 
- win
->m_diffY
; 
 220     gtk_widget_set_uposition( win
->m_widget
, x
, y 
); 
 225 //----------------------------------------------------------------------------- 
 226 // "motion_notify_event" of m_mainWidget 
 227 //----------------------------------------------------------------------------- 
 229 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxMiniFrame 
*win 
) 
 231     if (g_isIdle
) wxapp_install_idle_handler(); 
 233     if (!win
->m_hasVMT
) return FALSE
; 
 234     if (g_blockEventsOnDrag
) return TRUE
; 
 235     if (g_blockEventsOnScroll
) return TRUE
; 
 237     if (!win
->m_isDragging
) return TRUE
; 
 239     if (gdk_event
->is_hint
) 
 243        GdkModifierType state
; 
 244        gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 247        gdk_event
->state 
= state
; 
 250     DrawFrame( widget
, win
->m_oldX
, win
->m_oldY
, win
->m_width
, win
->m_height 
); 
 251     win
->m_oldX 
= (int)gdk_event
->x 
- win
->m_diffX
; 
 252     win
->m_oldY 
= (int)gdk_event
->y 
- win
->m_diffY
; 
 253     DrawFrame( widget
, win
->m_oldX
, win
->m_oldY
, win
->m_width
, win
->m_height 
); 
 258 //----------------------------------------------------------------------------- 
 259 // "clicked" of X system button 
 260 //----------------------------------------------------------------------------- 
 262 static void gtk_button_clicked_callback( GtkWidget 
*WXUNUSED(widget
), wxMiniFrame 
*mf 
) 
 264     if (g_isIdle
) wxapp_install_idle_handler(); 
 269 //----------------------------------------------------------------------------- 
 271 //----------------------------------------------------------------------------- 
 273 static char *cross_xpm
[] = { 
 274 /* columns rows colors chars-per-pixel */ 
 300 IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame
,wxFrame
) 
 302 bool wxMiniFrame::Create( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
 303       const wxPoint 
&pos
, const wxSize 
&size
, 
 304       long style
, const wxString 
&name 
) 
 306     style 
= style 
| wxCAPTION 
| wxFRAME_FLOAT_ON_PARENT
; 
 308     if ((style 
& wxCAPTION
) || (style 
& wxTINY_CAPTION_HORIZ
) || (style 
& wxTINY_CAPTION_VERT
)) 
 312     m_isDragging 
= FALSE
; 
 318     wxFrame::Create( parent
, id
, title
, pos
, size
, style
, name 
); 
 320     if ((style 
& wxSYSTEM_MENU
) && 
 321         ((style 
& wxCAPTION
) || (style 
& wxTINY_CAPTION_HORIZ
) || (style 
& wxTINY_CAPTION_VERT
))) 
 323         GdkBitmap 
*mask 
= (GdkBitmap
*) NULL
; 
 324         GdkPixmap 
*pixmap 
= gdk_pixmap_create_from_xpm_d( wxGetRootWindow()->window
, &mask
, NULL
, cross_xpm 
); 
 326         GtkWidget 
*pw 
= gtk_pixmap_new( pixmap
, mask 
); 
 327         gdk_bitmap_unref( mask 
); 
 328         gdk_pixmap_unref( pixmap 
); 
 329         gtk_widget_show( pw 
); 
 331         GtkWidget 
*close_button 
= gtk_button_new(); 
 332         gtk_container_add( GTK_CONTAINER(close_button
), pw 
); 
 334         gtk_pizza_put( GTK_PIZZA(m_mainWidget
), 
 336                          size
.x
-16, 4, 11, 11 ); 
 338         gtk_widget_show( close_button 
); 
 340         gtk_signal_connect( GTK_OBJECT(close_button
), "clicked", 
 341           GTK_SIGNAL_FUNC(gtk_button_clicked_callback
), (gpointer
*)this ); 
 344     /* these are called when the borders are drawn */ 
 345     gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event", 
 346         GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this ); 
 348     gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw", 
 349        GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this ); 
 351     /* these are required for dragging the mini frame around */ 
 352     gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "button_press_event", 
 353       GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this ); 
 355     gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "button_release_event", 
 356       GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this ); 
 358     gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "motion_notify_event", 
 359       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );