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"
16 #include "wx/settings.h"
19 #include "wx/dcscreen.h"
23 #include "wx/gtk/win_gtk.h"
24 #include "wx/gtk/private.h"
27 #include <gdk/gdkprivate.h>
30 //-----------------------------------------------------------------------------
32 //-----------------------------------------------------------------------------
34 extern bool g_blockEventsOnDrag
;
35 extern bool g_blockEventsOnScroll
;
36 extern GtkWidget
*wxGetRootWindow();
38 //-----------------------------------------------------------------------------
39 // "expose_event" of m_mainWidget
40 //-----------------------------------------------------------------------------
42 // StepColour() it a utility function that simply darkens
43 // or lightens a color, based on the specified percentage
44 static wxColor
StepColour(const wxColor
& c
, int percent
)
46 int r
= c
.Red(), g
= c
.Green(), b
= c
.Blue();
47 return wxColour((unsigned char)wxMin((r
*percent
)/100,255),
48 (unsigned char)wxMin((g
*percent
)/100,255),
49 (unsigned char)wxMin((b
*percent
)/100,255));
52 static wxColor
LightContrastColour(const wxColour
& c
)
56 // if the color is especially dark, then
57 // make the contrast even lighter
58 if (c
.Red() < 128 && c
.Green() < 128 && c
.Blue() < 128)
61 return StepColour(c
, amount
);
65 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxMiniFrame
*win
)
67 if (g_isIdle
) wxapp_install_idle_handler();
69 if (!win
->m_hasVMT
) return;
70 if (gdk_event
->count
> 0) return;
72 GtkPizza
*pizza
= GTK_PIZZA(widget
);
74 gtk_paint_shadow (widget
->style
,
78 NULL
, NULL
, NULL
, // FIXME: No clipping?
80 win
->m_width
, win
->m_height
);
82 int style
= win
->GetWindowStyle();
84 if (!win
->GetTitle().empty() &&
85 ((style
& wxCAPTION
) ||
86 (style
& wxTINY_CAPTION_HORIZ
) ||
87 (style
& wxTINY_CAPTION_VERT
)))
91 dc
.m_window
= pizza
->bin_window
;
93 dc
.SetFont( *wxSMALL_FONT
);
94 int height
= dc
.GetCharHeight();
96 wxBrush
brush( LightContrastColour( wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT
) ) );
98 dc
.SetPen( *wxTRANSPARENT_PEN
);
99 dc
.DrawRectangle( 3, 3, win
->m_width
- 7, height
-2 );
101 dc
.SetTextForeground( *wxWHITE
);
102 dc
.DrawText( win
->GetTitle(), 6, 3 );
104 if (style
& wxCLOSE_BOX
)
105 dc
.DrawBitmap( win
->m_closeButton
, win
->m_width
-19, 3, true );
110 //-----------------------------------------------------------------------------
111 // "button_press_event" of m_mainWidget
112 //-----------------------------------------------------------------------------
115 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxMiniFrame
*win
)
117 if (g_isIdle
) wxapp_install_idle_handler();
119 if (!win
->m_hasVMT
) return FALSE
;
120 if (g_blockEventsOnDrag
) return TRUE
;
121 if (g_blockEventsOnScroll
) return TRUE
;
123 if (win
->m_isDragging
) return TRUE
;
125 GtkPizza
*pizza
= GTK_PIZZA(widget
);
126 if (gdk_event
->window
!= pizza
->bin_window
) return TRUE
;
128 int y
= (int)gdk_event
->y
;
129 int x
= (int)gdk_event
->x
;
131 int style
= win
->GetWindowStyle();
132 if ((style
& wxCLOSE_BOX
) &&
133 ((style
& wxCAPTION
) || (style
& wxTINY_CAPTION_HORIZ
) || (style
& wxTINY_CAPTION_VERT
)))
135 if ((y
> 3) && (y
< 19) && (x
> win
->m_width
-19) && (x
< win
->m_width
-3))
143 dc
.SetFont( *wxSMALL_FONT
);
144 int height
= dc
.GetCharHeight() + 1;
147 if (y
> height
) return TRUE
;
149 gdk_window_raise( win
->m_widget
->window
);
151 gdk_pointer_grab( widget
->window
, FALSE
,
153 (GDK_BUTTON_PRESS_MASK
|
154 GDK_BUTTON_RELEASE_MASK
|
155 GDK_POINTER_MOTION_MASK
|
156 GDK_POINTER_MOTION_HINT_MASK
|
157 GDK_BUTTON_MOTION_MASK
|
158 GDK_BUTTON1_MOTION_MASK
),
161 (unsigned int) GDK_CURRENT_TIME
);
168 win
->m_isDragging
= true;
174 //-----------------------------------------------------------------------------
175 // "button_release_event" of m_mainWidget
176 //-----------------------------------------------------------------------------
179 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxMiniFrame
*win
)
181 if (g_isIdle
) wxapp_install_idle_handler();
183 if (!win
->m_hasVMT
) return FALSE
;
184 if (g_blockEventsOnDrag
) return TRUE
;
185 if (g_blockEventsOnScroll
) return TRUE
;
187 if (!win
->m_isDragging
) return TRUE
;
189 win
->m_isDragging
= false;
191 int x
= (int)gdk_event
->x
;
192 int y
= (int)gdk_event
->y
;
194 gdk_pointer_ungrab ( (guint32
)GDK_CURRENT_TIME
);
197 gdk_window_get_origin( widget
->window
, &org_x
, &org_y
);
198 x
+= org_x
- win
->m_diffX
;
199 y
+= org_y
- win
->m_diffY
;
202 gtk_window_move( GTK_WINDOW(win
->m_widget
), x
, y
);
208 //-----------------------------------------------------------------------------
209 // "motion_notify_event" of m_mainWidget
210 //-----------------------------------------------------------------------------
213 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxMiniFrame
*win
)
215 if (g_isIdle
) wxapp_install_idle_handler();
217 if (!win
->m_hasVMT
) return FALSE
;
218 if (g_blockEventsOnDrag
) return TRUE
;
219 if (g_blockEventsOnScroll
) return TRUE
;
221 if (!win
->m_isDragging
) return TRUE
;
223 if (gdk_event
->is_hint
)
227 GdkModifierType state
;
228 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
231 gdk_event
->state
= state
;
234 win
->m_oldX
= (int)gdk_event
->x
- win
->m_diffX
;
235 win
->m_oldY
= (int)gdk_event
->y
- win
->m_diffY
;
237 int x
= (int)gdk_event
->x
;
238 int y
= (int)gdk_event
->y
;
242 gdk_window_get_origin( widget
->window
, &org_x
, &org_y
);
243 x
+= org_x
- win
->m_diffX
;
244 y
+= org_y
- win
->m_diffY
;
247 gtk_window_move( GTK_WINDOW(win
->m_widget
), x
, y
);
254 //-----------------------------------------------------------------------------
256 //-----------------------------------------------------------------------------
258 static unsigned char close_bits
[]={
259 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
260 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
261 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
264 IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame
,wxFrame
)
266 bool wxMiniFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
267 const wxPoint
&pos
, const wxSize
&size
,
268 long style
, const wxString
&name
)
270 style
= style
| wxCAPTION
;
272 if ((style
& wxCAPTION
) || (style
& wxTINY_CAPTION_HORIZ
) || (style
& wxTINY_CAPTION_VERT
))
275 if (style
& wxRESIZE_BORDER
)
279 m_isDragging
= false;
285 wxFrame::Create( parent
, id
, title
, pos
, size
, style
, name
);
287 if (m_parent
&& (GTK_IS_WINDOW(m_parent
->m_widget
)))
289 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
292 if ((style
& wxCLOSE_BOX
) &&
293 ((style
& wxCAPTION
) || (style
& wxTINY_CAPTION_HORIZ
) || (style
& wxTINY_CAPTION_VERT
)))
295 wxImage img
= wxBitmap((const char*)close_bits
, 16, 16).ConvertToImage();
296 img
.Replace(255,255,255,123,123,123);
297 img
.Replace(0,0,0,255,255,255);
298 img
.SetMaskColour(123,123,123);
299 m_closeButton
= wxBitmap( img
);
302 /* these are called when the borders are drawn */
303 g_signal_connect (m_mainWidget
, "expose_event",
304 G_CALLBACK (gtk_window_own_expose_callback
), this );
306 /* these are required for dragging the mini frame around */
307 g_signal_connect (m_mainWidget
, "button_press_event",
308 G_CALLBACK (gtk_window_button_press_callback
), this);
309 g_signal_connect (m_mainWidget
, "button_release_event",
310 G_CALLBACK (gtk_window_button_release_callback
), this);
311 g_signal_connect (m_mainWidget
, "motion_notify_event",
312 G_CALLBACK (gtk_window_motion_notify_callback
), this);
317 void wxMiniFrame::SetTitle( const wxString
&title
)
319 wxFrame::SetTitle( title
);
321 gdk_window_invalidate_rect( GTK_PIZZA(m_mainWidget
)->bin_window
, NULL
, true );
324 #endif // wxUSE_MINIFRAME