1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/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/gtk/win_gtk.h" 
  23 #include "wx/gtk/private.h" 
  26 #include <gdk/gdkprivate.h> 
  29 //----------------------------------------------------------------------------- 
  31 //----------------------------------------------------------------------------- 
  33 extern bool        g_blockEventsOnDrag
; 
  34 extern bool        g_blockEventsOnScroll
; 
  35 extern GtkWidget  
*wxGetRootWindow(); 
  37 //----------------------------------------------------------------------------- 
  38 // "expose_event" of m_mainWidget 
  39 //----------------------------------------------------------------------------- 
  42 static void gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxFrame 
*win 
) 
  44     if (g_isIdle
) wxapp_install_idle_handler(); 
  46     if (!win
->m_hasVMT
) return; 
  47     if (gdk_event
->count 
> 0) return; 
  49     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
  51     gtk_paint_shadow (widget
->style
, 
  55                       NULL
, NULL
, NULL
, // FIXME: No clipping? 
  57                       win
->m_width
, win
->m_height
); 
  59     if (!win
->GetTitle().empty() && 
  60         ((win
->GetWindowStyle() & wxCAPTION
) || 
  61          (win
->GetWindowStyle() & wxTINY_CAPTION_HORIZ
) || 
  62          (win
->GetWindowStyle() & wxTINY_CAPTION_VERT
))) 
  65         dc
.SetFont( *wxSMALL_FONT 
); 
  66         int height 
= dc
.GetCharHeight(); 
  68         GdkGC 
*gc 
= gdk_gc_new( pizza
->bin_window 
); 
  69         gdk_gc_set_foreground( gc
, &widget
->style
->bg
[GTK_STATE_SELECTED
] ); 
  70         gdk_draw_rectangle( pizza
->bin_window
, gc
, TRUE
, 
  78         dc
.m_window 
= pizza
->bin_window
; 
  79         dc
.SetTextForeground( *wxWHITE 
); 
  80         dc
.DrawText( win
->GetTitle(), 6, 3 ); 
  85 //----------------------------------------------------------------------------- 
  86 // "button_press_event" of m_mainWidget 
  87 //----------------------------------------------------------------------------- 
  90 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxMiniFrame 
*win 
) 
  92     if (g_isIdle
) wxapp_install_idle_handler(); 
  94     if (!win
->m_hasVMT
) return FALSE
; 
  95     if (g_blockEventsOnDrag
) return TRUE
; 
  96     if (g_blockEventsOnScroll
) return TRUE
; 
  98     if (win
->m_isDragging
) return TRUE
; 
 100     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 101     if (gdk_event
->window 
!= pizza
->bin_window
) return TRUE
; 
 104     dc
.SetFont( *wxSMALL_FONT 
); 
 105     int height 
= dc
.GetCharHeight() + 1; 
 107     if (gdk_event
->y 
> height
) return TRUE
; 
 109     gdk_window_raise( win
->m_widget
->window 
); 
 111     gdk_pointer_grab( widget
->window
, FALSE
, 
 113                          (GDK_BUTTON_PRESS_MASK 
| 
 114                           GDK_BUTTON_RELEASE_MASK 
| 
 115                           GDK_POINTER_MOTION_MASK        
| 
 116                           GDK_POINTER_MOTION_HINT_MASK  
| 
 117                           GDK_BUTTON_MOTION_MASK        
| 
 118                           GDK_BUTTON1_MOTION_MASK
), 
 121                       (unsigned int) GDK_CURRENT_TIME 
); 
 123     win
->m_diffX 
= (int)gdk_event
->x
; 
 124     win
->m_diffY 
= (int)gdk_event
->y
; 
 128     win
->m_isDragging 
= true; 
 134 //----------------------------------------------------------------------------- 
 135 // "button_release_event" of m_mainWidget 
 136 //----------------------------------------------------------------------------- 
 139 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxMiniFrame 
*win 
) 
 141     if (g_isIdle
) wxapp_install_idle_handler(); 
 143     if (!win
->m_hasVMT
) return FALSE
; 
 144     if (g_blockEventsOnDrag
) return TRUE
; 
 145     if (g_blockEventsOnScroll
) return TRUE
; 
 147     if (!win
->m_isDragging
) return TRUE
; 
 149     win
->m_isDragging 
= false; 
 151     int x 
= (int)gdk_event
->x
; 
 152     int y 
= (int)gdk_event
->y
; 
 154     gdk_pointer_ungrab ( (guint32
)GDK_CURRENT_TIME 
); 
 157     gdk_window_get_origin( widget
->window
, &org_x
, &org_y 
); 
 158     x 
+= org_x 
- win
->m_diffX
; 
 159     y 
+= org_y 
- win
->m_diffY
; 
 162     gtk_window_move( GTK_WINDOW(win
->m_widget
), x
, y 
); 
 168 //----------------------------------------------------------------------------- 
 169 // "motion_notify_event" of m_mainWidget 
 170 //----------------------------------------------------------------------------- 
 173 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxMiniFrame 
