1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk1/minifram.cpp 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // For compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  15 #include "wx/minifram.h" 
  18     #include "wx/dcscreen.h" 
  22 #include "wx/gtk1/win_gtk.h" 
  23 #include "wx/gtk1/private.h" 
  26 #include <gdk/gdkprivate.h> 
  29 //----------------------------------------------------------------------------- 
  31 //----------------------------------------------------------------------------- 
  33 extern void wxapp_install_idle_handler(); 
  36 //----------------------------------------------------------------------------- 
  38 //----------------------------------------------------------------------------- 
  40 extern bool        g_blockEventsOnDrag
; 
  41 extern bool        g_blockEventsOnScroll
; 
  42 extern GtkWidget  
*wxGetRootWindow(); 
  44 //----------------------------------------------------------------------------- 
  46 //----------------------------------------------------------------------------- 
  48 /* draw XOR rectangle when moving mine frame around */ 
  50 static void DrawFrame( GtkWidget 
*widget
, int x
, int y
, int w
, int h 
) 
  54     gdk_window_get_origin( widget
->window
, &org_x
, &org_y 
); 
  58     GdkGC 
*gc 
= gdk_gc_new( GDK_ROOT_PARENT() ); 
  59     gdk_gc_set_subwindow( gc
, GDK_INCLUDE_INFERIORS 
); 
  60     gdk_gc_set_function( gc
, GDK_INVERT 
); 
  62     gdk_draw_rectangle( GDK_ROOT_PARENT(), gc
, FALSE
, x
, y
, w
, h 
); 
  66 //----------------------------------------------------------------------------- 
  67 // "expose_event" of m_mainWidget 
  68 //----------------------------------------------------------------------------- 
  71 static void gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxFrame 
*win 
) 
  73     if (g_isIdle
) wxapp_install_idle_handler(); 
  75     if (!win
->m_hasVMT
) return; 
  76     if (gdk_event
->count 
> 0) return; 
  78     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
  80     gtk_draw_shadow( widget
->style
, 
  85                      win
->m_width
, win
->m_height 
); 
  87     if (!win
->GetTitle().empty() && 
  88         ((win
->GetWindowStyle() & wxCAPTION
) || 
  89          (win
->GetWindowStyle() & wxTINY_CAPTION_HORIZ
) || 
  90          (win
->GetWindowStyle() & wxTINY_CAPTION_VERT
))) 
  93         dc
.SetFont( *wxSMALL_FONT 
); 
  94         int height 
= dc
.GetCharHeight(); 
  96         GdkGC 
*gc 
= gdk_gc_new( pizza
->bin_window 
); 
  97         gdk_gc_set_foreground( gc
, &widget
->style
->bg
[GTK_STATE_SELECTED
] ); 
  98         gdk_draw_rectangle( pizza
->bin_window
, gc
, TRUE
, 
 106         dc
.m_window 
= pizza
->bin_window
; 
 107         dc
.SetTextForeground( *wxWHITE 
); 
 108         dc
.DrawText( win
->GetTitle(), 6, 3 ); 
 113 //----------------------------------------------------------------------------- 
 114 // "draw" of m_mainWidget 
 115 //----------------------------------------------------------------------------- 
 118 static void gtk_window_own_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*WXUNUSED(rect
), wxFrame 
*win 
) 
 120     if (g_isIdle
) wxapp_install_idle_handler(); 
 122     if (!win
->m_hasVMT
) return; 
 124     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 126     gtk_draw_shadow( widget
->style
, 
 131                      win
->m_width
, win
->m_height 
); 
 133     if (!win
->GetTitle().empty() && 
 134         ((win
->GetWindowStyle() & wxCAPTION
) || 
 135          (win
->GetWindowStyle() & wxTINY_CAPTION_HORIZ
) || 
 136          (win
->GetWindowStyle() & wxTINY_CAPTION_VERT
))) 
 139         dc
.SetFont( *wxSMALL_FONT 
); 
 140         int height 
= dc
.GetCharHeight(); 
 142         GdkGC 
