1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/themes/gtk.cpp
3 // Purpose: wxUniversal theme implementing GTK-like LNF
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
30 #include "wx/dcmemory.h"
31 #include "wx/window.h"
35 #include "wx/bmpbuttn.h"
36 #include "wx/button.h"
37 #include "wx/checkbox.h"
38 #include "wx/listbox.h"
39 #include "wx/checklst.h"
40 #include "wx/combobox.h"
41 #include "wx/scrolbar.h"
42 #include "wx/slider.h"
43 #include "wx/textctrl.h"
44 #include "wx/toolbar.h"
45 #include "wx/statusbr.h"
47 #include "wx/settings.h"
48 #include "wx/toplevel.h"
52 #include "wx/notebook.h"
53 #include "wx/spinbutt.h"
54 #include "wx/artprov.h"
55 #ifdef wxUSE_TOGGLEBTN
56 #include "wx/tglbtn.h"
57 #endif // wxUSE_TOGGLEBTN
59 #include "wx/univ/stdrend.h"
60 #include "wx/univ/inpcons.h"
61 #include "wx/univ/inphand.h"
62 #include "wx/univ/colschem.h"
63 #include "wx/univ/theme.h"
65 class WXDLLEXPORT wxGTKMenuGeometryInfo
;
67 // ----------------------------------------------------------------------------
69 // ----------------------------------------------------------------------------
71 // standard border size
72 static const int BORDER_THICKNESS
= 2;
74 // ----------------------------------------------------------------------------
75 // wxGTKRenderer: draw the GUI elements in GTK style
76 // ----------------------------------------------------------------------------
78 class wxGTKRenderer
: public wxStdRenderer
81 wxGTKRenderer(const wxColourScheme
*scheme
);
84 virtual void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
85 virtual void DrawTextBorder(wxDC
& dc
,
89 wxRect
*rectIn
= NULL
);
90 virtual void DrawButtonLabel(wxDC
& dc
,
91 const wxString
& label
,
92 const wxBitmap
& image
,
98 virtual void DrawButtonBorder(wxDC
& dc
,
101 wxRect
*rectIn
= NULL
);
102 virtual void DrawArrow(wxDC
& dc
,
106 virtual void DrawScrollbarArrow(wxDC
& dc
,
110 virtual void DrawScrollbarThumb(wxDC
& dc
,
111 wxOrientation orient
,
114 virtual void DrawScrollbarShaft(wxDC
& dc
,
115 wxOrientation orient
,
120 virtual void DrawToolBarButton(wxDC
& dc
,
121 const wxString
& label
,
122 const wxBitmap
& bitmap
,
127 #endif // wxUSE_TOOLBAR
130 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
131 #endif // wxUSE_TEXTCTRL
134 virtual void DrawTab(wxDC
& dc
,
137 const wxString
& label
,
138 const wxBitmap
& bitmap
= wxNullBitmap
,
140 int indexAccel
= -1);
141 #endif // wxUSE_NOTEBOOK
144 virtual void DrawSliderShaft(wxDC
& dc
,
147 wxOrientation orient
,
150 wxRect
*rectShaft
= NULL
);
151 virtual void DrawSliderThumb(wxDC
& dc
,
153 wxOrientation orient
,
156 virtual void DrawSliderTicks(wxDC
& WXUNUSED(dc
),
157 const wxRect
& WXUNUSED(rect
),
158 int WXUNUSED(lenThumb
),
159 wxOrientation
WXUNUSED(orient
),
162 int WXUNUSED(step
) = 1,
163 int WXUNUSED(flags
) = 0,
164 long WXUNUSED(style
) = 0)
166 // we don't have the ticks in GTK version
168 #endif // wxUSE_SLIDER
171 virtual void DrawMenuBarItem(wxDC
& dc
,
173 const wxString
& label
,
175 int indexAccel
= -1);
176 virtual void DrawMenuItem(wxDC
& dc
,
178 const wxMenuGeometryInfo
& geometryInfo
,
179 const wxString
& label
,
180 const wxString
& accel
,
181 const wxBitmap
& bitmap
= wxNullBitmap
,
183 int indexAccel
= -1);
184 virtual void DrawMenuSeparator(wxDC
& dc
,
186 const wxMenuGeometryInfo
& geomInfo
);
187 #endif // wxUSE_MENUS
189 virtual void DrawFrameTitleBar(wxDC
& dc
,
191 const wxString
& title
,
194 int specialButton
= 0,
195 int specialButtonFlag
= 0);
196 virtual void DrawFrameBorder(wxDC
& dc
,
199 virtual void DrawFrameBackground(wxDC
& dc
,
202 virtual void DrawFrameTitle(wxDC
& dc
,
204 const wxString
& title
,
206 virtual void DrawFrameIcon(wxDC
& dc
,
210 virtual void DrawFrameButton(wxDC
& dc
,
211 wxCoord x
, wxCoord y
,
216 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
217 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
218 virtual wxSize
GetFrameMinSize(int flags
) const;
219 virtual wxSize
GetFrameIconSize() const;
220 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
222 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
224 wxBitmap
*bmpPressed
,
225 wxBitmap
*bmpDisabled
);
227 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
229 // geometry and hit testing
230 virtual wxSize
GetScrollbarArrowSize() const
231 { return m_sizeScrollbarArrow
; }
233 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
234 wxScrollBar::Element elem
,
235 int thumbPos
= -1) const;
236 #endif // wxUSE_SCROLLBAR
238 virtual wxSize
GetCheckBitmapSize() const
239 { return wxSize(10, 10); }
240 virtual wxSize
GetRadioBitmapSize() const
241 { return wxSize(11, 11); }
242 virtual wxCoord
GetCheckItemMargin() const
245 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
246 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
247 virtual wxSize
GetToolBarMargin() const
248 { return wxSize(6, 6); }
251 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
253 wxCoord
*extraSpaceBeyond
) const;
254 #endif // wxUSE_TEXTCTRL
257 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
258 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
259 #endif // wxUSE_NOTEBOOK
262 virtual wxCoord
GetSliderDim() const { return 15; }
263 virtual wxCoord
GetSliderTickLen() const { return 0; }
264 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
266 wxOrientation orient
,
267 long style
= 0) const;
268 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
270 wxOrientation orient
) const;
271 #endif // wxUSE_SLIDER
273 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
276 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
277 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
278 const wxMenu
& menu
) const;
279 #endif // wxUSE_MENUS
281 // helpers for "wxBitmap wxColourScheme::Get()"
282 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
283 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
284 void DrawUndeterminedBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
287 // overridden wxStdRenderer methods
288 virtual void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
290 virtual void DrawFrameWithLabel(wxDC
& dc
,
291 const wxString
& label
,
292 const wxRect
& rectFrame
,
293 const wxRect
& rectText
,
298 virtual void DrawCheckItemBitmap(wxDC
& dc
,
299 const wxBitmap
& bitmap
,
303 // get the colour to use for background
304 wxColour
GetBackgroundColour(int flags
) const
306 if ( flags
& wxCONTROL_PRESSED
)
307 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
308 else if ( flags
& wxCONTROL_CURRENT
)
309 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
311 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
314 // as DrawShadedRect() but the pixels in the bottom left and upper right
315 // border are drawn with the pen1, not pen2
316 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
317 const wxPen
& pen1
, const wxPen
& pen2
);
319 // used for drawing opened rectangles - draws only one side of it at once
320 // (and doesn't adjust the rect)
321 void DrawAntiShadedRectSide(wxDC
& dc
,
327 // draw an opened rect for the arrow in given direction
328 void DrawArrowBorder(wxDC
& dc
,
332 // draw two sides of the rectangle
333 void DrawThumbBorder(wxDC
& dc
,
335 wxOrientation orient
);
337 // just as DrawRaisedBorder() except that the bottom left and up right
338 // pixels of the interior rect are drawn in another colour (i.e. the inner
339 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
340 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
342 // draw inner GTK shadow
343 void DrawInnerShadedRect(wxDC
& dc
, wxRect
*rect
);
346 // returns the size of the arrow for the scrollbar (depends on
348 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
351 if ( scrollbar
->IsVertical() )
353 size
= m_sizeScrollbarArrow
;
357 size
.x
= m_sizeScrollbarArrow
.y
;
358 size
.y
= m_sizeScrollbarArrow
.x
;
363 #endif // wxUSE_SCROLLBAR
365 // get the line wrap indicator bitmap
366 wxBitmap
GetLineWrapBitmap() const;
368 virtual wxBitmap
GetCheckBitmap(int flags
);
369 virtual wxBitmap
GetRadioBitmap(int flags
);
371 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
373 void DrawUpZag(wxDC
& dc
,
374 wxCoord x1
, wxCoord x2
,
375 wxCoord y1
, wxCoord y2
);
376 void DrawDownZag(wxDC
& dc
,
377 wxCoord x1
, wxCoord x2
,
378 wxCoord y1
, wxCoord y2
);
380 // draw the radio button bitmap for the given state
381 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
383 // common part of DrawMenuItem() and DrawMenuBarItem()
384 void DoDrawMenuItem(wxDC
& dc
,
386 const wxString
& label
,
389 const wxString
& accel
= wxEmptyString
,
390 const wxBitmap
& bitmap
= wxNullBitmap
,
391 const wxGTKMenuGeometryInfo
*geometryInfo
= NULL
);
393 // initialize the combo bitmaps
394 void InitComboBitmaps();
397 const wxColourScheme
*m_scheme
;
400 wxSize m_sizeScrollbarArrow
;
405 // the checkbox and radio button bitmaps: first row is for the normal,
406 // second for the pressed state and the columns are for checked, unchecked
407 // and undeterminated respectively
408 wxBitmap m_bitmapsCheckbox
[IndicatorState_MaxCtrl
][IndicatorStatus_Max
],
409 m_bitmapsRadiobtn
[IndicatorState_MaxCtrl
][IndicatorStatus_Max
];
411 // the line wrap bitmap (drawn at the end of wrapped lines)
412 wxBitmap m_bmpLineWrap
;
414 // the combobox bitmaps
424 wxBitmap m_bitmapsCombo
[ComboState_Max
];
427 // ----------------------------------------------------------------------------
428 // wxGTKInputHandler and derived classes: process the keyboard and mouse
429 // messages according to GTK standards
430 // ----------------------------------------------------------------------------
432 class wxGTKInputHandler
: public wxInputHandler
435 wxGTKInputHandler() { }
437 virtual bool HandleKey(wxInputConsumer
*control
,
438 const wxKeyEvent
& event
,
440 virtual bool HandleMouse(wxInputConsumer
*control
,
441 const wxMouseEvent
& event
);
442 virtual bool HandleMouseMove(wxInputConsumer
*control
,
443 const wxMouseEvent
& event
);
448 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
451 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
452 : wxStdScrollBarInputHandler(renderer
, handler
) { }
455 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
457 // only arrows and the thumb can be highlighted
458 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
461 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
464 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
466 // only arrows can be pressed
470 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
473 // any button can be used to drag the scrollbar under GTK+
474 virtual bool IsAllowedButton(int WXUNUSED(button
)) const { return true; }
478 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
479 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
483 #endif // wxUSE_SCROLLBAR
487 class wxGTKCheckboxInputHandler
: public wxStdInputHandler
490 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
491 : wxStdInputHandler(handler
) { }
493 virtual bool HandleKey(wxInputConsumer
*control
,
494 const wxKeyEvent
& event
,
498 #endif // wxUSE_CHECKBOX
502 class wxGTKTextCtrlInputHandler
: public wxStdInputHandler
505 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
506 : wxStdInputHandler(handler
) { }
508 virtual bool HandleKey(wxInputConsumer
*control
,
509 const wxKeyEvent
& event
,
513 #endif // wxUSE_TEXTCTRL
515 // ----------------------------------------------------------------------------
516 // wxGTKColourScheme: uses the standard GTK colours
517 // ----------------------------------------------------------------------------
519 class wxGTKColourScheme
: public wxColourScheme
522 virtual wxColour
Get(StdColour col
) const;
523 virtual wxColour
GetBackground(wxWindow
*win
) const;
526 // ----------------------------------------------------------------------------
528 // ----------------------------------------------------------------------------
530 class wxGTKArtProvider
: public wxArtProvider
533 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
534 const wxArtClient
& client
,
538 // ----------------------------------------------------------------------------
540 // ----------------------------------------------------------------------------
542 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
544 class wxGTKTheme
: public wxTheme
548 virtual ~wxGTKTheme();
550 virtual wxRenderer
*GetRenderer();
551 virtual wxArtProvider
*GetArtProvider();
552 virtual wxInputHandler
*GetInputHandler(const wxString
& control
,
553 wxInputConsumer
*consumer
);
554 virtual wxColourScheme
*GetColourScheme();
557 wxGTKRenderer
*m_renderer
;
559 wxGTKArtProvider
*m_artProvider
;
561 // the names of the already created handlers and the handlers themselves
562 // (these arrays are synchronized)
563 wxSortedArrayString m_handlerNames
;
564 wxArrayHandlers m_handlers
;
566 wxGTKColourScheme
*m_scheme
;
568 WX_DECLARE_THEME(gtk
)
571 // ============================================================================
573 // ============================================================================
575 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
577 // ----------------------------------------------------------------------------
579 // ----------------------------------------------------------------------------
581 wxGTKTheme::wxGTKTheme()
585 m_artProvider
= NULL
;
588 wxGTKTheme::~wxGTKTheme()
592 wxArtProvider::RemoveProvider(m_artProvider
);
595 wxRenderer
*wxGTKTheme::GetRenderer()
599 m_renderer
= new wxGTKRenderer(GetColourScheme());
605 wxArtProvider
*wxGTKTheme::GetArtProvider()
607 if ( !m_artProvider
)
609 m_artProvider
= new wxGTKArtProvider
;
612 return m_artProvider
;
615 wxColourScheme
*wxGTKTheme::GetColourScheme()
619 m_scheme
= new wxGTKColourScheme
;
624 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
,
625 wxInputConsumer
*consumer
)
627 wxInputHandler
*handler
= NULL
;
628 int n
= m_handlerNames
.Index(control
);
629 if ( n
== wxNOT_FOUND
)
631 static wxGTKInputHandler s_handlerDef
;
633 wxInputHandler
* const
634 handlerStd
= consumer
->DoGetStdInputHandler(&s_handlerDef
);
636 // create a new handler
638 if ( control
== wxINP_HANDLER_CHECKBOX
)
640 static wxGTKCheckboxInputHandler
s_handler(handlerStd
);
642 handler
= &s_handler
;
645 #endif // wxUSE_CHECKBOX
647 if ( control
== wxINP_HANDLER_SCROLLBAR
)
649 static wxGTKScrollBarInputHandler
s_handler(m_renderer
, handlerStd
);
651 handler
= &s_handler
;
654 #endif // wxUSE_SCROLLBAR
656 if ( control
== wxINP_HANDLER_TEXTCTRL
)
658 static wxGTKTextCtrlInputHandler
s_handler(handlerStd
);
660 handler
= &s_handler
;
663 #endif // wxUSE_TEXTCTRL
665 // no special handler for this control
666 handler
= handlerStd
;
669 n
= m_handlerNames
.Add(control
);
670 m_handlers
.Insert(handler
, n
);
672 else // we already have it
674 handler
= m_handlers
[n
];
680 // ============================================================================
682 // ============================================================================
684 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
687 if ( win
->UseBgCol() )
689 // use the user specified colour
690 col
= win
->GetBackgroundColour();
693 if ( !win
->ShouldInheritColours() )
695 // doesn't depend on the state
703 int flags
= win
->GetStateFlags();
705 // the colour set by the user should be used for the normal state
706 // and for the states for which we don't have any specific colours
707 if ( !col
.Ok() || (flags
!= 0) )
710 if ( wxDynamicCast(win
, wxScrollBar
) )
711 col
= Get(SCROLLBAR
);
713 #endif //wxUSE_SCROLLBAR
714 if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
715 col
= Get(CONTROL_CURRENT
);
716 else if ( flags
& wxCONTROL_PRESSED
)
717 col
= Get(CONTROL_PRESSED
);
726 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
730 case WINDOW
: return *wxWHITE
;
732 case SHADOW_DARK
: return *wxBLACK
;
733 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
734 case SHADOW_IN
: return wxColour(0xd6d6d6);
735 case SHADOW_OUT
: return wxColour(0x969696);
737 case CONTROL
: return wxColour(0xd6d6d6);
738 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
739 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
741 case CONTROL_TEXT
: return *wxBLACK
;
742 case CONTROL_TEXT_DISABLED
:
743 return wxColour(0x757575);
744 case CONTROL_TEXT_DISABLED_SHADOW
:
748 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
750 case HIGHLIGHT
: return wxColour(0x9c0000);
751 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
753 case GAUGE
: return Get(CONTROL_CURRENT
);
755 case TITLEBAR
: return wxColour(0xaeaaae);
756 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
757 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
758 case TITLEBAR_ACTIVE_TEXT
:
761 case DESKTOP
: return *wxBLACK
;
765 wxFAIL_MSG(_T("invalid standard colour"));
770 // ============================================================================
772 // ============================================================================
774 // ----------------------------------------------------------------------------
776 // ----------------------------------------------------------------------------
778 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
779 : wxStdRenderer(scheme
)
781 m_sizeScrollbarArrow
= wxSize(15, 14);
783 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
));
786 // ----------------------------------------------------------------------------
788 // ----------------------------------------------------------------------------
790 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
796 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
801 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
802 rect
.GetLeft(), rect
.GetBottom() + 1);
806 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
807 rect
.GetRight() + 1, rect
.GetTop());
811 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
812 rect
.GetRight(), rect
.GetBottom() + 1);
816 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
817 rect
.GetRight() + 1, rect
.GetBottom());
821 wxFAIL_MSG(_T("unknown rectangle side"));
825 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
826 const wxPen
& pen1
, const wxPen
& pen2
)
828 // draw the rectangle
830 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
831 rect
->GetLeft(), rect
->GetBottom() + 1);
832 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
833 rect
->GetRight() + 1, rect
->GetTop());
835 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
836 rect
->GetRight(), rect
->GetBottom());
837 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
838 rect
->GetRight() + 1, rect
->GetBottom());
844 void wxGTKRenderer::DrawInnerShadedRect(wxDC
& dc
, wxRect
*rect
)
846 DrawAntiShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
847 DrawAntiShadedRect(dc
, rect
, m_penBlack
, m_penHighlight
);
850 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
852 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
853 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
856 void wxGTKRenderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
858 DrawAntiShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
859 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
862 void wxGTKRenderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
864 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
865 wxRect rectFocus
= rect
;
866 DrawRect(dc
, &rectFocus
, m_penBlack
);
869 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
871 const wxRect
& rectOrig
,
875 wxRect rect
= rectOrig
;
877 if ( border
!= wxBORDER_NONE
)
879 if ( flags
& wxCONTROL_FOCUSED
)
881 DrawRect(dc
, &rect
, m_penBlack
);
882 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
886 DrawInnerShadedRect(dc
, &rect
);
894 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
895 const wxString
& label
,
896 const wxBitmap
& image
,
903 // no focus rect around buttons label in GTK+
904 wxStdRenderer::DrawButtonLabel(dc
, label
, image
, rect
, flags
,
905 alignment
, indexAccel
, rectBounds
);
908 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
909 const wxRect
& rectTotal
,
913 wxRect rect
= rectTotal
;
915 if ( flags
& wxCONTROL_PRESSED
)
917 // button pressed: draw a black border around it and an inward shade
918 DrawRect(dc
, &rect
, m_penBlack
);
920 DrawInnerShadedRect(dc
, &rect
);
922 else // button not pressed
924 if ( flags
& wxCONTROL_ISDEFAULT
)
929 if ( flags
& wxCONTROL_FOCUSED
)
931 // button is currently default: add an extra border around it
932 DrawRect(dc
, &rect
, m_penBlack
);
935 // now draw a normal button
936 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
937 DrawAntiShadedRect(dc
, &rect
, GetBackgroundColour(flags
), m_penDarkGrey
);
944 // ----------------------------------------------------------------------------
946 // ----------------------------------------------------------------------------
948 void wxGTKRenderer::DrawFrameWithLabel(wxDC
& dc
,
949 const wxString
& label
,
950 const wxRect
& rectFrame
,
951 const wxRect
& rectTextOrig
,
956 wxRect
rectText(rectTextOrig
);
957 rectText
.Inflate(1, 0);
960 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
962 rectLabel
.width
+= 2;
964 DrawFrameWithoutLabel(dc
, rectFrame
, rectLabel
);
966 // GTK+ does it like this
967 dc
.SetPen(m_penHighlight
);
968 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
969 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
972 // ----------------------------------------------------------------------------
973 // check/radion buttons
974 // ----------------------------------------------------------------------------
976 void wxGTKRenderer::DrawCheckItemBitmap(wxDC
& dc
,
977 const wxBitmap
& bitmap
,
981 // never draw the focus rect around the check indicators here
982 DrawCheckButton(dc
, wxEmptyString
, bitmap
, rect
, flags
& ~wxCONTROL_FOCUSED
);
985 void wxGTKRenderer::DrawUndeterminedBitmap(wxDC
& dc
,
986 const wxRect
& rectTotal
,
989 // FIXME: For sure it is not GTK look but it is better than nothing.
990 // Show me correct look and I will immediatelly make it better (ABX)
991 wxRect rect
= rectTotal
;
997 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
998 col2
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1002 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1003 col2
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1006 dc
.SetPen(*wxTRANSPARENT_PEN
);
1008 dc
.DrawRectangle(rect
);
1011 dc
.DrawRectangle(rect
);
1014 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1015 const wxRect
& rectTotal
,
1018 wxRect rect
= rectTotal
;
1019 DrawAntiRaisedBorder(dc
, &rect
);
1021 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1022 dc
.SetPen(wxPen(col
));
1023 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1026 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1027 //else: it is SHADOW_IN, leave as is
1029 dc
.SetPen(*wxTRANSPARENT_PEN
);
1031 dc
.DrawRectangle(rect
);
1034 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1036 wxRect rect
= rectTotal
;
1037 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1038 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1040 dc
.SetPen(*wxTRANSPARENT_PEN
);
1041 dc
.SetBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
));
1042 dc
.DrawRectangle(rect
);
1045 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1051 xRight
= rect
.GetRight(),
1052 yBottom
= rect
.GetBottom();
1054 wxCoord yMid
= (y
+ yBottom
) / 2;
1056 // then draw the upper half
1057 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1058 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1059 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1062 if ( flags
& wxCONTROL_CHECKED
)
1063 dc
.SetPen(m_penBlack
);
1064 else if ( flags
& wxCONTROL_PRESSED
)
1065 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
)));
1066 else // unchecked and unpressed
1070 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1072 // and then the lower one
1073 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1074 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1075 if ( !(flags
& wxCONTROL_CHECKED
) )
1076 dc
.SetPen(m_penDarkGrey
);
1077 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1079 if ( !(flags
& wxCONTROL_CHECKED
) )
1080 drawIt
= true; // with the same pen
1081 else if ( flags
& wxCONTROL_PRESSED
)
1083 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
)));
1086 else // checked and unpressed
1090 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1093 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1099 wxCoord xMid
= (x1
+ x2
) / 2;
1100 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1101 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1104 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1110 wxCoord xMid
= (x1
+ x2
) / 2;
1111 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1112 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1115 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1117 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1119 // init the bitmaps once only
1121 wxSize size
= GetCheckBitmapSize();
1122 rect
.width
= size
.x
;
1123 rect
.height
= size
.y
;
1124 for ( int i
= 0; i
< 2; i
++ )
1126 for ( int j
= 0; j
< 3; j
++ )
1127 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1133 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1134 DrawCheckBitmap(dc
, rect
);
1137 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1138 DrawUncheckBitmap(dc
, rect
, false);
1140 // normal undeterminated
1141 dc
.SelectObject(m_bitmapsCheckbox
[0][2]);
1142 DrawUndeterminedBitmap(dc
, rect
, false);
1145 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1147 // pressed unchecked
1148 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1149 DrawUncheckBitmap(dc
, rect
, true);
1151 // pressed undeterminated
1152 dc
.SelectObject(m_bitmapsCheckbox
[1][2]);
1153 DrawUndeterminedBitmap(dc
, rect
, true);
1156 IndicatorState state
;
1157 IndicatorStatus status
;
1158 GetIndicatorsFromFlags(flags
, state
, status
);
1160 // disabled looks the same as normal
1161 if ( state
== IndicatorState_Disabled
)
1162 state
= IndicatorState_Normal
;
1164 return m_bitmapsCheckbox
[state
][status
];
1167 wxBitmap
wxGTKRenderer::GetRadioBitmap(int flags
)
1169 IndicatorState state
;
1170 IndicatorStatus status
;
1171 GetIndicatorsFromFlags(flags
, state
, status
);
1173 wxBitmap
& bmp
= m_bitmapsRadiobtn
[state
][status
];
1176 const wxSize size
= GetRadioBitmapSize();
1179 bmp
.Create(size
.x
, size
.y
);
1180 dc
.SelectObject(bmp
);
1182 DrawRadioBitmap(dc
, size
, flags
);
1188 wxBitmap
wxGTKRenderer::GetLineWrapBitmap() const
1190 if ( !m_bmpLineWrap
.Ok() )
1192 // the line wrap bitmap as used by GTK+
1193 #define line_wrap_width 6
1194 #define line_wrap_height 9
1195 static const char line_wrap_bits
[] =
1197 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1200 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1201 if ( !bmpLineWrap
.Ok() )
1203 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1207 wxConstCast(this, wxGTKRenderer
)->m_bmpLineWrap
= bmpLineWrap
;
1211 return m_bmpLineWrap
;
1215 void wxGTKRenderer::DrawToolBarButton(wxDC
& dc
,
1216 const wxString
& label
,
1217 const wxBitmap
& bitmap
,
1218 const wxRect
& rectOrig
,
1220 long WXUNUSED(style
),
1223 // we don't draw the separators at all
1224 if ( !label
.empty() || bitmap
.Ok() )
1226 wxRect rect
= rectOrig
;
1227 rect
.Deflate(BORDER_THICKNESS
);
1229 if ( flags
& wxCONTROL_PRESSED
)
1231 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
, &rect
);
1233 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), rect
);
1235 else if ( flags
& wxCONTROL_CURRENT
)
1237 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rect
);
1239 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rect
);
1242 if(tbarStyle
& wxTB_TEXT
)
1244 if(tbarStyle
& wxTB_HORIZONTAL
)
1246 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1250 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
1255 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
1256 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
1257 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
1261 #endif // wxUSE_TOOLBAR
1263 // ----------------------------------------------------------------------------
1265 // ----------------------------------------------------------------------------
1269 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1271 wxCoord
*extraSpaceBeyond
) const
1274 rectText
= wxStdRenderer::GetTextClientArea(text
, rect
, extraSpaceBeyond
);
1276 if ( text
->WrapLines() )
1278 // leave enough for the line wrap bitmap indicator
1279 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1281 rectText
.width
-= widthMark
;
1283 if ( extraSpaceBeyond
)
1284 *extraSpaceBeyond
= widthMark
;
1290 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1292 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1294 // for a mono bitmap he colours it appears in depends on the current text
1295 // colours, so set them correctly
1297 if ( bmpLineWrap
.GetDepth() == 1 )
1299 colFgOld
= dc
.GetTextForeground();
1301 // FIXME: I wonder what should we do if the background is black too?
1302 dc
.SetTextForeground(*wxBLACK
);
1305 dc
.DrawBitmap(bmpLineWrap
,
1306 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1308 if ( colFgOld
.Ok() )
1310 // restore old colour
1311 dc
.SetTextForeground(colFgOld
);
1315 #endif // wxUSE_TEXTCTRL
1317 // ----------------------------------------------------------------------------
1319 // ----------------------------------------------------------------------------
1323 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1324 const wxRect
& rectOrig
,
1326 const wxString
& label
,
1327 const wxBitmap
& bitmap
,
1331 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1332 #define REVERSE_FOR_VERTICAL(X,Y) \
1333 SELECT_FOR_VERTICAL(X,Y) \
1335 SELECT_FOR_VERTICAL(Y,X)
1337 wxRect rect
= rectOrig
;
1339 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1341 // the current tab is drawn indented (to the top for default case) and
1342 // bigger than the other ones
1343 const wxSize indent
= GetTabIndent();
1344 if ( flags
& wxCONTROL_SELECTED
)
1346 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1347 SELECT_FOR_VERTICAL( 0, indent
.y
));
1351 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1358 rect
.height
+= indent
.y
;
1365 rect
.width
+= indent
.x
;
1370 // selected tab has different colour
1371 wxColour col
= flags
& wxCONTROL_SELECTED
1372 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1373 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1374 DrawSolidRect(dc
, col
, rect
);
1376 if ( flags
& wxCONTROL_FOCUSED
)
1378 // draw the focus rect
1379 wxRect rectBorder
= rect
;
1380 rectBorder
.Deflate(4, 3);
1381 if ( dir
== wxBOTTOM
)
1382 rectBorder
.Offset(0, -1);
1383 if ( dir
== wxRIGHT
)
1384 rectBorder
.Offset(-1, 0);
1386 DrawRect(dc
, &rectBorder
, m_penBlack
);
1389 // draw the text, image and the focus around them (if necessary)
1390 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1391 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1393 rectLabel
.Deflate(1, 1);
1396 // draw it horizontally into memory and rotate for screen
1398 wxBitmap bitmapRotated
,
1399 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1400 rectLabel
.y
+ rectLabel
.height
);
1401 dcMem
.SelectObject(bitmapMem
);
1402 dcMem
.SetBackground(dc
.GetBackground());
1403 dcMem
.SetFont(dc
.GetFont());
1404 dcMem
.SetTextForeground(dc
.GetTextForeground());
1408 wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) )
1411 #endif // wxUSE_IMAGE
1413 dcMem
.DrawLabel(label
, bitmapRotated
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1414 dcMem
.SelectObject(wxNullBitmap
);
1415 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1417 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
))
1421 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1425 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1428 // now draw the tab itself
1429 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1430 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1431 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1432 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1438 // left orientation looks like top but IsVertical makes x and y reversed
1440 // top is not vertical so use coordinates in written order
1441 dc
.SetPen(m_penHighlight
);
1442 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1443 REVERSE_FOR_VERTICAL(x
, y
));
1444 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
),
1445 REVERSE_FOR_VERTICAL(x2
, y
));
1447 dc
.SetPen(m_penBlack
);
1448 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1449 REVERSE_FOR_VERTICAL(x2
, y
));
1451 dc
.SetPen(m_penDarkGrey
);
1452 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1453 REVERSE_FOR_VERTICAL(x2
- 1, y
+ 1));
1455 if ( flags
& wxCONTROL_SELECTED
)
1457 dc
.SetPen(m_penLightGrey
);
1459 // overwrite the part of the border below this tab
1460 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1461 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1463 // and the shadow of the tab to the left of us
1464 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ 2),
1465 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1470 // right orientation looks like bottom but IsVertical makes x and y reversed
1472 // bottom is not vertical so use coordinates in written order
1473 dc
.SetPen(m_penHighlight
);
1475 // we need to continue one pixel further to overwrite the corner of
1476 // the border for the selected tab
1477 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
1478 REVERSE_FOR_VERTICAL(x
, y2
));
1480 // it doesn't work like this (TODO: implement it properly)
1482 // erase the corner of the tab to the right
1483 dc
.SetPen(m_penLightGrey
);
1484 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1485 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 2));
1486 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 1));
1489 dc
.SetPen(m_penBlack
);
1490 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
),
1491 REVERSE_FOR_VERTICAL(x2
, y2
));
1492 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
1493 REVERSE_FOR_VERTICAL(x2
, y2
));
1495 dc
.SetPen(m_penDarkGrey
);
1496 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 2, y2
- 1),
1497 REVERSE_FOR_VERTICAL(x2
- 1, y2
- 1));
1498 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
1499 REVERSE_FOR_VERTICAL(x2
- 1, y2
));
1501 if ( flags
& wxCONTROL_SELECTED
)
1503 dc
.SetPen(m_penLightGrey
);
1505 // overwrite the part of the (double!) border above this tab
1506 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
1507 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
1508 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
1509 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1511 // and the shadow of the tab to the left of us
1512 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- 1),
1513 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
1519 #endif // wxUSE_NOTEBOOK
1521 // ----------------------------------------------------------------------------
1523 // ----------------------------------------------------------------------------
1527 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1529 wxOrientation orient
) const
1531 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1535 wxRect rectShaft
= GetSliderShaftRect(rect
, lenThumb
, orient
);
1536 if ( orient
== wxHORIZONTAL
)
1538 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1539 size
.y
= rectShaft
.height
;
1543 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1544 size
.x
= rectShaft
.width
;
1550 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1551 int WXUNUSED(lenThumb
),
1552 wxOrientation
WXUNUSED(orient
),
1553 long WXUNUSED(style
)) const
1555 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
1558 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
1559 const wxRect
& rectOrig
,
1560 int WXUNUSED(lenThumb
),
1561 wxOrientation
WXUNUSED(orient
),
1563 long WXUNUSED(style
),
1566 wxRect rect
= rectOrig
;
1568 // draw the border first
1569 if ( flags
& wxCONTROL_FOCUSED
)
1571 DrawRect(dc
, &rect
, m_penBlack
);
1573 else // not focused, normal
1575 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1578 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1580 // and the background
1581 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
1587 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
1588 const wxRect
& rectOrig
,
1589 wxOrientation orient
,
1590 int WXUNUSED(flags
),
1591 long WXUNUSED(style
))
1593 // draw the thumb border
1594 wxRect rect
= rectOrig
;
1595 DrawAntiRaisedBorder(dc
, &rect
);
1597 // draw the handle in the middle
1598 if ( orient
== wxVERTICAL
)
1600 rect
.height
= 2*BORDER_THICKNESS
;
1601 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
1605 rect
.width
= 2*BORDER_THICKNESS
;
1606 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
1609 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1612 #endif // wxUSE_SLIDER
1616 // ----------------------------------------------------------------------------
1618 // ----------------------------------------------------------------------------
1620 // wxGTKMenuGeometryInfo: the wxMenuGeometryInfo used by wxGTKRenderer
1621 class WXDLLEXPORT wxGTKMenuGeometryInfo
: public wxMenuGeometryInfo
1624 virtual wxSize
GetSize() const { return m_size
; }
1626 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
1627 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
1629 wxCoord
GetItemHeight() const { return m_heightItem
; }
1632 // the total size of the menu
1635 // the offset of the start of the menu item label
1638 // the offset of the start of the accel label
1641 // the height of a normal (not separator) item
1642 wxCoord m_heightItem
;
1644 friend wxMenuGeometryInfo
*
1645 wxGTKRenderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
1648 // FIXME: all constants are hardcoded but shouldn't be
1649 static const wxCoord MENU_LEFT_MARGIN
= 9;
1650 static const wxCoord MENU_RIGHT_MARGIN
= 6;
1652 static const wxCoord MENU_HORZ_MARGIN
= 6;
1653 static const wxCoord MENU_VERT_MARGIN
= 3;
1655 // the margin around bitmap/check marks (on each side)
1656 static const wxCoord MENU_BMP_MARGIN
= 2;
1658 // the margin between the labels and accel strings
1659 static const wxCoord MENU_ACCEL_MARGIN
= 8;
1661 // the separator height in pixels: in fact, strangely enough, the real height
1662 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
1664 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
1666 // the size of the standard checkmark bitmap
1667 static const wxCoord MENU_CHECK_SIZE
= 9;
1669 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
1671 const wxString
& label
,
1675 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
);
1678 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
1680 const wxMenuGeometryInfo
& gi
,
1681 const wxString
& label
,
1682 const wxString
& accel
,
1683 const wxBitmap
& bitmap
,
1687 const wxGTKMenuGeometryInfo
& geomInfo
= (const wxGTKMenuGeometryInfo
&)gi
;
1692 rect
.width
= geomInfo
.GetSize().x
;
1693 rect
.height
= geomInfo
.GetItemHeight();
1695 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
, accel
, bitmap
, &geomInfo
);
1698 void wxGTKRenderer::DoDrawMenuItem(wxDC
& dc
,
1699 const wxRect
& rectOrig
,
1700 const wxString
& label
,
1703 const wxString
& accel
,
1704 const wxBitmap
& bitmap
,
1705 const wxGTKMenuGeometryInfo
*geometryInfo
)
1707 wxRect rect
= rectOrig
;
1709 // draw the selected item specially
1710 if ( flags
& wxCONTROL_SELECTED
)
1713 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
1715 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rectIn
);
1718 rect
.Deflate(MENU_HORZ_MARGIN
, MENU_VERT_MARGIN
);
1720 // draw the bitmap: use the bitmap provided or the standard checkmark for
1721 // the checkable items
1724 wxBitmap bmp
= bitmap
;
1725 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKABLE
) )
1727 bmp
= GetCheckBitmap(flags
);
1732 rect
.SetRight(geometryInfo
->GetLabelOffset());
1733 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
1736 //else: menubar items don't have bitmaps
1741 rect
.x
= geometryInfo
->GetLabelOffset();
1742 rect
.SetRight(geometryInfo
->GetAccelOffset());
1745 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1747 // draw the accel string
1748 if ( !accel
.empty() )
1750 // menubar items shouldn't have them
1751 wxCHECK_RET( geometryInfo
, _T("accel strings only valid for menus") );
1753 rect
.x
= geometryInfo
->GetAccelOffset();
1754 rect
.SetRight(geometryInfo
->GetSize().x
);
1756 // NB: no accel index here
1757 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
1760 // draw the submenu indicator
1761 if ( flags
& wxCONTROL_ISSUBMENU
)
1763 wxCHECK_RET( geometryInfo
, _T("wxCONTROL_ISSUBMENU only valid for menus") );
1765 rect
.x
= geometryInfo
->GetSize().x
- MENU_RIGHT_MARGIN
;
1766 rect
.width
= MENU_RIGHT_MARGIN
;
1768 DrawArrow(dc
, wxRIGHT
, rect
, flags
);
1772 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
1774 const wxMenuGeometryInfo
& geomInfo
)
1776 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
1779 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
1781 wxSize size
= sizeText
;
1783 // TODO: make this configurable
1784 size
.x
+= 2*MENU_HORZ_MARGIN
;
1785 size
.y
+= 2*MENU_VERT_MARGIN
;
1790 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
1791 const wxMenu
& menu
) const
1793 // prepare the dc: for now we draw all the items with the system font
1795 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
1797 // the height of a normal item
1798 wxCoord heightText
= dc
.GetCharHeight();
1803 // the max length of label and accel strings: the menu width is the sum of
1804 // them, even if they're for different items (as the accels should be
1807 // the max length of the bitmap is never 0 as Windows always leaves enough
1808 // space for a check mark indicator
1809 wxCoord widthLabelMax
= 0,
1811 widthBmpMax
= MENU_LEFT_MARGIN
;
1813 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
1815 node
= node
->GetNext() )
1817 // height of this item
1820 wxMenuItem
*item
= node
->GetData();
1821 if ( item
->IsSeparator() )
1823 h
= MENU_SEPARATOR_HEIGHT
;
1825 else // not separator
1830 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
1831 if ( widthLabel
> widthLabelMax
)
1833 widthLabelMax
= widthLabel
;
1837 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
1838 if ( widthAccel
> widthAccelMax
)
1840 widthAccelMax
= widthAccel
;
1843 const wxBitmap
& bmp
= item
->GetBitmap();
1846 wxCoord widthBmp
= bmp
.GetWidth();
1847 if ( widthBmp
> widthBmpMax
)
1848 widthBmpMax
= widthBmp
;
1850 //else if ( item->IsCheckable() ): no need to check for this as
1851 // MENU_LEFT_MARGIN is big enough to show the check mark
1854 h
+= 2*MENU_VERT_MARGIN
;
1856 // remember the item position and height
1857 item
->SetGeometry(height
, h
);
1862 // bundle the metrics into a struct and return it
1863 wxGTKMenuGeometryInfo
*gi
= new wxGTKMenuGeometryInfo
;
1865 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
1866 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
1867 if ( widthAccelMax
> 0 )
1869 // if we actually have any accesl, add a margin
1870 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
1873 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
1875 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
1876 gi
->m_size
.y
= height
;
1881 #endif // wxUSE_MENUS
1883 // ----------------------------------------------------------------------------
1885 // ----------------------------------------------------------------------------
1887 void wxGTKRenderer::InitComboBitmaps()
1889 wxSize sizeArrow
= m_sizeScrollbarArrow
;
1895 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1897 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
1900 static const int comboButtonFlags
[ComboState_Max
] =
1908 wxRect
rect(sizeArrow
);
1911 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1913 int flags
= comboButtonFlags
[n
];
1915 dc
.SelectObject(m_bitmapsCombo
[n
]);
1916 DrawSolidRect(dc
, GetBackgroundColour(flags
), rect
);
1917 DrawArrow(dc
, wxDOWN
, rect
, flags
);
1921 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
1923 wxBitmap
*bmpPressed
,
1924 wxBitmap
*bmpDisabled
)
1926 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
1932 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
1934 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
1936 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
1938 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
1941 // ----------------------------------------------------------------------------
1943 // ----------------------------------------------------------------------------
1945 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
1949 static const wxDirection sides
[] =
1951 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
1954 wxRect rect1
, rect2
, rectInner
;
1960 rectInner
.Inflate(-2);
1962 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
1964 // find the side not to draw and also adjust the rectangles to compensate
1966 wxDirection sideToOmit
;
1970 sideToOmit
= wxDOWN
;
1972 rectInner
.height
+= 1;
1980 rectInner
.height
+= 1;
1984 sideToOmit
= wxRIGHT
;
1986 rectInner
.width
+= 1;
1990 sideToOmit
= wxLEFT
;
1994 rectInner
.width
+= 1;
1998 wxFAIL_MSG(_T("unknown arrow direction"));
2002 // the outer rect first
2004 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2006 wxDirection side
= sides
[n
];
2007 if ( side
== sideToOmit
)
2010 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
2013 // and then the inner one
2014 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2016 wxDirection side
= sides
[n
];
2017 if ( side
== sideToOmit
)
2020 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
2026 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
2028 const wxRect
& rectArrow
,
2031 // first of all, draw the border around it - but we don't want the border
2032 // on the side opposite to the arrow point
2033 wxRect rect
= rectArrow
;
2034 DrawArrowBorder(dc
, &rect
, dir
);
2036 // then the arrow itself
2037 DrawArrow(dc
, dir
, rect
, flags
);
2040 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
2041 // these people are just crazy :-(
2042 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2055 wxPoint ptArrow
[Point_Max
];
2057 wxColour colInside
= GetBackgroundColour(flags
);
2059 if ( flags
& wxCONTROL_DISABLED
)
2061 penShadow
[0] = m_penDarkGrey
;
2062 penShadow
[1] = m_penDarkGrey
;
2063 penShadow
[2] = wxNullPen
;
2064 penShadow
[3] = wxNullPen
;
2066 else if ( flags
& wxCONTROL_PRESSED
)
2068 penShadow
[0] = m_penDarkGrey
;
2069 penShadow
[1] = m_penHighlight
;
2070 penShadow
[2] = wxNullPen
;
2071 penShadow
[3] = m_penBlack
;
2073 else // normal arrow
2075 penShadow
[0] = m_penHighlight
;
2076 penShadow
[1] = m_penBlack
;
2077 penShadow
[2] = m_penDarkGrey
;
2078 penShadow
[3] = wxNullPen
;
2082 if ( dir
== wxUP
|| dir
== wxDOWN
)
2085 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2089 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2092 // draw the arrow interior
2093 dc
.SetPen(*wxTRANSPARENT_PEN
);
2094 dc
.SetBrush(colInside
);
2099 ptArrow
[Point_First
].x
= rect
.GetLeft();
2100 ptArrow
[Point_First
].y
= rect
.GetBottom();
2101 ptArrow
[Point_Second
].x
= middle
;
2102 ptArrow
[Point_Second
].y
= rect
.GetTop();
2103 ptArrow
[Point_Third
].x
= rect
.GetRight();
2104 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2108 ptArrow
[Point_First
] = rect
.GetPosition();
2109 ptArrow
[Point_Second
].x
= middle
;
2110 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2111 ptArrow
[Point_Third
].x
= rect
.GetRight();
2112 ptArrow
[Point_Third
].y
= rect
.GetTop();
2116 ptArrow
[Point_First
].x
= rect
.GetRight();
2117 ptArrow
[Point_First
].y
= rect
.GetTop();
2118 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2119 ptArrow
[Point_Second
].y
= middle
;
2120 ptArrow
[Point_Third
].x
= rect
.GetRight();
2121 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2125 ptArrow
[Point_First
] = rect
.GetPosition();
2126 ptArrow
[Point_Second
].x
= rect
.GetRight();
2127 ptArrow
[Point_Second
].y
= middle
;
2128 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2129 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2133 wxFAIL_MSG(_T("unknown arrow direction"));
2136 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2138 // draw the arrow border
2139 dc
.SetPen(penShadow
[0]);
2143 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2144 dc
.DrawPoint(ptArrow
[Point_First
]);
2145 if ( penShadow
[3].Ok() )
2147 dc
.SetPen(penShadow
[3]);
2148 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2149 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2151 dc
.SetPen(penShadow
[1]);
2152 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2153 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2154 dc
.DrawPoint(ptArrow
[Point_Third
]);
2155 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2156 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2157 if ( penShadow
[2].Ok() )
2159 dc
.SetPen(penShadow
[2]);
2160 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2161 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2162 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2163 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2168 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2169 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2170 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2171 if ( penShadow
[2].Ok() )
2173 dc
.SetPen(penShadow
[2]);
2174 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2175 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2177 dc
.SetPen(penShadow
[1]);
2178 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2179 dc
.DrawPoint(ptArrow
[Point_Third
]);
2183 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2184 dc
.DrawPoint(ptArrow
[Point_First
]);
2185 if ( penShadow
[2].Ok() )
2187 dc
.SetPen(penShadow
[2]);
2188 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2189 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2190 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2191 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2193 dc
.SetPen(penShadow
[1]);
2194 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2195 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2196 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2197 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2201 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2202 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2203 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2204 dc
.SetPen(penShadow
[1]);
2205 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2206 dc
.DrawPoint(ptArrow
[Point_Third
]);
2210 wxFAIL_MSG(_T("unknown arrow direction"));
2215 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2217 wxOrientation orient
)
2219 if ( orient
== wxVERTICAL
)
2221 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2223 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2225 rect
->Inflate(-1, 0);
2227 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2229 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2231 rect
->Inflate(-1, 0);
2235 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2237 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2239 rect
->Inflate(0, -1);
2241 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2243 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2245 rect
->Inflate(0, -1);
2249 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2250 wxOrientation orient
,
2254 // the thumb is never pressed never has focus border under GTK and the
2255 // scrollbar background never changes at all
2256 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2258 // we don't want the border in the direction of the scrollbar movement
2259 wxRect rectThumb
= rect
;
2260 DrawThumbBorder(dc
, &rectThumb
, orient
);
2262 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2263 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2266 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2267 wxOrientation orient
,
2269 int WXUNUSED(flags
))
2271 wxRect rectBar
= rect
;
2272 DrawThumbBorder(dc
, &rectBar
, orient
);
2273 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2277 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2278 wxScrollBar::Element elem
,
2281 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2282 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2284 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2286 elem
= wxScrollBar::Element_Bar_2
;
2289 return wxStdRenderer::GetScrollbarRect(scrollbar
, elem
, thumbPos
);
2292 #endif // wxUSE_SCROLLBAR
2294 // ----------------------------------------------------------------------------
2296 // ----------------------------------------------------------------------------
2298 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2301 if ( wxDynamicCast(window
, wxBitmapButton
) )
2306 #endif // wxUSE_BMPBUTTON
2307 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
2310 || wxDynamicCast(window
, wxButton
)
2311 # endif // wxUSE_BUTTON
2312 # if wxUSE_TOGGLEBTN
2313 || wxDynamicCast(window
, wxToggleButton
)
2314 # endif // wxUSE_TOGGLEBTN
2317 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2319 // TODO: this is ad hoc...
2320 size
->x
+= 3*window
->GetCharWidth();
2321 wxCoord minBtnHeight
= 18;
2322 if ( size
->y
< minBtnHeight
)
2323 size
->y
= minBtnHeight
;
2325 // button border width
2329 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
2331 if ( wxDynamicCast(window
, wxScrollBar
) )
2333 // we only set the width of vert scrollbars and height of the
2335 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2336 size
->y
= m_sizeScrollbarArrow
.x
;
2338 size
->x
= m_sizeScrollbarArrow
.x
;
2341 #endif // wxUSE_SCROLLBAR
2343 // take into account the border width
2344 wxStdRenderer::AdjustSize(size
, window
);
2348 // ----------------------------------------------------------------------------
2349 // top level windows
2350 // ----------------------------------------------------------------------------
2352 void wxGTKRenderer::DrawFrameTitleBar(wxDC
& WXUNUSED(dc
),
2353 const wxRect
& WXUNUSED(rect
),
2354 const wxString
& WXUNUSED(title
),
2355 const wxIcon
& WXUNUSED(icon
),
2356 int WXUNUSED(flags
),
2357 int WXUNUSED(specialButton
),
2358 int WXUNUSED(specialButtonFlag
))
2362 void wxGTKRenderer::DrawFrameBorder(wxDC
& WXUNUSED(dc
),
2363 const wxRect
& WXUNUSED(rect
),
2364 int WXUNUSED(flags
))
2368 void wxGTKRenderer::DrawFrameBackground(wxDC
& WXUNUSED(dc
),
2369 const wxRect
& WXUNUSED(rect
),
2370 int WXUNUSED(flags
))
2374 void wxGTKRenderer::DrawFrameTitle(wxDC
& WXUNUSED(dc
),
2375 const wxRect
& WXUNUSED(rect
),
2376 const wxString
& WXUNUSED(title
),
2377 int WXUNUSED(flags
))
2381 void wxGTKRenderer::DrawFrameIcon(wxDC
& WXUNUSED(dc
),
2382 const wxRect
& WXUNUSED(rect
),
2383 const wxIcon
& WXUNUSED(icon
),
2384 int WXUNUSED(flags
))
2388 void wxGTKRenderer::DrawFrameButton(wxDC
& WXUNUSED(dc
),
2389 wxCoord
WXUNUSED(x
),
2390 wxCoord
WXUNUSED(y
),
2391 int WXUNUSED(button
),
2392 int WXUNUSED(flags
))
2397 wxGTKRenderer::GetFrameClientArea(const wxRect
& rect
,
2398 int WXUNUSED(flags
)) const
2404 wxGTKRenderer::GetFrameTotalSize(const wxSize
& clientSize
,
2405 int WXUNUSED(flags
)) const
2410 wxSize
wxGTKRenderer::GetFrameMinSize(int WXUNUSED(flags
)) const
2415 wxSize
wxGTKRenderer::GetFrameIconSize() const
2417 return wxSize(wxDefaultCoord
, wxDefaultCoord
);
2421 wxGTKRenderer::HitTestFrame(const wxRect
& WXUNUSED(rect
),
2422 const wxPoint
& WXUNUSED(pt
),
2423 int WXUNUSED(flags
)) const
2425 return wxHT_TOPLEVEL_CLIENT_AREA
;
2429 // ----------------------------------------------------------------------------
2431 // ----------------------------------------------------------------------------
2433 /* Copyright (c) Julian Smart */
2434 static const char *error_xpm
[] = {
2435 /* columns rows colors chars-per-pixel */
2449 " ................. ",
2450 " ................... ",
2451 " ....................... ",
2452 " ......................... ",
2453 " ........................... ",
2454 " ...........................X ",
2455 " .............................X ",
2456 " ............................... ",
2457 " ...............................X ",
2458 " .................................X ",
2459 " .................................X ",
2460 " .................................XX ",
2461 " ...ooooooooooooooooooooooooooo...XX ",
2462 " ....ooooooooooooooooooooooooooo....X ",
2463 " ....ooooooooooooooooooooooooooo....X ",
2464 " ....ooooooooooooooooooooooooooo....XX ",
2465 " ....ooooooooooooooooooooooooooo....XX ",
2466 " ....ooooooooooooooooooooooooooo....XX ",
2467 " ...ooooooooooooooooooooooooooo...XXX ",
2468 " ...ooooooooooooooooooooooooooo...XXX ",
2469 " .................................XX ",
2470 " .................................XX ",
2471 " ...............................XXX ",
2472 " ...............................XXX ",
2473 " .............................XXX ",
2474 " ...........................XXXX ",
2475 " ...........................XXX ",
2476 " .........................XXX ",
2477 " .......................XXXX ",
2478 " X...................XXXXX ",
2479 " X.................XXXXX ",
2480 " X.............XXXXX ",
2481 " XXXX.....XXXXXXXX ",
2492 /* Copyright (c) Julian Smart */
2493 static const char *info_xpm
[] = {
2494 /* columns rows colors chars-per-pixel */
2518 " .XXXOXXXXXXXoo. ",
2519 " .XOOXXX+XXXXXo. ",
2520 " .XOOOXX+++XXXXoo. ",
2521 " .XOOXXX+++XXXXXo. ",
2522 " .XOOOXXX+++XXXXXXo. ",
2523 " .XOOXXXX+++XXXXXXo. ",
2524 " .XXXXXXX+++XXXXXXX. ",
2525 " .XXXXXXX+++XXXXXXo. ",
2526 " .XXXXXXX+++XXXXXoo. ",
2527 " .XXXXXX+++XXXXXo. ",
2528 " .XXXXXXX+XXXXXXo. ",
2529 " .XXXXXXXXXXXXo. ",
2530 " .XXXXX+++XXXoo. ",
2556 /* Copyright (c) Julian Smart */
2557 static const char *warning_xpm
[] = {
2558 /* columns rows colors chars-per-pixel */
2588 " ..XXXXO@#XXX... ",
2589 " ...XXXXO@#XXXX.. ",
2590 " ..XXXXXO@#XXXX... ",
2591 " ...XXXXXo@OXXXXX.. ",
2592 " ...XXXXXXo@OXXXXXX.. ",
2593 " ..XXXXXXX$@OXXXXXX... ",
2594 " ...XXXXXXXX@XXXXXXXX.. ",
2595 " ...XXXXXXXXXXXXXXXXXX... ",
2596 " ..XXXXXXXXXXOXXXXXXXXX.. ",
2597 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
2598 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
2599 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
2600 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
2601 " .............................. ",
2602 " .............................. ",
2620 /* Copyright (c) Julian Smart */
2621 static const char *question_xpm
[] = {
2622 /* columns rows colors chars-per-pixel */
2652 " ..XXXXoooooXXXO+ ",
2653 " ..XXooooooooooooX@.. ",
2654 " ..XoooooooooooooooXX#. ",
2655 " $%XoooooooooooooooooXX#. ",
2656 " &.XoooooooXXXXXXooooooXX.. ",
2657 " .XooooooXX.$...$XXoooooX*. ",
2658 " $.XoooooX%.$ .*oooooo=.. ",
2659 " .XooooooX.. -.XoooooX.. ",
2660 " .XoooooX..+ .XoooooX;. ",
2661 " ...XXXX..: .XoooooX;. ",
2662 " ........ >.XoooooX;. ",
2696 wxBitmap
wxGTKArtProvider::CreateBitmap(const wxArtID
& id
,
2697 const wxArtClient
& WXUNUSED(client
),
2698 const wxSize
& WXUNUSED(size
))
2700 if ( id
== wxART_INFORMATION
)
2701 return wxBitmap(info_xpm
);
2702 if ( id
== wxART_ERROR
)
2703 return wxBitmap(error_xpm
);
2704 if ( id
== wxART_WARNING
)
2705 return wxBitmap(warning_xpm
);
2706 if ( id
== wxART_QUESTION
)
2707 return wxBitmap(question_xpm
);
2708 return wxNullBitmap
;
2712 // ============================================================================
2714 // ============================================================================
2716 // ----------------------------------------------------------------------------
2717 // wxGTKInputHandler
2718 // ----------------------------------------------------------------------------
2720 bool wxGTKInputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
2721 const wxKeyEvent
& WXUNUSED(event
),
2722 bool WXUNUSED(pressed
))
2727 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
2728 const wxMouseEvent
& event
)
2730 // clicking on the control gives it focus
2731 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
2733 control
->GetInputWindow()->SetFocus();
2741 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
2742 const wxMouseEvent
& event
)
2744 if ( event
.Entering() )
2746 control
->GetInputWindow()->SetCurrent(true);
2748 else if ( event
.Leaving() )
2750 control
->GetInputWindow()->SetCurrent(false);
2762 // ----------------------------------------------------------------------------
2763 // wxGTKCheckboxInputHandler
2764 // ----------------------------------------------------------------------------
2766 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
2767 const wxKeyEvent
& event
,
2772 int keycode
= event
.GetKeyCode();
2773 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
2775 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
2784 #endif // wxUSE_CHECKBOX
2788 // ----------------------------------------------------------------------------
2789 // wxGTKTextCtrlInputHandler
2790 // ----------------------------------------------------------------------------
2792 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
2793 const wxKeyEvent
& event
,
2796 // handle only GTK-specific text bindings here, the others are handled in
2800 wxControlAction action
;
2801 int keycode
= event
.GetKeyCode();
2802 if ( event
.ControlDown() )
2807 action
= wxACTION_TEXT_HOME
;
2811 action
= wxACTION_TEXT_LEFT
;
2815 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
2819 action
= wxACTION_TEXT_END
;
2823 action
= wxACTION_TEXT_RIGHT
;
2827 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
2831 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2835 action
= wxACTION_TEXT_DOWN
;
2839 action
= wxACTION_TEXT_UP
;
2843 //delete the entire line
2844 control
->PerformAction(wxACTION_TEXT_HOME
);
2845 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2849 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
2853 else if ( event
.AltDown() )
2858 action
= wxACTION_TEXT_WORD_LEFT
;
2862 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
2866 action
= wxACTION_TEXT_WORD_RIGHT
;
2871 if ( action
!= wxACTION_NONE
)
2873 control
->PerformAction(action
);
2879 return wxStdInputHandler::HandleKey(control
, event
, pressed
);
2882 #endif // wxUSE_TEXTCTRL