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
,
118 virtual void DrawScrollCorner(wxDC
& dc
,
122 virtual void DrawToolBarButton(wxDC
& dc
,
123 const wxString
& label
,
124 const wxBitmap
& bitmap
,
129 #endif // wxUSE_TOOLBAR
132 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
133 #endif // wxUSE_TEXTCTRL
136 virtual void DrawTab(wxDC
& dc
,
139 const wxString
& label
,
140 const wxBitmap
& bitmap
= wxNullBitmap
,
142 int indexAccel
= -1);
143 #endif // wxUSE_NOTEBOOK
146 virtual void DrawSliderShaft(wxDC
& dc
,
149 wxOrientation orient
,
152 wxRect
*rectShaft
= NULL
);
153 virtual void DrawSliderThumb(wxDC
& dc
,
155 wxOrientation orient
,
158 virtual void DrawSliderTicks(wxDC
& WXUNUSED(dc
),
159 const wxRect
& WXUNUSED(rect
),
160 int WXUNUSED(lenThumb
),
161 wxOrientation
WXUNUSED(orient
),
164 int WXUNUSED(step
) = 1,
165 int WXUNUSED(flags
) = 0,
166 long WXUNUSED(style
) = 0)
168 // we don't have the ticks in GTK version
170 #endif // wxUSE_SLIDER
173 virtual void DrawMenuBarItem(wxDC
& dc
,
175 const wxString
& label
,
177 int indexAccel
= -1);
178 virtual void DrawMenuItem(wxDC
& dc
,
180 const wxMenuGeometryInfo
& geometryInfo
,
181 const wxString
& label
,
182 const wxString
& accel
,
183 const wxBitmap
& bitmap
= wxNullBitmap
,
185 int indexAccel
= -1);
186 virtual void DrawMenuSeparator(wxDC
& dc
,
188 const wxMenuGeometryInfo
& geomInfo
);
189 #endif // wxUSE_MENUS
192 virtual void DrawStatusField(wxDC
& dc
,
194 const wxString
& label
,
195 int flags
= 0, int style
= 0);
196 #endif // wxUSE_STATUSBAR
198 virtual void DrawFrameTitleBar(wxDC
& dc
,
200 const wxString
& title
,
203 int specialButton
= 0,
204 int specialButtonFlag
= 0);
205 virtual void DrawFrameBorder(wxDC
& dc
,
208 virtual void DrawFrameBackground(wxDC
& dc
,
211 virtual void DrawFrameTitle(wxDC
& dc
,
213 const wxString
& title
,
215 virtual void DrawFrameIcon(wxDC
& dc
,
219 virtual void DrawFrameButton(wxDC
& dc
,
220 wxCoord x
, wxCoord y
,
225 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
226 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
227 virtual wxSize
GetFrameMinSize(int flags
) const;
228 virtual wxSize
GetFrameIconSize() const;
229 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
231 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
233 wxBitmap
*bmpPressed
,
234 wxBitmap
*bmpDisabled
);
236 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
238 // geometry and hit testing
239 virtual wxSize
GetScrollbarArrowSize() const
240 { return m_sizeScrollbarArrow
; }
242 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
243 wxScrollBar::Element elem
,
244 int thumbPos
= -1) const;
245 #endif // wxUSE_SCROLLBAR
247 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
248 { return fontHeight
+ 2; }
249 virtual wxSize
GetCheckBitmapSize() const
250 { return wxSize(10, 10); }
251 virtual wxSize
GetRadioBitmapSize() const
252 { return wxSize(11, 11); }
253 virtual wxCoord
GetCheckItemMargin() const
256 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
257 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
258 virtual wxSize
GetToolBarMargin() const
259 { return wxSize(6, 6); }
262 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
264 wxCoord
*extraSpaceBeyond
) const;
265 #endif // wxUSE_TEXTCTRL
268 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
269 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
270 #endif // wxUSE_NOTEBOOK
273 virtual wxCoord
GetSliderDim() const { return 15; }
274 virtual wxCoord
GetSliderTickLen() const { return 0; }
275 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
277 wxOrientation orient
,
278 long style
= 0) const;
279 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
281 wxOrientation orient
) const;
282 #endif // wxUSE_SLIDER
284 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
287 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
288 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
289 const wxMenu
& menu
) const;
290 #endif // wxUSE_MENUS
293 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
294 #endif // wxUSE_STATUSBAR
296 // helpers for "wxBitmap wxColourScheme::Get()"
297 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
298 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
299 void DrawUndeterminedBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
302 // overridden wxStdRenderer methods
303 virtual void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
305 virtual void DrawFrameWithLabel(wxDC
& dc
,
306 const wxString
& label
,
307 const wxRect
& rectFrame
,
308 const wxRect
& rectText
,
313 virtual void DrawCheckItemBitmap(wxDC
& dc
,
314 const wxBitmap
& bitmap
,
318 // get the colour to use for background
319 wxColour
GetBackgroundColour(int flags
) const
321 if ( flags
& wxCONTROL_PRESSED
)
322 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
323 else if ( flags
& wxCONTROL_CURRENT
)
324 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
326 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
329 // as DrawShadedRect() but the pixels in the bottom left and upper right
330 // border are drawn with the pen1, not pen2
331 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
332 const wxPen
& pen1
, const wxPen
& pen2
);
334 // used for drawing opened rectangles - draws only one side of it at once
335 // (and doesn't adjust the rect)
336 void DrawAntiShadedRectSide(wxDC
& dc
,
342 // draw an opened rect for the arrow in given direction
343 void DrawArrowBorder(wxDC
& dc
,
347 // draw two sides of the rectangle
348 void DrawThumbBorder(wxDC
& dc
,
350 wxOrientation orient
);
352 // just as DrawRaisedBorder() except that the bottom left and up right
353 // pixels of the interior rect are drawn in another colour (i.e. the inner
354 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
355 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
357 // draw inner GTK shadow
358 void DrawInnerShadedRect(wxDC
& dc
, wxRect
*rect
);
361 // returns the size of the arrow for the scrollbar (depends on
363 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
366 if ( scrollbar
->IsVertical() )
368 size
= m_sizeScrollbarArrow
;
372 size
.x
= m_sizeScrollbarArrow
.y
;
373 size
.y
= m_sizeScrollbarArrow
.x
;
378 #endif // wxUSE_SCROLLBAR
380 // get the line wrap indicator bitmap
381 wxBitmap
GetLineWrapBitmap() const;
383 virtual wxBitmap
GetCheckBitmap(int flags
);
384 virtual wxBitmap
GetRadioBitmap(int flags
);
386 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
388 void DrawUpZag(wxDC
& dc
,
389 wxCoord x1
, wxCoord x2
,
390 wxCoord y1
, wxCoord y2
);
391 void DrawDownZag(wxDC
& dc
,
392 wxCoord x1
, wxCoord x2
,
393 wxCoord y1
, wxCoord y2
);
395 // draw the radio button bitmap for the given state
396 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
398 // common part of DrawMenuItem() and DrawMenuBarItem()
399 void DoDrawMenuItem(wxDC
& dc
,
401 const wxString
& label
,
404 const wxString
& accel
= wxEmptyString
,
405 const wxBitmap
& bitmap
= wxNullBitmap
,
406 const wxGTKMenuGeometryInfo
*geometryInfo
= NULL
);
408 // initialize the combo bitmaps
409 void InitComboBitmaps();
412 const wxColourScheme
*m_scheme
;
415 wxSize m_sizeScrollbarArrow
;
420 // the checkbox and radio button bitmaps: first row is for the normal,
421 // second for the pressed state and the columns are for checked, unchecked
422 // and undeterminated respectively
423 wxBitmap m_bitmapsCheckbox
[IndicatorState_MaxCtrl
][IndicatorStatus_Max
],
424 m_bitmapsRadiobtn
[IndicatorState_MaxCtrl
][IndicatorStatus_Max
];
426 // the line wrap bitmap (drawn at the end of wrapped lines)
427 wxBitmap m_bmpLineWrap
;
429 // the combobox bitmaps
439 wxBitmap m_bitmapsCombo
[ComboState_Max
];
442 // ----------------------------------------------------------------------------
443 // wxGTKInputHandler and derived classes: process the keyboard and mouse
444 // messages according to GTK standards
445 // ----------------------------------------------------------------------------
447 class wxGTKInputHandler
: public wxInputHandler
450 wxGTKInputHandler() { }
452 virtual bool HandleKey(wxInputConsumer
*control
,
453 const wxKeyEvent
& event
,
455 virtual bool HandleMouse(wxInputConsumer
*control
,
456 const wxMouseEvent
& event
);
457 virtual bool HandleMouseMove(wxInputConsumer
*control
,
458 const wxMouseEvent
& event
);
463 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
466 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
467 : wxStdScrollBarInputHandler(renderer
, handler
) { }
470 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
472 // only arrows and the thumb can be highlighted
473 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
476 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
479 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
481 // only arrows can be pressed
485 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
488 // any button can be used to drag the scrollbar under GTK+
489 virtual bool IsAllowedButton(int WXUNUSED(button
)) const { return true; }
493 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
494 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
498 #endif // wxUSE_SCROLLBAR
502 class wxGTKCheckboxInputHandler
: public wxStdInputHandler
505 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
506 : wxStdInputHandler(handler
) { }
508 virtual bool HandleKey(wxInputConsumer
*control
,
509 const wxKeyEvent
& event
,
513 #endif // wxUSE_CHECKBOX
517 class wxGTKTextCtrlInputHandler
: public wxStdInputHandler
520 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
521 : wxStdInputHandler(handler
) { }
523 virtual bool HandleKey(wxInputConsumer
*control
,
524 const wxKeyEvent
& event
,
528 #endif // wxUSE_TEXTCTRL
530 // ----------------------------------------------------------------------------
531 // wxGTKColourScheme: uses the standard GTK colours
532 // ----------------------------------------------------------------------------
534 class wxGTKColourScheme
: public wxColourScheme
537 virtual wxColour
Get(StdColour col
) const;
538 virtual wxColour
GetBackground(wxWindow
*win
) const;
541 // ----------------------------------------------------------------------------
543 // ----------------------------------------------------------------------------
545 class wxGTKArtProvider
: public wxArtProvider
548 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
549 const wxArtClient
& client
,
553 // ----------------------------------------------------------------------------
555 // ----------------------------------------------------------------------------
557 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
559 class wxGTKTheme
: public wxTheme
563 virtual ~wxGTKTheme();
565 virtual wxRenderer
*GetRenderer();
566 virtual wxArtProvider
*GetArtProvider();
567 virtual wxInputHandler
*GetInputHandler(const wxString
& control
,
568 wxInputConsumer
*consumer
);
569 virtual wxColourScheme
*GetColourScheme();
572 wxGTKRenderer
*m_renderer
;
574 wxGTKArtProvider
*m_artProvider
;
576 // the names of the already created handlers and the handlers themselves
577 // (these arrays are synchronized)
578 wxSortedArrayString m_handlerNames
;
579 wxArrayHandlers m_handlers
;
581 wxGTKColourScheme
*m_scheme
;
583 WX_DECLARE_THEME(gtk
)
586 // ============================================================================
588 // ============================================================================
590 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
592 // ----------------------------------------------------------------------------
594 // ----------------------------------------------------------------------------
596 wxGTKTheme::wxGTKTheme()
600 m_artProvider
= NULL
;
603 wxGTKTheme::~wxGTKTheme()
607 wxArtProvider::RemoveProvider(m_artProvider
);
610 wxRenderer
*wxGTKTheme::GetRenderer()
614 m_renderer
= new wxGTKRenderer(GetColourScheme());
620 wxArtProvider
*wxGTKTheme::GetArtProvider()
622 if ( !m_artProvider
)
624 m_artProvider
= new wxGTKArtProvider
;
627 return m_artProvider
;
630 wxColourScheme
*wxGTKTheme::GetColourScheme()
634 m_scheme
= new wxGTKColourScheme
;
639 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
,
640 wxInputConsumer
*consumer
)
642 wxInputHandler
*handler
= NULL
;
643 int n
= m_handlerNames
.Index(control
);
644 if ( n
== wxNOT_FOUND
)
646 static wxGTKInputHandler s_handlerDef
;
648 wxInputHandler
* const
649 handlerStd
= consumer
->DoGetStdInputHandler(&s_handlerDef
);
651 // create a new handler
653 if ( control
== wxINP_HANDLER_CHECKBOX
)
655 static wxGTKCheckboxInputHandler
s_handler(handlerStd
);
657 handler
= &s_handler
;
660 #endif // wxUSE_CHECKBOX
662 if ( control
== wxINP_HANDLER_SCROLLBAR
)
664 static wxGTKScrollBarInputHandler
s_handler(m_renderer
, handlerStd
);
666 handler
= &s_handler
;
669 #endif // wxUSE_SCROLLBAR
671 if ( control
== wxINP_HANDLER_TEXTCTRL
)
673 static wxGTKTextCtrlInputHandler
s_handler(handlerStd
);
675 handler
= &s_handler
;
678 #endif // wxUSE_TEXTCTRL
680 // no special handler for this control
681 handler
= handlerStd
;
684 n
= m_handlerNames
.Add(control
);
685 m_handlers
.Insert(handler
, n
);
687 else // we already have it
689 handler
= m_handlers
[n
];
695 // ============================================================================
697 // ============================================================================
699 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
702 if ( win
->UseBgCol() )
704 // use the user specified colour
705 col
= win
->GetBackgroundColour();
708 if ( !win
->ShouldInheritColours() )
710 // doesn't depend on the state
718 int flags
= win
->GetStateFlags();
720 // the colour set by the user should be used for the normal state
721 // and for the states for which we don't have any specific colours
722 if ( !col
.Ok() || (flags
!= 0) )
725 if ( wxDynamicCast(win
, wxScrollBar
) )
726 col
= Get(SCROLLBAR
);
728 #endif //wxUSE_SCROLLBAR
729 if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
730 col
= Get(CONTROL_CURRENT
);
731 else if ( flags
& wxCONTROL_PRESSED
)
732 col
= Get(CONTROL_PRESSED
);
741 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
745 case WINDOW
: return *wxWHITE
;
747 case SHADOW_DARK
: return *wxBLACK
;
748 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
749 case SHADOW_IN
: return wxColour(0xd6d6d6);
750 case SHADOW_OUT
: return wxColour(0x969696);
752 case CONTROL
: return wxColour(0xd6d6d6);
753 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
754 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
756 case CONTROL_TEXT
: return *wxBLACK
;
757 case CONTROL_TEXT_DISABLED
:
758 return wxColour(0x757575);
759 case CONTROL_TEXT_DISABLED_SHADOW
:
763 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
765 case HIGHLIGHT
: return wxColour(0x9c0000);
766 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
768 case GAUGE
: return Get(CONTROL_CURRENT
);
770 case TITLEBAR
: return wxColour(0xaeaaae);
771 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
772 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
773 case TITLEBAR_ACTIVE_TEXT
:
776 case DESKTOP
: return *wxBLACK
;
780 wxFAIL_MSG(_T("invalid standard colour"));
785 // ============================================================================
787 // ============================================================================
789 // ----------------------------------------------------------------------------
791 // ----------------------------------------------------------------------------
793 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
794 : wxStdRenderer(scheme
)
796 m_sizeScrollbarArrow
= wxSize(15, 14);
798 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
));
801 // ----------------------------------------------------------------------------
803 // ----------------------------------------------------------------------------
805 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
811 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
816 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
817 rect
.GetLeft(), rect
.GetBottom() + 1);
821 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
822 rect
.GetRight() + 1, rect
.GetTop());
826 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
827 rect
.GetRight(), rect
.GetBottom() + 1);
831 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
832 rect
.GetRight() + 1, rect
.GetBottom());
836 wxFAIL_MSG(_T("unknown rectangle side"));
840 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
841 const wxPen
& pen1
, const wxPen
& pen2
)
843 // draw the rectangle
845 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
846 rect
->GetLeft(), rect
->GetBottom() + 1);
847 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
848 rect
->GetRight() + 1, rect
->GetTop());
850 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
851 rect
->GetRight(), rect
->GetBottom());
852 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
853 rect
->GetRight() + 1, rect
->GetBottom());
859 void wxGTKRenderer::DrawInnerShadedRect(wxDC
& dc
, wxRect
*rect
)
861 DrawAntiShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
862 DrawAntiShadedRect(dc
, rect
, m_penBlack
, m_penHighlight
);
865 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
867 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
868 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
871 void wxGTKRenderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
873 DrawAntiShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
874 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
877 void wxGTKRenderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
879 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
880 wxRect rectFocus
= rect
;
881 DrawRect(dc
, &rectFocus
, m_penBlack
);
884 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
886 const wxRect
& rectOrig
,
890 wxRect rect
= rectOrig
;
892 if ( border
!= wxBORDER_NONE
)
894 if ( flags
& wxCONTROL_FOCUSED
)
896 DrawRect(dc
, &rect
, m_penBlack
);
897 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
901 DrawInnerShadedRect(dc
, &rect
);
909 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
910 const wxString
& label
,
911 const wxBitmap
& image
,
918 // no focus rect around buttons label in GTK+
919 wxStdRenderer::DrawButtonLabel(dc
, label
, image
, rect
, flags
,
920 alignment
, indexAccel
, rectBounds
);
923 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
924 const wxRect
& rectTotal
,
928 wxRect rect
= rectTotal
;
930 if ( flags
& wxCONTROL_PRESSED
)
932 // button pressed: draw a black border around it and an inward shade
933 DrawRect(dc
, &rect
, m_penBlack
);
935 DrawInnerShadedRect(dc
, &rect
);
937 else // button not pressed
939 if ( flags
& wxCONTROL_ISDEFAULT
)
944 if ( flags
& wxCONTROL_FOCUSED
)
946 // button is currently default: add an extra border around it
947 DrawRect(dc
, &rect
, m_penBlack
);
950 // now draw a normal button
951 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
952 DrawAntiShadedRect(dc
, &rect
, GetBackgroundColour(flags
), m_penDarkGrey
);
959 // ----------------------------------------------------------------------------
961 // ----------------------------------------------------------------------------
963 void wxGTKRenderer::DrawFrameWithLabel(wxDC
& dc
,
964 const wxString
& label
,
965 const wxRect
& rectFrame
,
966 const wxRect
& rectTextOrig
,
971 wxRect
rectText(rectTextOrig
);
972 rectText
.Inflate(1, 0);
975 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
977 rectLabel
.width
+= 2;
979 DrawFrameWithoutLabel(dc
, rectFrame
, rectLabel
);
981 // GTK+ does it like this
982 dc
.SetPen(m_penHighlight
);
983 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
984 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
987 // ----------------------------------------------------------------------------
988 // check/radion buttons
989 // ----------------------------------------------------------------------------
991 void wxGTKRenderer::DrawCheckItemBitmap(wxDC
& dc
,
992 const wxBitmap
& bitmap
,
996 // never draw the focus rect around the check indicators here
997 DrawCheckButton(dc
, wxEmptyString
, bitmap
, rect
, flags
& ~wxCONTROL_FOCUSED
);
1000 void wxGTKRenderer::DrawUndeterminedBitmap(wxDC
& dc
,
1001 const wxRect
& rectTotal
,
1004 // FIXME: For sure it is not GTK look but it is better than nothing.
1005 // Show me correct look and I will immediatelly make it better (ABX)
1006 wxRect rect
= rectTotal
;
1008 wxColour col1
, col2
;
1012 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1013 col2
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1017 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1018 col2
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1021 dc
.SetPen(*wxTRANSPARENT_PEN
);
1023 dc
.DrawRectangle(rect
);
1026 dc
.DrawRectangle(rect
);
1029 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1030 const wxRect
& rectTotal
,
1033 wxRect rect
= rectTotal
;
1034 DrawAntiRaisedBorder(dc
, &rect
);
1036 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1037 dc
.SetPen(wxPen(col
));
1038 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1041 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1042 //else: it is SHADOW_IN, leave as is
1044 dc
.SetPen(*wxTRANSPARENT_PEN
);
1046 dc
.DrawRectangle(rect
);
1049 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1051 wxRect rect
= rectTotal
;
1052 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1053 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1055 dc
.SetPen(*wxTRANSPARENT_PEN
);
1056 dc
.SetBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
));
1057 dc
.DrawRectangle(rect
);
1060 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1066 xRight
= rect
.GetRight(),
1067 yBottom
= rect
.GetBottom();
1069 wxCoord yMid
= (y
+ yBottom
) / 2;
1071 // then draw the upper half
1072 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1073 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1074 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1077 if ( flags
& wxCONTROL_CHECKED
)
1078 dc
.SetPen(m_penBlack
);
1079 else if ( flags
& wxCONTROL_PRESSED
)
1080 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
)));
1081 else // unchecked and unpressed
1085 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1087 // and then the lower one
1088 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1089 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1090 if ( !(flags
& wxCONTROL_CHECKED
) )
1091 dc
.SetPen(m_penDarkGrey
);
1092 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1094 if ( !(flags
& wxCONTROL_CHECKED
) )
1095 drawIt
= true; // with the same pen
1096 else if ( flags
& wxCONTROL_PRESSED
)
1098 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
)));
1101 else // checked and unpressed
1105 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1108 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1114 wxCoord xMid
= (x1
+ x2
) / 2;
1115 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1116 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1119 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1125 wxCoord xMid
= (x1
+ x2
) / 2;
1126 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1127 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1130 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1132 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1134 // init the bitmaps once only
1136 wxSize size
= GetCheckBitmapSize();
1137 rect
.width
= size
.x
;
1138 rect
.height
= size
.y
;
1139 for ( int i
= 0; i
< 2; i
++ )
1141 for ( int j
= 0; j
< 3; j
++ )
1142 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1148 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1149 DrawCheckBitmap(dc
, rect
);
1152 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1153 DrawUncheckBitmap(dc
, rect
, false);
1155 // normal undeterminated
1156 dc
.SelectObject(m_bitmapsCheckbox
[0][2]);
1157 DrawUndeterminedBitmap(dc
, rect
, false);
1160 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1162 // pressed unchecked
1163 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1164 DrawUncheckBitmap(dc
, rect
, true);
1166 // pressed undeterminated
1167 dc
.SelectObject(m_bitmapsCheckbox
[1][2]);
1168 DrawUndeterminedBitmap(dc
, rect
, true);
1171 IndicatorState state
;
1172 IndicatorStatus status
;
1173 GetIndicatorsFromFlags(flags
, state
, status
);
1175 // disabled looks the same as normal
1176 if ( state
== IndicatorState_Disabled
)
1177 state
= IndicatorState_Normal
;
1179 return m_bitmapsCheckbox
[state
][status
];
1182 wxBitmap
wxGTKRenderer::GetRadioBitmap(int flags
)
1184 IndicatorState state
;
1185 IndicatorStatus status
;
1186 GetIndicatorsFromFlags(flags
, state
, status
);
1188 wxBitmap
& bmp
= m_bitmapsRadiobtn
[state
][status
];
1191 const wxSize size
= GetRadioBitmapSize();
1194 bmp
.Create(size
.x
, size
.y
);
1195 dc
.SelectObject(bmp
);
1197 DrawRadioBitmap(dc
, size
, flags
);
1203 wxBitmap
wxGTKRenderer::GetLineWrapBitmap() const
1205 if ( !m_bmpLineWrap
.Ok() )
1207 // the line wrap bitmap as used by GTK+
1208 #define line_wrap_width 6
1209 #define line_wrap_height 9
1210 static const char line_wrap_bits
[] =
1212 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1215 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1216 if ( !bmpLineWrap
.Ok() )
1218 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1222 wxConstCast(this, wxGTKRenderer
)->m_bmpLineWrap
= bmpLineWrap
;
1226 return m_bmpLineWrap
;
1230 void wxGTKRenderer::DrawToolBarButton(wxDC
& dc
,
1231 const wxString
& label
,
1232 const wxBitmap
& bitmap
,
1233 const wxRect
& rectOrig
,
1235 long WXUNUSED(style
),
1238 // we don't draw the separators at all
1239 if ( !label
.empty() || bitmap
.Ok() )
1241 wxRect rect
= rectOrig
;
1242 rect
.Deflate(BORDER_THICKNESS
);
1244 if ( flags
& wxCONTROL_PRESSED
)
1246 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
, &rect
);
1248 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), rect
);
1250 else if ( flags
& wxCONTROL_CURRENT
)
1252 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rect
);
1254 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rect
);
1257 if(tbarStyle
& wxTB_TEXT
)
1259 if(tbarStyle
& wxTB_HORIZONTAL
)
1261 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1265 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
1270 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
1271 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
1272 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
1276 #endif // wxUSE_TOOLBAR
1278 // ----------------------------------------------------------------------------
1280 // ----------------------------------------------------------------------------
1284 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1286 wxCoord
*extraSpaceBeyond
) const
1289 rectText
= wxStdRenderer::GetTextClientArea(text
, rect
, extraSpaceBeyond
);
1291 if ( text
->WrapLines() )
1293 // leave enough for the line wrap bitmap indicator
1294 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1296 rectText
.width
-= widthMark
;
1298 if ( extraSpaceBeyond
)
1299 *extraSpaceBeyond
= widthMark
;
1305 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1307 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1309 // for a mono bitmap he colours it appears in depends on the current text
1310 // colours, so set them correctly
1312 if ( bmpLineWrap
.GetDepth() == 1 )
1314 colFgOld
= dc
.GetTextForeground();
1316 // FIXME: I wonder what should we do if the background is black too?
1317 dc
.SetTextForeground(*wxBLACK
);
1320 dc
.DrawBitmap(bmpLineWrap
,
1321 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1323 if ( colFgOld
.Ok() )
1325 // restore old colour
1326 dc
.SetTextForeground(colFgOld
);
1330 #endif // wxUSE_TEXTCTRL
1332 // ----------------------------------------------------------------------------
1334 // ----------------------------------------------------------------------------
1338 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1339 const wxRect
& rectOrig
,
1341 const wxString
& label
,
1342 const wxBitmap
& bitmap
,
1346 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1347 #define REVERSE_FOR_VERTICAL(X,Y) \
1348 SELECT_FOR_VERTICAL(X,Y) \
1350 SELECT_FOR_VERTICAL(Y,X)
1352 wxRect rect
= rectOrig
;
1354 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1356 // the current tab is drawn indented (to the top for default case) and
1357 // bigger than the other ones
1358 const wxSize indent
= GetTabIndent();
1359 if ( flags
& wxCONTROL_SELECTED
)
1361 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1362 SELECT_FOR_VERTICAL( 0, indent
.y
));
1366 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1373 rect
.height
+= indent
.y
;
1380 rect
.width
+= indent
.x
;
1385 // selected tab has different colour
1386 wxColour col
= flags
& wxCONTROL_SELECTED
1387 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1388 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1389 DrawSolidRect(dc
, col
, rect
);
1391 if ( flags
& wxCONTROL_FOCUSED
)
1393 // draw the focus rect
1394 wxRect rectBorder
= rect
;
1395 rectBorder
.Deflate(4, 3);
1396 if ( dir
== wxBOTTOM
)
1397 rectBorder
.Offset(0, -1);
1398 if ( dir
== wxRIGHT
)
1399 rectBorder
.Offset(-1, 0);
1401 DrawRect(dc
, &rectBorder
, m_penBlack
);
1404 // draw the text, image and the focus around them (if necessary)
1405 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1406 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1408 rectLabel
.Deflate(1, 1);
1411 // draw it horizontally into memory and rotate for screen
1413 wxBitmap bitmapRotated
,
1414 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1415 rectLabel
.y
+ rectLabel
.height
);
1416 dcMem
.SelectObject(bitmapMem
);
1417 dcMem
.SetBackground(dc
.GetBackground());
1418 dcMem
.SetFont(dc
.GetFont());
1419 dcMem
.SetTextForeground(dc
.GetTextForeground());
1423 wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) )
1426 #endif // wxUSE_IMAGE
1428 dcMem
.DrawLabel(label
, bitmapRotated
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1429 dcMem
.SelectObject(wxNullBitmap
);
1430 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1432 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
))
1436 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1440 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1443 // now draw the tab itself
1444 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1445 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1446 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1447 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1453 // left orientation looks like top but IsVertical makes x and y reversed
1455 // top is not vertical so use coordinates in written order
1456 dc
.SetPen(m_penHighlight
);
1457 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1458 REVERSE_FOR_VERTICAL(x
, y
));
1459 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
),
1460 REVERSE_FOR_VERTICAL(x2
, y
));
1462 dc
.SetPen(m_penBlack
);
1463 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1464 REVERSE_FOR_VERTICAL(x2
, y
));
1466 dc
.SetPen(m_penDarkGrey
);
1467 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1468 REVERSE_FOR_VERTICAL(x2
- 1, y
+ 1));
1470 if ( flags
& wxCONTROL_SELECTED
)
1472 dc
.SetPen(m_penLightGrey
);
1474 // overwrite the part of the border below this tab
1475 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1476 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1478 // and the shadow of the tab to the left of us
1479 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ 2),
1480 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1485 // right orientation looks like bottom but IsVertical makes x and y reversed
1487 // bottom is not vertical so use coordinates in written order
1488 dc
.SetPen(m_penHighlight
);
1490 // we need to continue one pixel further to overwrite the corner of
1491 // the border for the selected tab
1492 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
1493 REVERSE_FOR_VERTICAL(x
, y2
));
1495 // it doesn't work like this (TODO: implement it properly)
1497 // erase the corner of the tab to the right
1498 dc
.SetPen(m_penLightGrey
);
1499 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1500 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 2));
1501 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 1));
1504 dc
.SetPen(m_penBlack
);
1505 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
),
1506 REVERSE_FOR_VERTICAL(x2
, y2
));
1507 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
1508 REVERSE_FOR_VERTICAL(x2
, y2
));
1510 dc
.SetPen(m_penDarkGrey
);
1511 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 2, y2
- 1),
1512 REVERSE_FOR_VERTICAL(x2
- 1, y2
- 1));
1513 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
1514 REVERSE_FOR_VERTICAL(x2
- 1, y2
));
1516 if ( flags
& wxCONTROL_SELECTED
)
1518 dc
.SetPen(m_penLightGrey
);
1520 // overwrite the part of the (double!) border above this tab
1521 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
1522 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
1523 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
1524 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1526 // and the shadow of the tab to the left of us
1527 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- 1),
1528 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
1534 #endif // wxUSE_NOTEBOOK
1536 // ----------------------------------------------------------------------------
1538 // ----------------------------------------------------------------------------
1542 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1544 wxOrientation orient
) const
1546 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1550 wxRect rectShaft
= GetSliderShaftRect(rect
, lenThumb
, orient
);
1551 if ( orient
== wxHORIZONTAL
)
1553 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1554 size
.y
= rectShaft
.height
;
1558 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1559 size
.x
= rectShaft
.width
;
1565 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1566 int WXUNUSED(lenThumb
),
1567 wxOrientation
WXUNUSED(orient
),
1568 long WXUNUSED(style
)) const
1570 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
1573 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
1574 const wxRect
& rectOrig
,
1575 int WXUNUSED(lenThumb
),
1576 wxOrientation
WXUNUSED(orient
),
1578 long WXUNUSED(style
),
1581 wxRect rect
= rectOrig
;
1583 // draw the border first
1584 if ( flags
& wxCONTROL_FOCUSED
)
1586 DrawRect(dc
, &rect
, m_penBlack
);
1588 else // not focused, normal
1590 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1593 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1595 // and the background
1596 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
1602 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
1603 const wxRect
& rectOrig
,
1604 wxOrientation orient
,
1605 int WXUNUSED(flags
),
1606 long WXUNUSED(style
))
1608 // draw the thumb border
1609 wxRect rect
= rectOrig
;
1610 DrawAntiRaisedBorder(dc
, &rect
);
1612 // draw the handle in the middle
1613 if ( orient
== wxVERTICAL
)
1615 rect
.height
= 2*BORDER_THICKNESS
;
1616 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
1620 rect
.width
= 2*BORDER_THICKNESS
;
1621 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
1624 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1627 #endif // wxUSE_SLIDER
1631 // ----------------------------------------------------------------------------
1633 // ----------------------------------------------------------------------------
1635 // wxGTKMenuGeometryInfo: the wxMenuGeometryInfo used by wxGTKRenderer
1636 class WXDLLEXPORT wxGTKMenuGeometryInfo
: public wxMenuGeometryInfo
1639 virtual wxSize
GetSize() const { return m_size
; }
1641 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
1642 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
1644 wxCoord
GetItemHeight() const { return m_heightItem
; }
1647 // the total size of the menu
1650 // the offset of the start of the menu item label
1653 // the offset of the start of the accel label
1656 // the height of a normal (not separator) item
1657 wxCoord m_heightItem
;
1659 friend wxMenuGeometryInfo
*
1660 wxGTKRenderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
1663 // FIXME: all constants are hardcoded but shouldn't be
1664 static const wxCoord MENU_LEFT_MARGIN
= 9;
1665 static const wxCoord MENU_RIGHT_MARGIN
= 6;
1667 static const wxCoord MENU_HORZ_MARGIN
= 6;
1668 static const wxCoord MENU_VERT_MARGIN
= 3;
1670 // the margin around bitmap/check marks (on each side)
1671 static const wxCoord MENU_BMP_MARGIN
= 2;
1673 // the margin between the labels and accel strings
1674 static const wxCoord MENU_ACCEL_MARGIN
= 8;
1676 // the separator height in pixels: in fact, strangely enough, the real height
1677 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
1679 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
1681 // the size of the standard checkmark bitmap
1682 static const wxCoord MENU_CHECK_SIZE
= 9;
1684 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
1686 const wxString
& label
,
1690 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
);
1693 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
1695 const wxMenuGeometryInfo
& gi
,
1696 const wxString
& label
,
1697 const wxString
& accel
,
1698 const wxBitmap
& bitmap
,
1702 const wxGTKMenuGeometryInfo
& geomInfo
= (const wxGTKMenuGeometryInfo
&)gi
;
1707 rect
.width
= geomInfo
.GetSize().x
;
1708 rect
.height
= geomInfo
.GetItemHeight();
1710 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
, accel
, bitmap
, &geomInfo
);
1713 void wxGTKRenderer::DoDrawMenuItem(wxDC
& dc
,
1714 const wxRect
& rectOrig
,
1715 const wxString
& label
,
1718 const wxString
& accel
,
1719 const wxBitmap
& bitmap
,
1720 const wxGTKMenuGeometryInfo
*geometryInfo
)
1722 wxRect rect
= rectOrig
;
1724 // draw the selected item specially
1725 if ( flags
& wxCONTROL_SELECTED
)
1728 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
1730 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rectIn
);
1733 rect
.Deflate(MENU_HORZ_MARGIN
, MENU_VERT_MARGIN
);
1735 // draw the bitmap: use the bitmap provided or the standard checkmark for
1736 // the checkable items
1739 wxBitmap bmp
= bitmap
;
1740 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKABLE
) )
1742 bmp
= GetCheckBitmap(flags
);
1747 rect
.SetRight(geometryInfo
->GetLabelOffset());
1748 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
1751 //else: menubar items don't have bitmaps
1756 rect
.x
= geometryInfo
->GetLabelOffset();
1757 rect
.SetRight(geometryInfo
->GetAccelOffset());
1760 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1762 // draw the accel string
1763 if ( !accel
.empty() )
1765 // menubar items shouldn't have them
1766 wxCHECK_RET( geometryInfo
, _T("accel strings only valid for menus") );
1768 rect
.x
= geometryInfo
->GetAccelOffset();
1769 rect
.SetRight(geometryInfo
->GetSize().x
);
1771 // NB: no accel index here
1772 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
1775 // draw the submenu indicator
1776 if ( flags
& wxCONTROL_ISSUBMENU
)
1778 wxCHECK_RET( geometryInfo
, _T("wxCONTROL_ISSUBMENU only valid for menus") );
1780 rect
.x
= geometryInfo
->GetSize().x
- MENU_RIGHT_MARGIN
;
1781 rect
.width
= MENU_RIGHT_MARGIN
;
1783 DrawArrow(dc
, wxRIGHT
, rect
, flags
);
1787 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
1789 const wxMenuGeometryInfo
& geomInfo
)
1791 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
1794 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
1796 wxSize size
= sizeText
;
1798 // TODO: make this configurable
1799 size
.x
+= 2*MENU_HORZ_MARGIN
;
1800 size
.y
+= 2*MENU_VERT_MARGIN
;
1805 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
1806 const wxMenu
& menu
) const
1808 // prepare the dc: for now we draw all the items with the system font
1810 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
1812 // the height of a normal item
1813 wxCoord heightText
= dc
.GetCharHeight();
1818 // the max length of label and accel strings: the menu width is the sum of
1819 // them, even if they're for different items (as the accels should be
1822 // the max length of the bitmap is never 0 as Windows always leaves enough
1823 // space for a check mark indicator
1824 wxCoord widthLabelMax
= 0,
1826 widthBmpMax
= MENU_LEFT_MARGIN
;
1828 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
1830 node
= node
->GetNext() )
1832 // height of this item
1835 wxMenuItem
*item
= node
->GetData();
1836 if ( item
->IsSeparator() )
1838 h
= MENU_SEPARATOR_HEIGHT
;
1840 else // not separator
1845 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
1846 if ( widthLabel
> widthLabelMax
)
1848 widthLabelMax
= widthLabel
;
1852 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
1853 if ( widthAccel
> widthAccelMax
)
1855 widthAccelMax
= widthAccel
;
1858 const wxBitmap
& bmp
= item
->GetBitmap();
1861 wxCoord widthBmp
= bmp
.GetWidth();
1862 if ( widthBmp
> widthBmpMax
)
1863 widthBmpMax
= widthBmp
;
1865 //else if ( item->IsCheckable() ): no need to check for this as
1866 // MENU_LEFT_MARGIN is big enough to show the check mark
1869 h
+= 2*MENU_VERT_MARGIN
;
1871 // remember the item position and height
1872 item
->SetGeometry(height
, h
);
1877 // bundle the metrics into a struct and return it
1878 wxGTKMenuGeometryInfo
*gi
= new wxGTKMenuGeometryInfo
;
1880 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
1881 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
1882 if ( widthAccelMax
> 0 )
1884 // if we actually have any accesl, add a margin
1885 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
1888 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
1890 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
1891 gi
->m_size
.y
= height
;
1896 #endif // wxUSE_MENUS
1900 // ----------------------------------------------------------------------------
1902 // ----------------------------------------------------------------------------
1905 wxGTKRenderer::GetStatusBarBorders(wxCoord
* WXUNUSED(borderBetweenFields
)) const
1910 void wxGTKRenderer::DrawStatusField(wxDC
& WXUNUSED(dc
),
1911 const wxRect
& WXUNUSED(rect
),
1912 const wxString
& WXUNUSED(label
),
1913 int WXUNUSED(flags
), int WXUNUSED(style
))
1917 #endif // wxUSE_STATUSBAR
1919 // ----------------------------------------------------------------------------
1921 // ----------------------------------------------------------------------------
1923 void wxGTKRenderer::InitComboBitmaps()
1925 wxSize sizeArrow
= m_sizeScrollbarArrow
;
1931 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1933 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
1936 static const int comboButtonFlags
[ComboState_Max
] =
1944 wxRect
rect(sizeArrow
);
1947 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1949 int flags
= comboButtonFlags
[n
];
1951 dc
.SelectObject(m_bitmapsCombo
[n
]);
1952 DrawSolidRect(dc
, GetBackgroundColour(flags
), rect
);
1953 DrawArrow(dc
, wxDOWN
, rect
, flags
);
1957 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
1959 wxBitmap
*bmpPressed
,
1960 wxBitmap
*bmpDisabled
)
1962 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
1968 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
1970 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
1972 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
1974 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
1977 // ----------------------------------------------------------------------------
1979 // ----------------------------------------------------------------------------
1981 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
1985 static const wxDirection sides
[] =
1987 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
1990 wxRect rect1
, rect2
, rectInner
;
1996 rectInner
.Inflate(-2);
1998 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
2000 // find the side not to draw and also adjust the rectangles to compensate
2002 wxDirection sideToOmit
;
2006 sideToOmit
= wxDOWN
;
2008 rectInner
.height
+= 1;
2016 rectInner
.height
+= 1;
2020 sideToOmit
= wxRIGHT
;
2022 rectInner
.width
+= 1;
2026 sideToOmit
= wxLEFT
;
2030 rectInner
.width
+= 1;
2034 wxFAIL_MSG(_T("unknown arrow direction"));
2038 // the outer rect first
2040 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2042 wxDirection side
= sides
[n
];
2043 if ( side
== sideToOmit
)
2046 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
2049 // and then the inner one
2050 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2052 wxDirection side
= sides
[n
];
2053 if ( side
== sideToOmit
)
2056 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
2062 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
2064 const wxRect
& rectArrow
,
2067 // first of all, draw the border around it - but we don't want the border
2068 // on the side opposite to the arrow point
2069 wxRect rect
= rectArrow
;
2070 DrawArrowBorder(dc
, &rect
, dir
);
2072 // then the arrow itself
2073 DrawArrow(dc
, dir
, rect
, flags
);
2076 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
2077 // these people are just crazy :-(
2078 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2091 wxPoint ptArrow
[Point_Max
];
2093 wxColour colInside
= GetBackgroundColour(flags
);
2095 if ( flags
& wxCONTROL_DISABLED
)
2097 penShadow
[0] = m_penDarkGrey
;
2098 penShadow
[1] = m_penDarkGrey
;
2099 penShadow
[2] = wxNullPen
;
2100 penShadow
[3] = wxNullPen
;
2102 else if ( flags
& wxCONTROL_PRESSED
)
2104 penShadow
[0] = m_penDarkGrey
;
2105 penShadow
[1] = m_penHighlight
;
2106 penShadow
[2] = wxNullPen
;
2107 penShadow
[3] = m_penBlack
;
2109 else // normal arrow
2111 penShadow
[0] = m_penHighlight
;
2112 penShadow
[1] = m_penBlack
;
2113 penShadow
[2] = m_penDarkGrey
;
2114 penShadow
[3] = wxNullPen
;
2118 if ( dir
== wxUP
|| dir
== wxDOWN
)
2121 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2125 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2128 // draw the arrow interior
2129 dc
.SetPen(*wxTRANSPARENT_PEN
);
2130 dc
.SetBrush(colInside
);
2135 ptArrow
[Point_First
].x
= rect
.GetLeft();
2136 ptArrow
[Point_First
].y
= rect
.GetBottom();
2137 ptArrow
[Point_Second
].x
= middle
;
2138 ptArrow
[Point_Second
].y
= rect
.GetTop();
2139 ptArrow
[Point_Third
].x
= rect
.GetRight();
2140 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2144 ptArrow
[Point_First
] = rect
.GetPosition();
2145 ptArrow
[Point_Second
].x
= middle
;
2146 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2147 ptArrow
[Point_Third
].x
= rect
.GetRight();
2148 ptArrow
[Point_Third
].y
= rect
.GetTop();
2152 ptArrow
[Point_First
].x
= rect
.GetRight();
2153 ptArrow
[Point_First
].y
= rect
.GetTop();
2154 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2155 ptArrow
[Point_Second
].y
= middle
;
2156 ptArrow
[Point_Third
].x
= rect
.GetRight();
2157 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2161 ptArrow
[Point_First
] = rect
.GetPosition();
2162 ptArrow
[Point_Second
].x
= rect
.GetRight();
2163 ptArrow
[Point_Second
].y
= middle
;
2164 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2165 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2169 wxFAIL_MSG(_T("unknown arrow direction"));
2172 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2174 // draw the arrow border
2175 dc
.SetPen(penShadow
[0]);
2179 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2180 dc
.DrawPoint(ptArrow
[Point_First
]);
2181 if ( penShadow
[3].Ok() )
2183 dc
.SetPen(penShadow
[3]);
2184 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2185 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2187 dc
.SetPen(penShadow
[1]);
2188 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2189 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2190 dc
.DrawPoint(ptArrow
[Point_Third
]);
2191 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2192 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2193 if ( penShadow
[2].Ok() )
2195 dc
.SetPen(penShadow
[2]);
2196 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2197 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2198 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2199 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2204 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2205 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2206 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2207 if ( penShadow
[2].Ok() )
2209 dc
.SetPen(penShadow
[2]);
2210 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2211 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2213 dc
.SetPen(penShadow
[1]);
2214 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2215 dc
.DrawPoint(ptArrow
[Point_Third
]);
2219 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2220 dc
.DrawPoint(ptArrow
[Point_First
]);
2221 if ( penShadow
[2].Ok() )
2223 dc
.SetPen(penShadow
[2]);
2224 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2225 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2226 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2227 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2229 dc
.SetPen(penShadow
[1]);
2230 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2231 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2232 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2233 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2237 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2238 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2239 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2240 dc
.SetPen(penShadow
[1]);
2241 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2242 dc
.DrawPoint(ptArrow
[Point_Third
]);
2246 wxFAIL_MSG(_T("unknown arrow direction"));
2251 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2253 wxOrientation orient
)
2255 if ( orient
== wxVERTICAL
)
2257 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2259 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2261 rect
->Inflate(-1, 0);
2263 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2265 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2267 rect
->Inflate(-1, 0);
2271 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2273 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2275 rect
->Inflate(0, -1);
2277 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2279 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2281 rect
->Inflate(0, -1);
2285 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2286 wxOrientation orient
,
2290 // the thumb is never pressed never has focus border under GTK and the
2291 // scrollbar background never changes at all
2292 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2294 // we don't want the border in the direction of the scrollbar movement
2295 wxRect rectThumb
= rect
;
2296 DrawThumbBorder(dc
, &rectThumb
, orient
);
2298 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2299 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2302 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2303 wxOrientation orient
,
2305 int WXUNUSED(flags
))
2307 wxRect rectBar
= rect
;
2308 DrawThumbBorder(dc
, &rectBar
, orient
);
2309 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2312 void wxGTKRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2314 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2318 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2319 wxScrollBar::Element elem
,
2322 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2323 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2325 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2327 elem
= wxScrollBar::Element_Bar_2
;
2330 return wxStdRenderer::GetScrollbarRect(scrollbar
, elem
, thumbPos
);
2333 #endif // wxUSE_SCROLLBAR
2335 // ----------------------------------------------------------------------------
2337 // ----------------------------------------------------------------------------
2339 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2342 if ( wxDynamicCast(window
, wxBitmapButton
) )
2347 #endif // wxUSE_BMPBUTTON
2348 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
2351 || wxDynamicCast(window
, wxButton
)
2352 # endif // wxUSE_BUTTON
2353 # if wxUSE_TOGGLEBTN
2354 || wxDynamicCast(window
, wxToggleButton
)
2355 # endif // wxUSE_TOGGLEBTN
2358 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2360 // TODO: this is ad hoc...
2361 size
->x
+= 3*window
->GetCharWidth();
2362 wxCoord minBtnHeight
= 18;
2363 if ( size
->y
< minBtnHeight
)
2364 size
->y
= minBtnHeight
;
2366 // button border width
2370 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
2372 if ( wxDynamicCast(window
, wxScrollBar
) )
2374 // we only set the width of vert scrollbars and height of the
2376 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2377 size
->y
= m_sizeScrollbarArrow
.x
;
2379 size
->x
= m_sizeScrollbarArrow
.x
;
2382 #endif // wxUSE_SCROLLBAR
2384 // take into account the border width
2385 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
2386 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
2387 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
2391 // ----------------------------------------------------------------------------
2392 // top level windows
2393 // ----------------------------------------------------------------------------
2395 void wxGTKRenderer::DrawFrameTitleBar(wxDC
& WXUNUSED(dc
),
2396 const wxRect
& WXUNUSED(rect
),
2397 const wxString
& WXUNUSED(title
),
2398 const wxIcon
& WXUNUSED(icon
),
2399 int WXUNUSED(flags
),
2400 int WXUNUSED(specialButton
),
2401 int WXUNUSED(specialButtonFlag
))
2405 void wxGTKRenderer::DrawFrameBorder(wxDC
& WXUNUSED(dc
),
2406 const wxRect
& WXUNUSED(rect
),
2407 int WXUNUSED(flags
))
2411 void wxGTKRenderer::DrawFrameBackground(wxDC
& WXUNUSED(dc
),
2412 const wxRect
& WXUNUSED(rect
),
2413 int WXUNUSED(flags
))
2417 void wxGTKRenderer::DrawFrameTitle(wxDC
& WXUNUSED(dc
),
2418 const wxRect
& WXUNUSED(rect
),
2419 const wxString
& WXUNUSED(title
),
2420 int WXUNUSED(flags
))
2424 void wxGTKRenderer::DrawFrameIcon(wxDC
& WXUNUSED(dc
),
2425 const wxRect
& WXUNUSED(rect
),
2426 const wxIcon
& WXUNUSED(icon
),
2427 int WXUNUSED(flags
))
2431 void wxGTKRenderer::DrawFrameButton(wxDC
& WXUNUSED(dc
),
2432 wxCoord
WXUNUSED(x
),
2433 wxCoord
WXUNUSED(y
),
2434 int WXUNUSED(button
),
2435 int WXUNUSED(flags
))
2440 wxGTKRenderer::GetFrameClientArea(const wxRect
& rect
,
2441 int WXUNUSED(flags
)) const
2447 wxGTKRenderer::GetFrameTotalSize(const wxSize
& clientSize
,
2448 int WXUNUSED(flags
)) const
2453 wxSize
wxGTKRenderer::GetFrameMinSize(int WXUNUSED(flags
)) const
2458 wxSize
wxGTKRenderer::GetFrameIconSize() const
2460 return wxSize(wxDefaultCoord
, wxDefaultCoord
);
2464 wxGTKRenderer::HitTestFrame(const wxRect
& WXUNUSED(rect
),
2465 const wxPoint
& WXUNUSED(pt
),
2466 int WXUNUSED(flags
)) const
2468 return wxHT_TOPLEVEL_CLIENT_AREA
;
2472 // ----------------------------------------------------------------------------
2474 // ----------------------------------------------------------------------------
2476 /* Copyright (c) Julian Smart */
2477 static const char *error_xpm
[] = {
2478 /* columns rows colors chars-per-pixel */
2492 " ................. ",
2493 " ................... ",
2494 " ....................... ",
2495 " ......................... ",
2496 " ........................... ",
2497 " ...........................X ",
2498 " .............................X ",
2499 " ............................... ",
2500 " ...............................X ",
2501 " .................................X ",
2502 " .................................X ",
2503 " .................................XX ",
2504 " ...ooooooooooooooooooooooooooo...XX ",
2505 " ....ooooooooooooooooooooooooooo....X ",
2506 " ....ooooooooooooooooooooooooooo....X ",
2507 " ....ooooooooooooooooooooooooooo....XX ",
2508 " ....ooooooooooooooooooooooooooo....XX ",
2509 " ....ooooooooooooooooooooooooooo....XX ",
2510 " ...ooooooooooooooooooooooooooo...XXX ",
2511 " ...ooooooooooooooooooooooooooo...XXX ",
2512 " .................................XX ",
2513 " .................................XX ",
2514 " ...............................XXX ",
2515 " ...............................XXX ",
2516 " .............................XXX ",
2517 " ...........................XXXX ",
2518 " ...........................XXX ",
2519 " .........................XXX ",
2520 " .......................XXXX ",
2521 " X...................XXXXX ",
2522 " X.................XXXXX ",
2523 " X.............XXXXX ",
2524 " XXXX.....XXXXXXXX ",
2535 /* Copyright (c) Julian Smart */
2536 static const char *info_xpm
[] = {
2537 /* columns rows colors chars-per-pixel */
2561 " .XXXOXXXXXXXoo. ",
2562 " .XOOXXX+XXXXXo. ",
2563 " .XOOOXX+++XXXXoo. ",
2564 " .XOOXXX+++XXXXXo. ",
2565 " .XOOOXXX+++XXXXXXo. ",
2566 " .XOOXXXX+++XXXXXXo. ",
2567 " .XXXXXXX+++XXXXXXX. ",
2568 " .XXXXXXX+++XXXXXXo. ",
2569 " .XXXXXXX+++XXXXXoo. ",
2570 " .XXXXXX+++XXXXXo. ",
2571 " .XXXXXXX+XXXXXXo. ",
2572 " .XXXXXXXXXXXXo. ",
2573 " .XXXXX+++XXXoo. ",
2599 /* Copyright (c) Julian Smart */
2600 static const char *warning_xpm
[] = {
2601 /* columns rows colors chars-per-pixel */
2631 " ..XXXXO@#XXX... ",
2632 " ...XXXXO@#XXXX.. ",
2633 " ..XXXXXO@#XXXX... ",
2634 " ...XXXXXo@OXXXXX.. ",
2635 " ...XXXXXXo@OXXXXXX.. ",
2636 " ..XXXXXXX$@OXXXXXX... ",
2637 " ...XXXXXXXX@XXXXXXXX.. ",
2638 " ...XXXXXXXXXXXXXXXXXX... ",
2639 " ..XXXXXXXXXXOXXXXXXXXX.. ",
2640 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
2641 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
2642 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
2643 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
2644 " .............................. ",
2645 " .............................. ",
2663 /* Copyright (c) Julian Smart */
2664 static const char *question_xpm
[] = {
2665 /* columns rows colors chars-per-pixel */
2695 " ..XXXXoooooXXXO+ ",
2696 " ..XXooooooooooooX@.. ",
2697 " ..XoooooooooooooooXX#. ",
2698 " $%XoooooooooooooooooXX#. ",
2699 " &.XoooooooXXXXXXooooooXX.. ",
2700 " .XooooooXX.$...$XXoooooX*. ",
2701 " $.XoooooX%.$ .*oooooo=.. ",
2702 " .XooooooX.. -.XoooooX.. ",
2703 " .XoooooX..+ .XoooooX;. ",
2704 " ...XXXX..: .XoooooX;. ",
2705 " ........ >.XoooooX;. ",
2739 wxBitmap
wxGTKArtProvider::CreateBitmap(const wxArtID
& id
,
2740 const wxArtClient
& WXUNUSED(client
),
2741 const wxSize
& WXUNUSED(size
))
2743 if ( id
== wxART_INFORMATION
)
2744 return wxBitmap(info_xpm
);
2745 if ( id
== wxART_ERROR
)
2746 return wxBitmap(error_xpm
);
2747 if ( id
== wxART_WARNING
)
2748 return wxBitmap(warning_xpm
);
2749 if ( id
== wxART_QUESTION
)
2750 return wxBitmap(question_xpm
);
2751 return wxNullBitmap
;
2755 // ============================================================================
2757 // ============================================================================
2759 // ----------------------------------------------------------------------------
2760 // wxGTKInputHandler
2761 // ----------------------------------------------------------------------------
2763 bool wxGTKInputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
2764 const wxKeyEvent
& WXUNUSED(event
),
2765 bool WXUNUSED(pressed
))
2770 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
2771 const wxMouseEvent
& event
)
2773 // clicking on the control gives it focus
2774 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
2776 control
->GetInputWindow()->SetFocus();
2784 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
2785 const wxMouseEvent
& event
)
2787 if ( event
.Entering() )
2789 control
->GetInputWindow()->SetCurrent(true);
2791 else if ( event
.Leaving() )
2793 control
->GetInputWindow()->SetCurrent(false);
2805 // ----------------------------------------------------------------------------
2806 // wxGTKCheckboxInputHandler
2807 // ----------------------------------------------------------------------------
2809 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
2810 const wxKeyEvent
& event
,
2815 int keycode
= event
.GetKeyCode();
2816 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
2818 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
2827 #endif // wxUSE_CHECKBOX
2831 // ----------------------------------------------------------------------------
2832 // wxGTKTextCtrlInputHandler
2833 // ----------------------------------------------------------------------------
2835 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
2836 const wxKeyEvent
& event
,
2839 // handle only GTK-specific text bindings here, the others are handled in
2843 wxControlAction action
;
2844 int keycode
= event
.GetKeyCode();
2845 if ( event
.ControlDown() )
2850 action
= wxACTION_TEXT_HOME
;
2854 action
= wxACTION_TEXT_LEFT
;
2858 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
2862 action
= wxACTION_TEXT_END
;
2866 action
= wxACTION_TEXT_RIGHT
;
2870 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
2874 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2878 action
= wxACTION_TEXT_DOWN
;
2882 action
= wxACTION_TEXT_UP
;
2886 //delete the entire line
2887 control
->PerformAction(wxACTION_TEXT_HOME
);
2888 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2892 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
2896 else if ( event
.AltDown() )
2901 action
= wxACTION_TEXT_WORD_LEFT
;
2905 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
2909 action
= wxACTION_TEXT_WORD_RIGHT
;
2914 if ( action
!= wxACTION_NONE
)
2916 control
->PerformAction(action
);
2922 return wxStdInputHandler::HandleKey(control
, event
, pressed
);
2925 #endif // wxUSE_TEXTCTRL