*gc 
= gdk_gc_new( pizza
->bin_window 
); 
 143         gdk_gc_set_foreground( gc
, &widget
->style
->bg
[GTK_STATE_SELECTED
] ); 
 144         gdk_draw_rectangle( pizza
->bin_window
, gc
, TRUE
, 
 152         dc
.m_window 
= pizza
->bin_window
; 
 153         dc
.SetTextForeground( *wxWHITE 
); 
 154         dc
.DrawText( win
->GetTitle(), 6, 3 ); 
 159 //----------------------------------------------------------------------------- 
 160 // "button_press_event" of m_mainWidget 
 161 //----------------------------------------------------------------------------- 
 164 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxMiniFrame 
*win 
) 
 166     if (g_isIdle
) wxapp_install_idle_handler(); 
 168     if (!win
->m_hasVMT
) return FALSE
; 
 169     if (g_blockEventsOnDrag
) return TRUE
; 
 170     if (g_blockEventsOnScroll
) return TRUE
; 
 172     if (win
->m_isDragging
) return TRUE
; 
 174     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 175     if (gdk_event
->window 
!= pizza
->bin_window
) return TRUE
; 
 178     dc
.SetFont( *wxSMALL_FONT 
); 
 179     int height 
= dc
.GetCharHeight() + 1; 
 181     if (gdk_event
->y 
> height
) return TRUE
; 
 183     gdk_window_raise( win
->m_widget
->window 
); 
 185     gdk_pointer_grab( widget
->window
, FALSE
, 
 187                          (GDK_BUTTON_PRESS_MASK 
| 
 188                           GDK_BUTTON_RELEASE_MASK 
| 
 189                           GDK_POINTER_MOTION_MASK        
| 
 190                           GDK_POINTER_MOTION_HINT_MASK  
| 
 191                           GDK_BUTTON_MOTION_MASK        
| 
 192                           GDK_BUTTON1_MOTION_MASK
), 
 195                       (unsigned int) GDK_CURRENT_TIME 
); 
 197     win
->m_diffX 
= (int)gdk_event
->x
; 
 198     win
->m_diffY 
= (int)gdk_event
->y
; 
 199     DrawFrame( widget
, 0, 0, win
->m_width
, win
->m_height 
); 
 203     win
->m_isDragging 
= true; 
 209 //----------------------------------------------------------------------------- 
 210 // "button_release_event" of m_mainWidget 
 211 //----------------------------------------------------------------------------- 
 214 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxMiniFrame 
*win 
) 
 216     if (g_isIdle
) wxapp_install_idle_handler(); 
 218     if (!win
->m_hasVMT
) return FALSE
; 
 219     if (g_blockEventsOnDrag
) return TRUE
; 
 220     if (g_blockEventsOnScroll
) return TRUE
; 
 222     if (!win
->m_isDragging
) return TRUE
; 
 224     win
->m_isDragging 
= false; 
 226     int x 
= (int)gdk_event
->x
; 
 227     int y 
= (int)gdk_event
->y
; 
 229     DrawFrame( widget
, win
->m_oldX
, win
->m_oldY
, win
->m_width
, win
->m_height 
); 
 230     gdk_pointer_ungrab ( (guint32
)GDK_CURRENT_TIME 
); 
 233     gdk_window_get_origin( widget
->window
, &org_x
, &org_y 
); 
 234     x 
+= org_x 
- win
->m_diffX
; 
 235     y 
+= org_y 
- win
->m_diffY
; 
 238     gtk_widget_set_uposition( win
->m_widget
, x
, y 
); 
 244 //----------------------------------------------------------------------------- 
 245 // "motion_notify_event" of m_mainWidget 
 246 //----------------------------------------------------------------------------- 
 249 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxMiniFrame 
*win 
) 
 251     if (g_isIdle
) wxapp_install_idle_handler(); 
 253     if (!win
->m_hasVMT
) return FALSE
; 
 254     if (g_blockEventsOnDrag
) return TRUE
; 
 255     if (g_blockEventsOnScroll
) return TRUE
; 
 257     if (!win
->m_isDragging
) return TRUE
; 
 259     if (gdk_event
->is_hint
) 
 263        GdkModifierType state