*win 
) 
 175     if (g_isIdle
) wxapp_install_idle_handler(); 
 177     if (!win
->m_hasVMT
) return FALSE
; 
 178     if (g_blockEventsOnDrag
) return TRUE
; 
 179     if (g_blockEventsOnScroll
) return TRUE
; 
 181     if (!win
->m_isDragging
) return TRUE
; 
 183     if (gdk_event
->is_hint
) 
 187        GdkModifierType state
; 
 188        gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 191        gdk_event
->state 
= state
; 
 194     win
->m_oldX 
= (int)gdk_event
->x 
- win
->m_diffX
; 
 195     win
->m_oldY 
= (int)gdk_event
->y 
- win
->m_diffY
; 
 197     int x 
= (int)gdk_event
->x
; 
 198     int y 
= (int)gdk_event
->y
; 
 202     gdk_window_get_origin( widget
->window
, &org_x
, &org_y 
); 
 203     x 
+= org_x 
- win
->m_diffX
; 
 204     y 
+= org_y 
- win
->m_diffY
; 
 207     gtk_window_move( GTK_WINDOW(win
->m_widget
), x
, y 
); 
 214 //----------------------------------------------------------------------------- 
 215 // "clicked" of X system button 
 216 //----------------------------------------------------------------------------- 
 219 static void gtk_button_clicked_callback( GtkWidget 
*WXUNUSED(widget
), wxMiniFrame 
*mf 
) 
 221     if (g_isIdle
) wxapp_install_idle_handler(); 
 227 //----------------------------------------------------------------------------- 
 229 //----------------------------------------------------------------------------- 
 231 static const char *cross_xpm
[] = { 
 232 /* columns rows colors chars-per-pixel */ 
 244 IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame
,wxFrame
) 
 246 bool wxMiniFrame::Create( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
 247       const wxPoint 
&pos
, const wxSize 
&size
, 
 248       long style
, const wxString 
&name 
) 
 250     style 
= style 
| wxCAPTION
; 
 252     if ((style 
& wxCAPTION
) || (style 
& wxTINY_CAPTION_HORIZ
) || (style 
& wxTINY_CAPTION_VERT
)) 
 256     m_isDragging 
= false; 
 262     wxFrame::Create( parent
, id
, title
, pos
, size
, style
, name 
); 
 264     if (m_parent 
&& (GTK_IS_WINDOW(m_parent
->m_widget
))) 
 266         gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) ); 
 269     if ((style 
& wxSYSTEM_MENU
) && 
 270         ((style 
& wxCAPTION
) || (style 
& wxTINY_CAPTION_HORIZ
) || (style 
& wxTINY_CAPTION_VERT
))) 
 272         GdkBitmap 
*mask 
= (GdkBitmap
*) NULL
; 
 273         GdkPixmap 
*pixmap 
= gdk_pixmap_create_from_xpm_d
 
 275                                 wxGetRootWindow()->window
, 
 281         GtkWidget 
*pw 
= gtk_pixmap_new( pixmap
, mask 
); 
 282         g_object_unref (mask
); 
 283         g_object_unref (pixmap
); 
 284         gtk_widget_show( pw 
); 
 286         GtkWidget 
*close_button 
= gtk_button_new(); 
 288         if (!gtk_check_version(2,4,0)) 
 289             gtk_button_set_focus_on_click( GTK_BUTTON(close_button
), FALSE 
); 
 291         gtk_container_add( GTK_CONTAINER(close_button
), pw 
); 
 293         gtk_pizza_put( GTK_PIZZA(m_mainWidget
), 
 295                          size
.x
-16, 4, 11, 11 ); 
 297         gtk_widget_show( close_button 
); 
 299         g_signal_connect (close_button
, "clicked", 
 300                           G_CALLBACK (gtk_button_clicked_callback
), 
 304     /* these are called when the borders are drawn */ 
 305     g_signal_connect (m_mainWidget
, "expose_event", 
 306                       G_CALLBACK (gtk_window_own_expose_callback
), this ); 
 308     /* these are required for dragging the mini frame around */ 
 309     g_signal_connect (m_mainWidget
, "button_press_event", 
 310                       G_CALLBACK (gtk_window_button_press_callback
), this); 
 311     g_signal_connect (m_mainWidget
, "button_release_event", 
 312                       G_CALLBACK (gtk_window_button_release_callback
), this); 
 313     g_signal_connect (m_mainWidget
, "motion_notify_event", 
 314                       G_CALLBACK (gtk_window_motion_notify_callback
), this); 
 319 void wxMiniFrame::SetTitle( const wxString 
&title 
) 
 321     wxFrame::SetTitle( title 
); 
 323     gdk_window_invalidate_rect( GTK_PIZZA(m_mainWidget
)->bin_window
, NULL
, true ); 
 326 #endif // wxUSE_MINIFRAME