; 
 264        gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 267        gdk_event
->state 
= state
; 
 270     DrawFrame( widget
, win
->m_oldX
, win
->m_oldY
, win
->m_width
, win
->m_height 
); 
 271     win
->m_oldX 
= (int)gdk_event
->x 
- win
->m_diffX
; 
 272     win
->m_oldY 
= (int)gdk_event
->y 
- win
->m_diffY
; 
 273     DrawFrame( widget
, win
->m_oldX
, win
->m_oldY
, win
->m_width
, win
->m_height 
); 
 279 //----------------------------------------------------------------------------- 
 280 // "clicked" of X system button 
 281 //----------------------------------------------------------------------------- 
 284 static void gtk_button_clicked_callback( GtkWidget 
*WXUNUSED(widget
), wxMiniFrame 
*mf 
) 
 286     if (g_isIdle
) wxapp_install_idle_handler(); 
 292 //----------------------------------------------------------------------------- 
 294 //----------------------------------------------------------------------------- 
 296 static const char *cross_xpm
[] = { 
 297 /* columns rows colors chars-per-pixel */ 
 323 IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame
,wxFrame
) 
 325 bool wxMiniFrame::Create( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
 326       const wxPoint 
&pos
, const wxSize 
&size
, 
 327       long style
, const wxString 
&name 
) 
 329     style 
= style 
| wxCAPTION
; 
 331     if ((style 
& wxCAPTION
) || (style 
& wxTINY_CAPTION_HORIZ
) || (style 
& wxTINY_CAPTION_VERT
)) 
 335     m_isDragging 
= false; 
 341     wxFrame::Create( parent
, id
, title
, pos
, size
, style
, name 
); 
 343     if (m_parent 
&& (GTK_IS_WINDOW(m_parent
->m_widget
))) 
 345         gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) ); 
 348     if ((style 
& wxSYSTEM_MENU
) && 
 349         ((style 
& wxCAPTION
) || (style 
& wxTINY_CAPTION_HORIZ
) || (style 
& wxTINY_CAPTION_VERT
))) 
 351         GdkBitmap 
*mask 
= (GdkBitmap
*) NULL
; 
 352         GdkPixmap 
*pixmap 
= gdk_pixmap_create_from_xpm_d
 
 354                                 wxGetRootWindow()->window
, 
 360         GtkWidget 
*pw 
= gtk_pixmap_new( pixmap
, mask 
); 
 361         gdk_bitmap_unref( mask 
); 
 362         gdk_pixmap_unref( pixmap 
); 
 363         gtk_widget_show( pw 
); 
 365         GtkWidget 
*close_button 
= gtk_button_new(); 
 366         gtk_container_add( GTK_CONTAINER(close_button
), pw 
); 
 368         gtk_pizza_put( GTK_PIZZA(m_mainWidget
), 
 370                          size
.x
-16, 4, 11, 11 ); 
 372         gtk_widget_show( close_button 
); 
 374         gtk_signal_connect( GTK_OBJECT(close_button
), "clicked", 
 375           GTK_SIGNAL_FUNC(gtk_button_clicked_callback
), (gpointer
*)this ); 
 378     /* these are called when the borders are drawn */ 
 379     gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event", 
 380         GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this ); 
 382     gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw", 
 383        GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this ); 
 385     /* these are required for dragging the mini frame around */ 
 386     gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "button_press_event", 
 387       GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this ); 
 389     gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "button_release_event", 
 390       GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this ); 
 392     gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "motion_notify_event", 
 393       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this ); 
 398 void wxMiniFrame::SetTitle( const wxString 
&title 
) 
 400     wxFrame::SetTitle( title 
); 
 402     gtk_widget_draw( m_mainWidget
, (GdkRectangle
*) NULL 
); 
 405 #endif // wxUSE_MINIFRAME