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/renderer.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 // ----------------------------------------------------------------------------
68 // constants (to be removed, for testing only)
69 // ----------------------------------------------------------------------------
71 static const size_t BORDER_THICKNESS
= 1;
73 // ----------------------------------------------------------------------------
74 // wxGTKRenderer: draw the GUI elements in GTK style
75 // ----------------------------------------------------------------------------
77 class wxGTKRenderer
: public wxRenderer
80 wxGTKRenderer(const wxColourScheme
*scheme
);
82 // implement the base class pure virtuals
83 virtual void DrawBackground(wxDC
& dc
,
87 wxWindow
*window
= NULL
);
88 virtual void DrawLabel(wxDC
& dc
,
89 const wxString
& label
,
92 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
94 wxRect
*rectBounds
= NULL
);
95 virtual void DrawButtonLabel(wxDC
& dc
,
96 const wxString
& label
,
97 const wxBitmap
& image
,
100 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
102 wxRect
*rectBounds
= NULL
);
103 virtual void DrawBorder(wxDC
& dc
,
107 wxRect
*rectIn
= (wxRect
*)NULL
);
108 virtual void DrawHorizontalLine(wxDC
& dc
,
109 wxCoord y
, wxCoord x1
, wxCoord x2
);
110 virtual void DrawVerticalLine(wxDC
& dc
,
111 wxCoord x
, wxCoord y1
, wxCoord y2
);
112 virtual void DrawFrame(wxDC
& dc
,
113 const wxString
& label
,
116 int alignment
= wxALIGN_LEFT
,
117 int indexAccel
= -1);
118 virtual void DrawTextBorder(wxDC
& dc
,
122 wxRect
*rectIn
= (wxRect
*)NULL
);
123 virtual void DrawButtonBorder(wxDC
& dc
,
126 wxRect
*rectIn
= (wxRect
*)NULL
);
127 virtual void DrawArrow(wxDC
& dc
,
131 virtual void DrawScrollbarArrow(wxDC
& dc
,
135 virtual void DrawScrollbarThumb(wxDC
& dc
,
136 wxOrientation orient
,
139 virtual void DrawScrollbarShaft(wxDC
& dc
,
140 wxOrientation orient
,
143 virtual void DrawScrollCorner(wxDC
& dc
,
145 virtual void DrawItem(wxDC
& dc
,
146 const wxString
& label
,
149 virtual void DrawCheckItem(wxDC
& dc
,
150 const wxString
& label
,
151 const wxBitmap
& bitmap
,
154 virtual void DrawCheckButton(wxDC
& dc
,
155 const wxString
& label
,
156 const wxBitmap
& bitmap
,
159 wxAlignment align
= wxALIGN_LEFT
,
160 int indexAccel
= -1);
162 virtual void DrawRadioButton(wxDC
& dc
,
163 const wxString
& label
,
164 const wxBitmap
& bitmap
,
167 wxAlignment align
= wxALIGN_LEFT
,
168 int indexAccel
= -1);
171 virtual void DrawToolBarButton(wxDC
& dc
,
172 const wxString
& label
,
173 const wxBitmap
& bitmap
,
178 #endif // wxUSE_TOOLBAR
180 virtual void DrawTextLine(wxDC
& dc
,
181 const wxString
& text
,
186 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
187 virtual void DrawTab(wxDC
& dc
,
190 const wxString
& label
,
191 const wxBitmap
& bitmap
= wxNullBitmap
,
193 int indexAccel
= -1);
196 virtual void DrawSliderShaft(wxDC
& dc
,
199 wxOrientation orient
,
202 wxRect
*rectShaft
= NULL
);
203 virtual void DrawSliderThumb(wxDC
& dc
,
205 wxOrientation orient
,
208 virtual void DrawSliderTicks(wxDC
& WXUNUSED(dc
),
209 const wxRect
& WXUNUSED(rect
),
210 int WXUNUSED(lenThumb
),
211 wxOrientation
WXUNUSED(orient
),
214 int WXUNUSED(step
) = 1,
215 int WXUNUSED(flags
) = 0,
216 long WXUNUSED(style
) = 0)
218 // we don't have the ticks in GTK version
220 #endif // wxUSE_SLIDER
223 virtual void DrawMenuBarItem(wxDC
& dc
,
225 const wxString
& label
,
227 int indexAccel
= -1);
228 virtual void DrawMenuItem(wxDC
& dc
,
230 const wxMenuGeometryInfo
& geometryInfo
,
231 const wxString
& label
,
232 const wxString
& accel
,
233 const wxBitmap
& bitmap
= wxNullBitmap
,
235 int indexAccel
= -1);
236 virtual void DrawMenuSeparator(wxDC
& dc
,
238 const wxMenuGeometryInfo
& geomInfo
);
239 #endif // wxUSE_MENUS
242 virtual void DrawStatusField(wxDC
& dc
,
244 const wxString
& label
,
245 int flags
= 0, int style
= 0);
246 #endif // wxUSE_STATUSBAR
248 virtual void DrawFrameTitleBar(wxDC
& dc
,
250 const wxString
& title
,
253 int specialButton
= 0,
254 int specialButtonFlag
= 0);
255 virtual void DrawFrameBorder(wxDC
& dc
,
258 virtual void DrawFrameBackground(wxDC
& dc
,
261 virtual void DrawFrameTitle(wxDC
& dc
,
263 const wxString
& title
,
265 virtual void DrawFrameIcon(wxDC
& dc
,
269 virtual void DrawFrameButton(wxDC
& dc
,
270 wxCoord x
, wxCoord y
,
275 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
276 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
277 virtual wxSize
GetFrameMinSize(int flags
) const;
278 virtual wxSize
GetFrameIconSize() const;
279 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
281 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
283 wxBitmap
*bmpPressed
,
284 wxBitmap
*bmpDisabled
);
286 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
287 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
288 virtual bool AreScrollbarsInsideBorder() const;
290 // geometry and hit testing
291 virtual wxSize
GetScrollbarArrowSize() const
292 { return m_sizeScrollbarArrow
; }
294 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
295 wxScrollBar::Element elem
,
296 int thumbPos
= -1) const;
297 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
298 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
299 const wxPoint
& pt
) const;
300 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
302 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
303 #endif // wxUSE_SCROLLBAR
305 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
306 { return fontHeight
+ 2; }
307 virtual wxSize
GetCheckBitmapSize() const
308 { return wxSize(10, 10); }
309 virtual wxSize
GetRadioBitmapSize() const
310 { return wxSize(11, 11); }
311 virtual wxCoord
GetCheckItemMargin() const
314 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
315 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
316 virtual wxSize
GetToolBarMargin() const
317 { return wxSize(6, 6); }
320 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
321 const wxRect
& rect
) const;
322 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
324 wxCoord
*extraSpaceBeyond
) const;
325 #endif // wxUSE_TEXTCTRL
327 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
328 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
331 virtual wxCoord
GetSliderDim() const { return 15; }
332 virtual wxCoord
GetSliderTickLen() const { return 0; }
333 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
335 wxOrientation orient
,
336 long style
= 0) const;
337 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
339 wxOrientation orient
) const;
340 #endif // wxUSE_SLIDER
342 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
345 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
346 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
347 const wxMenu
& menu
) const;
348 #endif // wxUSE_MENUS
351 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
352 #endif // wxUSE_STATUSBAR
354 // helpers for "wxBitmap wxColourScheme::Get()"
355 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
356 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
357 void DrawUndeterminedBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
360 // DrawBackground() helpers
362 // get the colour to use for background
363 wxColour
GetBackgroundColour(int flags
) const
365 if ( flags
& wxCONTROL_PRESSED
)
366 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
367 else if ( flags
& wxCONTROL_CURRENT
)
368 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
370 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
373 // draw the background with any colour, not only the default one(s)
374 void DoDrawBackground(wxDC
& dc
,
377 wxWindow
*window
= NULL
);
379 // DrawBorder() helpers: all of them shift and clip the DC after drawing
382 // just draw a rectangle with the given pen
383 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
385 // draw the lower left part of rectangle
386 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
388 // draw the rectange using the first brush for the left and top sides and
389 // the second one for the bottom and right ones
390 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
391 const wxPen
& pen1
, const wxPen
& pen2
);
393 // as DrawShadedRect() but the pixels in the bottom left and upper right
394 // border are drawn with the pen1, not pen2
395 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
396 const wxPen
& pen1
, const wxPen
& pen2
);
398 // used for drawing opened rectangles - draws only one side of it at once
399 // (and doesn't adjust the rect)
400 void DrawAntiShadedRectSide(wxDC
& dc
,
406 // draw an opened rect for the arrow in given direction
407 void DrawArrowBorder(wxDC
& dc
,
411 // draw two sides of the rectangle
412 void DrawThumbBorder(wxDC
& dc
,
414 wxOrientation orient
);
416 // draw the normal 3D border
417 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
419 // just as DrawRaisedBorder() except that the bottom left and up right
420 // pixels of the interior rect are drawn in another colour (i.e. the inner
421 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
422 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
425 // returns the size of the arrow for the scrollbar (depends on
427 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
430 if ( scrollbar
->IsVertical() )
432 size
= m_sizeScrollbarArrow
;
436 size
.x
= m_sizeScrollbarArrow
.y
;
437 size
.y
= m_sizeScrollbarArrow
.x
;
442 #endif // wxUSE_SCROLLBAR
444 // get the line wrap indicator bitmap
445 wxBitmap
GetLineWrapBitmap() const;
447 // DrawCheckBitmap and DrawRadioBitmap helpers
449 // draw the check bitmaps once and cache them for later use
450 wxBitmap
GetCheckBitmap(int flags
);
452 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
454 void DrawUpZag(wxDC
& dc
,
455 wxCoord x1
, wxCoord x2
,
456 wxCoord y1
, wxCoord y2
);
457 void DrawDownZag(wxDC
& dc
,
458 wxCoord x1
, wxCoord x2
,
459 wxCoord y1
, wxCoord y2
);
461 // draw the radio button bitmap for the given state
462 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
464 // draw check/radio - the bitmap must be a valid one by now
465 void DoDrawCheckOrRadioBitmap(wxDC
& dc
,
466 const wxString
& label
,
467 const wxBitmap
& bitmap
,
468 const wxRect
& rectTotal
,
473 // common part of DrawMenuItem() and DrawMenuBarItem()
474 void DoDrawMenuItem(wxDC
& dc
,
476 const wxString
& label
,
479 const wxString
& accel
= wxEmptyString
,
480 const wxBitmap
& bitmap
= wxNullBitmap
,
481 const wxGTKMenuGeometryInfo
*geometryInfo
= NULL
);
483 // initialize the combo bitmaps
484 void InitComboBitmaps();
487 const wxColourScheme
*m_scheme
;
490 wxSize m_sizeScrollbarArrow
;
499 // the checkbox bitmaps: first row is for the normal, second for the
500 // pressed state and the columns are for checked, unchecked and
501 // undeterminated respectively
502 wxBitmap m_bitmapsCheckbox
[2][3];
504 // the line wrap bitmap (drawn at the end of wrapped lines)
505 wxBitmap m_bmpLineWrap
;
507 // the combobox bitmaps
517 wxBitmap m_bitmapsCombo
[ComboState_Max
];
520 // ----------------------------------------------------------------------------
521 // wxGTKInputHandler and derived classes: process the keyboard and mouse
522 // messages according to GTK standards
523 // ----------------------------------------------------------------------------
525 class wxGTKInputHandler
: public wxInputHandler
528 wxGTKInputHandler() { }
530 virtual bool HandleKey(wxInputConsumer
*control
,
531 const wxKeyEvent
& event
,
533 virtual bool HandleMouse(wxInputConsumer
*control
,
534 const wxMouseEvent
& event
);
535 virtual bool HandleMouseMove(wxInputConsumer
*control
,
536 const wxMouseEvent
& event
);
541 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
544 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
545 : wxStdScrollBarInputHandler(renderer
, handler
) { }
548 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
550 // only arrows and the thumb can be highlighted
551 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
554 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
557 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
559 // only arrows can be pressed
563 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
566 // any button can be used to drag the scrollbar under GTK+
567 virtual bool IsAllowedButton(int WXUNUSED(button
)) const { return true; }
571 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
572 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
576 #endif // wxUSE_SCROLLBAR
580 class wxGTKCheckboxInputHandler
: public wxStdInputHandler
583 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
584 : wxStdInputHandler(handler
) { }
586 virtual bool HandleKey(wxInputConsumer
*control
,
587 const wxKeyEvent
& event
,
591 #endif // wxUSE_CHECKBOX
595 class wxGTKTextCtrlInputHandler
: public wxStdInputHandler
598 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
599 : wxStdInputHandler(handler
) { }
601 virtual bool HandleKey(wxInputConsumer
*control
,
602 const wxKeyEvent
& event
,
606 #endif // wxUSE_TEXTCTRL
608 // ----------------------------------------------------------------------------
609 // wxGTKColourScheme: uses the standard GTK colours
610 // ----------------------------------------------------------------------------
612 class wxGTKColourScheme
: public wxColourScheme
615 virtual wxColour
Get(StdColour col
) const;
616 virtual wxColour
GetBackground(wxWindow
*win
) const;
619 // ----------------------------------------------------------------------------
621 // ----------------------------------------------------------------------------
623 class wxGTKArtProvider
: public wxArtProvider
626 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
627 const wxArtClient
& client
,
631 // ----------------------------------------------------------------------------
633 // ----------------------------------------------------------------------------
635 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
637 class wxGTKTheme
: public wxTheme
641 virtual ~wxGTKTheme();
643 virtual wxRenderer
*GetRenderer();
644 virtual wxArtProvider
*GetArtProvider();
645 virtual wxInputHandler
*GetInputHandler(const wxString
& control
,
646 wxInputConsumer
*consumer
);
647 virtual wxColourScheme
*GetColourScheme();
650 wxGTKRenderer
*m_renderer
;
652 wxGTKArtProvider
*m_artProvider
;
654 // the names of the already created handlers and the handlers themselves
655 // (these arrays are synchronized)
656 wxSortedArrayString m_handlerNames
;
657 wxArrayHandlers m_handlers
;
659 wxGTKInputHandler
*m_handlerDefault
;
661 wxGTKColourScheme
*m_scheme
;
663 WX_DECLARE_THEME(gtk
)
666 // ============================================================================
668 // ============================================================================
670 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
672 // ----------------------------------------------------------------------------
674 // ----------------------------------------------------------------------------
676 wxGTKTheme::wxGTKTheme()
680 m_handlerDefault
= NULL
;
681 m_artProvider
= NULL
;
684 wxGTKTheme::~wxGTKTheme()
686 size_t count
= m_handlers
.GetCount();
687 for ( size_t n
= 0; n
< count
; n
++ )
689 if ( m_handlers
[n
] != m_handlerDefault
)
690 delete m_handlers
[n
];
693 delete m_handlerDefault
;
696 wxArtProvider::RemoveProvider(m_artProvider
);
699 wxRenderer
*wxGTKTheme::GetRenderer()
703 m_renderer
= new wxGTKRenderer(GetColourScheme());
709 wxArtProvider
*wxGTKTheme::GetArtProvider()
711 if ( !m_artProvider
)
713 m_artProvider
= new wxGTKArtProvider
;
716 return m_artProvider
;
719 wxColourScheme
*wxGTKTheme::GetColourScheme()
723 m_scheme
= new wxGTKColourScheme
;
728 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
,
729 wxInputConsumer
*consumer
)
731 wxInputHandler
*handler
= NULL
;
732 int n
= m_handlerNames
.Index(control
);
733 if ( n
== wxNOT_FOUND
)
735 static wxGTKInputHandler s_handlerDef
;
737 wxInputHandler
* const
738 handlerStd
= consumer
->DoGetStdInputHandler(&s_handlerDef
);
740 // create a new handler
742 if ( control
== wxINP_HANDLER_CHECKBOX
)
744 static wxGTKCheckboxInputHandler
s_handler(handlerStd
);
746 handler
= &s_handler
;
749 #endif // wxUSE_CHECKBOX
751 if ( control
== wxINP_HANDLER_SCROLLBAR
)
753 static wxGTKScrollBarInputHandler
s_handler(m_renderer
, handlerStd
);
755 handler
= &s_handler
;
758 #endif // wxUSE_SCROLLBAR
760 if ( control
== wxINP_HANDLER_TEXTCTRL
)
762 static wxGTKTextCtrlInputHandler
s_handler(handlerStd
);
764 handler
= &s_handler
;
767 #endif // wxUSE_TEXTCTRL
769 // no special handler for this control
770 handler
= handlerStd
;
773 n
= m_handlerNames
.Add(control
);
774 m_handlers
.Insert(handler
, n
);
776 else // we already have it
778 handler
= m_handlers
[n
];
784 // ============================================================================
786 // ============================================================================
788 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
791 if ( win
->UseBgCol() )
793 // use the user specified colour
794 col
= win
->GetBackgroundColour();
797 if ( !win
->ShouldInheritColours() )
799 // doesn't depend on the state
807 int flags
= win
->GetStateFlags();
809 // the colour set by the user should be used for the normal state
810 // and for the states for which we don't have any specific colours
811 if ( !col
.Ok() || (flags
!= 0) )
814 if ( wxDynamicCast(win
, wxScrollBar
) )
815 col
= Get(SCROLLBAR
);
817 #endif //wxUSE_SCROLLBAR
818 if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
819 col
= Get(CONTROL_CURRENT
);
820 else if ( flags
& wxCONTROL_PRESSED
)
821 col
= Get(CONTROL_PRESSED
);
830 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
834 case WINDOW
: return *wxWHITE
;
836 case SHADOW_DARK
: return *wxBLACK
;
837 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
838 case SHADOW_IN
: return wxColour(0xd6d6d6);
839 case SHADOW_OUT
: return wxColour(0x969696);
841 case CONTROL
: return wxColour(0xd6d6d6);
842 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
843 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
845 case CONTROL_TEXT
: return *wxBLACK
;
846 case CONTROL_TEXT_DISABLED
:
847 return wxColour(0x757575);
848 case CONTROL_TEXT_DISABLED_SHADOW
:
852 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
854 case HIGHLIGHT
: return wxColour(0x9c0000);
855 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
857 case GAUGE
: return Get(CONTROL_CURRENT
);
859 case TITLEBAR
: return wxColour(0xaeaaae);
860 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
861 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
862 case TITLEBAR_ACTIVE_TEXT
:
865 case DESKTOP
: return *wxBLACK
;
869 wxFAIL_MSG(_T("invalid standard colour"));
874 // ============================================================================
876 // ============================================================================
878 // ----------------------------------------------------------------------------
880 // ----------------------------------------------------------------------------
882 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
886 m_sizeScrollbarArrow
= wxSize(15, 14);
889 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
890 m_penDarkGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_OUT
), 0, wxSOLID
);
891 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
), 0, wxSOLID
);
892 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
893 m_penHighlight
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
), 0, wxSOLID
);
896 // ----------------------------------------------------------------------------
898 // ----------------------------------------------------------------------------
900 void wxGTKRenderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
904 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
905 dc
.DrawRectangle(*rect
);
911 void wxGTKRenderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
913 // draw the bottom and right sides
915 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
916 rect
->GetRight() + 1, rect
->GetBottom());
917 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
918 rect
->GetRight(), rect
->GetBottom());
925 void wxGTKRenderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
926 const wxPen
& pen1
, const wxPen
& pen2
)
928 // draw the rectangle
930 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
931 rect
->GetLeft(), rect
->GetBottom());
932 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
933 rect
->GetRight(), rect
->GetTop());
935 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
936 rect
->GetRight(), rect
->GetBottom());
937 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
938 rect
->GetRight() + 1, rect
->GetBottom());
944 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
950 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
955 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
956 rect
.GetLeft(), rect
.GetBottom() + 1);
960 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
961 rect
.GetRight() + 1, rect
.GetTop());
965 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
966 rect
.GetRight(), rect
.GetBottom() + 1);
970 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
971 rect
.GetRight() + 1, rect
.GetBottom());
975 wxFAIL_MSG(_T("unknown rectangle side"));
979 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
980 const wxPen
& pen1
, const wxPen
& pen2
)
982 // draw the rectangle
984 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
985 rect
->GetLeft(), rect
->GetBottom() + 1);
986 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
987 rect
->GetRight() + 1, rect
->GetTop());
989 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
990 rect
->GetRight(), rect
->GetBottom());
991 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
992 rect
->GetRight() + 1, rect
->GetBottom());
998 void wxGTKRenderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1000 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1001 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1004 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1006 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1007 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1010 void wxGTKRenderer::DrawBorder(wxDC
& dc
,
1012 const wxRect
& rectTotal
,
1013 int WXUNUSED(flags
),
1018 wxRect rect
= rectTotal
;
1022 case wxBORDER_SUNKEN
:
1023 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1025 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1026 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1030 case wxBORDER_STATIC
:
1031 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1033 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1037 case wxBORDER_RAISED
:
1038 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1040 DrawRaisedBorder(dc
, &rect
);
1044 case wxBORDER_DOUBLE
:
1045 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1047 DrawShadedRect(dc
, &rect
, m_penLightGrey
, m_penBlack
);
1048 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penDarkGrey
);
1049 DrawRect(dc
, &rect
, m_penLightGrey
);
1053 case wxBORDER_SIMPLE
:
1054 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1056 DrawRect(dc
, &rect
, m_penBlack
);
1061 wxFAIL_MSG(_T("unknown border type"));
1064 case wxBORDER_DEFAULT
:
1073 wxRect
wxGTKRenderer::GetBorderDimensions(wxBorder border
) const
1078 case wxBORDER_RAISED
:
1079 case wxBORDER_SUNKEN
:
1080 width
= 2*BORDER_THICKNESS
;
1083 case wxBORDER_SIMPLE
:
1084 case wxBORDER_STATIC
:
1085 width
= BORDER_THICKNESS
;
1088 case wxBORDER_DOUBLE
:
1089 width
= 3*BORDER_THICKNESS
;
1093 wxFAIL_MSG(_T("unknown border type"));
1096 case wxBORDER_DEFAULT
:
1106 rect
.height
= width
;
1111 bool wxGTKRenderer::AreScrollbarsInsideBorder() const
1113 // no, the scrollbars are outside the border in GTK+
1117 // ----------------------------------------------------------------------------
1119 // ----------------------------------------------------------------------------
1121 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
1123 const wxRect
& rectOrig
,
1127 wxRect rect
= rectOrig
;
1129 if ( border
!= wxBORDER_NONE
)
1131 if ( flags
& wxCONTROL_FOCUSED
)
1133 DrawRect(dc
, &rect
, m_penBlack
);
1134 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1138 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1139 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penHighlight
);
1147 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
1148 const wxRect
& rectTotal
,
1152 wxRect rect
= rectTotal
;
1154 if ( flags
& wxCONTROL_PRESSED
)
1156 // button pressed: draw a black border around it and an inward shade
1157 DrawRect(dc
, &rect
, m_penBlack
);
1159 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1161 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1162 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penDarkGrey
);
1167 // button not pressed
1169 if ( flags
& wxCONTROL_ISDEFAULT
)
1174 if ( flags
& wxCONTROL_FOCUSED
)
1176 // button is currently default: add an extra border around it
1177 DrawRect(dc
, &rect
, m_penBlack
);
1180 // now draw a normal button
1181 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1183 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1184 DrawAntiShadedRect(dc
, &rect
,
1185 wxPen(GetBackgroundColour(flags
), 0, wxSOLID
),
1196 // ----------------------------------------------------------------------------
1198 // ----------------------------------------------------------------------------
1200 void wxGTKRenderer::DrawHorizontalLine(wxDC
& dc
,
1201 wxCoord y
, wxCoord x1
, wxCoord x2
)
1203 dc
.SetPen(m_penDarkGrey
);
1204 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1205 dc
.SetPen(m_penHighlight
);
1207 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1210 void wxGTKRenderer::DrawVerticalLine(wxDC
& dc
,
1211 wxCoord x
, wxCoord y1
, wxCoord y2
)
1213 dc
.SetPen(m_penDarkGrey
);
1214 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1215 dc
.SetPen(m_penHighlight
);
1217 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1220 void wxGTKRenderer::DrawFrame(wxDC
& dc
,
1221 const wxString
& label
,
1227 wxCoord height
= 0; // of the label
1228 wxRect rectFrame
= rect
;
1229 if ( !label
.empty() )
1231 // the text should touch the top border of the rect, so the frame
1232 // itself should be lower
1233 dc
.GetTextExtent(label
, NULL
, &height
);
1234 rectFrame
.y
+= height
/ 2;
1235 rectFrame
.height
-= height
/ 2;
1237 // TODO: the +4 should be customizable
1240 rectText
.x
= rectFrame
.x
+ 4;
1241 rectText
.y
= rect
.y
;
1242 rectText
.width
= rectFrame
.width
- 8;
1243 rectText
.height
= height
;
1246 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1248 rectLabel
.width
+= 2;
1250 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1252 // GTK+ does it like this
1253 dc
.SetPen(m_penHighlight
);
1254 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
1255 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
1259 // just draw the complete frame
1260 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1261 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1265 // ----------------------------------------------------------------------------
1267 // ----------------------------------------------------------------------------
1269 void wxGTKRenderer::DrawLabel(wxDC
& dc
,
1270 const wxString
& label
,
1277 DrawButtonLabel(dc
, label
, wxNullBitmap
, rect
, flags
,
1278 alignment
, indexAccel
, rectBounds
);
1281 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
1282 const wxString
& label
,
1283 const wxBitmap
& image
,
1290 if ( flags
& wxCONTROL_DISABLED
)
1292 // make the text grey and draw a shade for it
1293 dc
.SetTextForeground(*wxWHITE
); // FIXME hardcoded colour
1294 wxRect rectShadow
= rect
;
1297 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1298 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT_DISABLED
));
1302 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT
));
1305 dc
.DrawLabel(label
, image
, rect
, alignment
, indexAccel
, rectBounds
);
1308 void wxGTKRenderer::DrawItem(wxDC
& dc
,
1309 const wxString
& label
,
1313 wxLogTrace(_T("listbox"), _T("drawing item '%s' at (%d, %d)-(%d, %d)"),
1316 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1319 if ( flags
& wxCONTROL_SELECTED
)
1321 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
), wxSOLID
));
1322 dc
.SetPen(*wxTRANSPARENT_PEN
);
1323 dc
.DrawRectangle(rect
);
1325 colFg
= dc
.GetTextForeground();
1326 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
1329 if ( flags
& wxCONTROL_FOCUSED
)
1331 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1332 wxRect rectFocus
= rect
;
1333 DrawRect(dc
, &rectFocus
, m_penBlack
);
1336 wxRect rectText
= rect
;
1339 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
1341 if ( flags
& wxCONTROL_SELECTED
)
1343 dc
.SetBackgroundMode(wxTRANSPARENT
);
1346 // restore the text colour
1349 dc
.SetTextForeground(colFg
);
1353 void wxGTKRenderer::DrawCheckItem(wxDC
& dc
,
1354 const wxString
& label
,
1355 const wxBitmap
& bitmap
,
1359 wxRect rectBitmap
= rect
;
1361 rectBitmap
.width
= GetCheckBitmapSize().x
;
1363 // never draw the focus rect around the check indicators here
1364 DrawCheckButton(dc
, wxEmptyString
, bitmap
, rectBitmap
, flags
& ~wxCONTROL_FOCUSED
);
1366 wxRect rectLabel
= rect
;
1367 wxCoord shift
= rectBitmap
.width
+ 2*GetCheckItemMargin();
1368 rectLabel
.x
+= shift
;
1369 rectLabel
.width
-= shift
;
1370 DrawItem(dc
, label
, rectLabel
, flags
);
1373 // ----------------------------------------------------------------------------
1374 // check/radion buttons
1375 // ----------------------------------------------------------------------------
1377 void wxGTKRenderer::DrawUndeterminedBitmap(wxDC
& dc
,
1378 const wxRect
& rectTotal
,
1381 // FIXME: For sure it is not GTK look but it is better than nothing.
1382 // Show me correct look and I will immediatelly make it better (ABX)
1383 wxRect rect
= rectTotal
;
1385 wxColour col1
, col2
;
1389 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1390 col2
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1394 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1395 col2
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1398 dc
.SetPen(*wxTRANSPARENT_PEN
);
1399 dc
.SetBrush(wxBrush(col1
, wxSOLID
));
1400 dc
.DrawRectangle(rect
);
1402 dc
.SetBrush(wxBrush(col2
, wxSOLID
));
1403 dc
.DrawRectangle(rect
);
1406 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1407 const wxRect
& rectTotal
,
1410 wxRect rect
= rectTotal
;
1411 DrawAntiRaisedBorder(dc
, &rect
);
1413 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1414 dc
.SetPen(wxPen(col
, 0, wxSOLID
));
1415 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1418 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1419 //else: it is SHADOW_IN, leave as is
1421 dc
.SetPen(*wxTRANSPARENT_PEN
);
1422 dc
.SetBrush(wxBrush(col
, wxSOLID
));
1423 dc
.DrawRectangle(rect
);
1426 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1428 wxRect rect
= rectTotal
;
1429 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1430 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1432 dc
.SetPen(*wxTRANSPARENT_PEN
);
1433 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), wxSOLID
));
1434 dc
.DrawRectangle(rect
);
1437 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1443 xRight
= rect
.GetRight(),
1444 yBottom
= rect
.GetBottom();
1446 wxCoord yMid
= (y
+ yBottom
) / 2;
1448 // this looks ugly when the background colour of the control is not the
1449 // same ours - radiobox is not transparent as it should be
1451 // first fill the middle: as FloodFill() is not implemented on all
1452 // platforms, this is the only thing to do
1453 wxColour colBg
= flags
& wxCONTROL_CURRENT
1454 ? wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
)
1455 : wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1456 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
1457 dc
.SetPen(*wxTRANSPARENT_PEN
);
1458 dc
.DrawRectangle(rect
);
1461 // then draw the upper half
1462 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1463 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1464 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1467 if ( flags
& wxCONTROL_CHECKED
)
1468 dc
.SetPen(m_penBlack
);
1469 else if ( flags
& wxCONTROL_PRESSED
)
1470 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1471 else // unchecked and unpressed
1475 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1477 // and then the lower one
1478 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1479 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1480 if ( !(flags
& wxCONTROL_CHECKED
) )
1481 dc
.SetPen(m_penDarkGrey
);
1482 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1484 if ( !(flags
& wxCONTROL_CHECKED
) )
1485 drawIt
= true; // with the same pen
1486 else if ( flags
& wxCONTROL_PRESSED
)
1488 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1491 else // checked and unpressed
1495 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1498 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1504 wxCoord xMid
= (x1
+ x2
) / 2;
1505 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1506 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1509 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1515 wxCoord xMid
= (x1
+ x2
) / 2;
1516 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1517 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1520 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1522 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1524 // init the bitmaps once only
1526 wxSize size
= GetCheckBitmapSize();
1527 rect
.width
= size
.x
;
1528 rect
.height
= size
.y
;
1529 for ( int i
= 0; i
< 2; i
++ )
1531 for ( int j
= 0; j
< 3; j
++ )
1532 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1538 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1539 DrawCheckBitmap(dc
, rect
);
1542 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1543 DrawUncheckBitmap(dc
, rect
, false);
1545 // normal undeterminated
1546 dc
.SelectObject(m_bitmapsCheckbox
[0][2]);
1547 DrawUndeterminedBitmap(dc
, rect
, false);
1550 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1552 // pressed unchecked
1553 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1554 DrawUncheckBitmap(dc
, rect
, true);
1556 // pressed undeterminated
1557 dc
.SelectObject(m_bitmapsCheckbox
[1][2]);
1558 DrawUndeterminedBitmap(dc
, rect
, true);
1561 int row
= flags
& wxCONTROL_PRESSED
1564 int col
= flags
& wxCONTROL_CHECKED
1566 : ( flags
& wxCONTROL_UNDETERMINED
1570 return m_bitmapsCheckbox
[row
][col
];
1573 wxBitmap
wxGTKRenderer::GetLineWrapBitmap() const
1575 if ( !m_bmpLineWrap
.Ok() )
1577 // the line wrap bitmap as used by GTK+
1578 #define line_wrap_width 6
1579 #define line_wrap_height 9
1580 static const char line_wrap_bits
[] =
1582 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1585 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1586 if ( !bmpLineWrap
.Ok() )
1588 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1592 wxConstCast(this, wxGTKRenderer
)->m_bmpLineWrap
= bmpLineWrap
;
1596 return m_bmpLineWrap
;
1599 void wxGTKRenderer::DrawCheckButton(wxDC
& dc
,
1600 const wxString
& label
,
1601 const wxBitmap
& bitmapOrig
,
1602 const wxRect
& rectTotal
,
1608 if ( bitmapOrig
.Ok() )
1610 bitmap
= bitmapOrig
;
1614 bitmap
= GetCheckBitmap(flags
);
1617 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1618 flags
, align
, indexAccel
);
1621 void wxGTKRenderer::DoDrawCheckOrRadioBitmap(wxDC
& dc
,
1622 const wxString
& label
,
1623 const wxBitmap
& bitmap
,
1624 const wxRect
& rectTotal
,
1629 wxRect rect
= rectTotal
;
1631 if ( flags
& wxCONTROL_FOCUSED
)
1633 // draw the focus border around everything
1634 DrawRect(dc
, &rect
, m_penBlack
);
1638 // the border does not offset the string under GTK
1642 // calculate the position of the bitmap and of the label
1644 yBmp
= rect
.y
+ (rect
.height
- bitmap
.GetHeight()) / 2;
1647 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
1648 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
1650 if ( align
== wxALIGN_RIGHT
)
1652 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
1653 rectLabel
.x
= rect
.x
+ 2;
1654 rectLabel
.SetRight(xBmp
);
1656 else // normal (checkbox to the left of the text) case
1659 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 4;
1660 rectLabel
.SetRight(rect
.GetRight());
1663 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
1665 DrawLabel(dc
, label
, rectLabel
, flags
,
1666 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1669 void wxGTKRenderer::DrawRadioButton(wxDC
& dc
,
1670 const wxString
& label
,
1671 const wxBitmap
& bitmapOrig
,
1672 const wxRect
& rectTotal
,
1678 if ( bitmapOrig
.Ok() )
1680 bitmap
= bitmapOrig
;
1685 wxSize size
= GetRadioBitmapSize();
1686 rect
.width
= size
.x
;
1687 rect
.height
= size
.y
;
1688 bitmap
.Create(rect
.width
, rect
.height
);
1690 dc
.SelectObject(bitmap
);
1691 dc
.SetBackground(*wxLIGHT_GREY_BRUSH
);
1693 DrawRadioBitmap(dc
, rect
, flags
);
1695 // must unselect the bitmap before setting a mask for it because of the
1697 dc
.SelectObject(wxNullBitmap
);
1698 bitmap
.SetMask(new wxMask(bitmap
, *wxLIGHT_GREY
));
1701 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1702 flags
, align
, indexAccel
);
1706 void wxGTKRenderer::DrawToolBarButton(wxDC
& dc
,
1707 const wxString
& label
,
1708 const wxBitmap
& bitmap
,
1709 const wxRect
& rectOrig
,
1711 long WXUNUSED(style
),
1714 // we don't draw the separators at all
1715 if ( !label
.empty() || bitmap
.Ok() )
1717 wxRect rect
= rectOrig
;
1718 rect
.Deflate(BORDER_THICKNESS
);
1720 if ( flags
& wxCONTROL_PRESSED
)
1722 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
, &rect
);
1724 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), rect
);
1726 else if ( flags
& wxCONTROL_CURRENT
)
1728 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rect
);
1730 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rect
);
1733 if(tbarStyle
& wxTB_TEXT
)
1735 if(tbarStyle
& wxTB_HORIZONTAL
)
1737 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1741 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
1746 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
1747 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
1748 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
1752 #endif // wxUSE_TOOLBAR
1754 // ----------------------------------------------------------------------------
1756 // ----------------------------------------------------------------------------
1760 wxRect
wxGTKRenderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
1761 const wxRect
& rect
) const
1763 wxRect rectTotal
= rect
;
1764 rectTotal
.Inflate(2*BORDER_THICKNESS
);
1768 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1770 wxCoord
*extraSpaceBeyond
) const
1772 wxRect rectText
= rect
;
1773 rectText
.Deflate(2*BORDER_THICKNESS
);
1775 if ( text
->WrapLines() )
1777 // leave enough for the line wrap bitmap indicator
1778 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1780 rectText
.width
-= widthMark
;
1782 if ( extraSpaceBeyond
)
1783 *extraSpaceBeyond
= widthMark
;
1789 #endif // wxUSE_TEXTCTRL
1791 void wxGTKRenderer::DrawTextLine(wxDC
& dc
,
1792 const wxString
& text
,
1798 // TODO: GTK+ draws selection even for unfocused controls, just with
1799 // different colours
1800 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
1803 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1805 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1807 // for a mono bitmap he colours it appears in depends on the current text
1808 // colours, so set them correctly
1810 if ( bmpLineWrap
.GetDepth() == 1 )
1812 colFgOld
= dc
.GetTextForeground();
1814 // FIXME: I wonder what should we do if the background is black too?
1815 dc
.SetTextForeground(*wxBLACK
);
1818 dc
.DrawBitmap(bmpLineWrap
,
1819 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1821 if ( colFgOld
.Ok() )
1823 // restore old colour
1824 dc
.SetTextForeground(colFgOld
);
1828 // ----------------------------------------------------------------------------
1830 // ----------------------------------------------------------------------------
1832 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1833 const wxRect
& rectOrig
,
1835 const wxString
& label
,
1836 const wxBitmap
& bitmap
,
1840 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1841 #define REVERSE_FOR_VERTICAL(X,Y) \
1842 SELECT_FOR_VERTICAL(X,Y) \
1844 SELECT_FOR_VERTICAL(Y,X)
1846 wxRect rect
= rectOrig
;
1848 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1850 // the current tab is drawn indented (to the top for default case) and
1851 // bigger than the other ones
1852 const wxSize indent
= GetTabIndent();
1853 if ( flags
& wxCONTROL_SELECTED
)
1855 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1856 SELECT_FOR_VERTICAL( 0, indent
.y
));
1860 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1867 rect
.height
+= indent
.y
;
1874 rect
.width
+= indent
.x
;
1879 // selected tab has different colour
1880 wxColour col
= flags
& wxCONTROL_SELECTED
1881 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1882 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1883 DoDrawBackground(dc
, col
, rect
);
1885 if ( flags
& wxCONTROL_FOCUSED
)
1887 // draw the focus rect
1888 wxRect rectBorder
= rect
;
1889 rectBorder
.Deflate(4, 3);
1890 if ( dir
== wxBOTTOM
)
1891 rectBorder
.Offset(0, -1);
1892 if ( dir
== wxRIGHT
)
1893 rectBorder
.Offset(-1, 0);
1895 DrawRect(dc
, &rectBorder
, m_penBlack
);
1898 // draw the text, image and the focus around them (if necessary)
1899 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1900 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1902 rectLabel
.Deflate(1, 1);
1905 // draw it horizontally into memory and rotate for screen
1907 wxBitmap bitmapRotated
,
1908 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1909 rectLabel
.y
+ rectLabel
.height
);
1910 dcMem
.SelectObject(bitmapMem
);
1911 dcMem
.SetBackground(dc
.GetBackground());
1912 dcMem
.SetFont(dc
.GetFont());
1913 dcMem
.SetTextForeground(dc
.GetTextForeground());
1917 wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) )
1920 #endif // wxUSE_IMAGE
1922 dcMem
.DrawLabel(label
, bitmapRotated
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1923 dcMem
.SelectObject(wxNullBitmap
);
1924 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1926 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
))
1930 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1934 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1937 // now draw the tab itself
1938 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1939 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1940 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1941 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1947 // left orientation looks like top but IsVertical makes x and y reversed
1949 // top is not vertical so use coordinates in written order
1950 dc
.SetPen(m_penHighlight
);
1951 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1952 REVERSE_FOR_VERTICAL(x
, y
));
1953 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
),
1954 REVERSE_FOR_VERTICAL(x2
, y
));
1956 dc
.SetPen(m_penBlack
);
1957 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1958 REVERSE_FOR_VERTICAL(x2
, y
));
1960 dc
.SetPen(m_penDarkGrey
);
1961 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1962 REVERSE_FOR_VERTICAL(x2
- 1, y
+ 1));
1964 if ( flags
& wxCONTROL_SELECTED
)
1966 dc
.SetPen(m_penLightGrey
);
1968 // overwrite the part of the border below this tab
1969 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1970 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1972 // and the shadow of the tab to the left of us
1973 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ 2),
1974 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1979 // right orientation looks like bottom but IsVertical makes x and y reversed
1981 // bottom is not vertical so use coordinates in written order
1982 dc
.SetPen(m_penHighlight
);
1984 // we need to continue one pixel further to overwrite the corner of
1985 // the border for the selected tab
1986 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
1987 REVERSE_FOR_VERTICAL(x
, y2
));
1989 // it doesn't work like this (TODO: implement it properly)
1991 // erase the corner of the tab to the right
1992 dc
.SetPen(m_penLightGrey
);
1993 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1994 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 2));
1995 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 1));
1998 dc
.SetPen(m_penBlack
);
1999 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
),
2000 REVERSE_FOR_VERTICAL(x2
, y2
));
2001 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
2002 REVERSE_FOR_VERTICAL(x2
, y2
));
2004 dc
.SetPen(m_penDarkGrey
);
2005 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 2, y2
- 1),
2006 REVERSE_FOR_VERTICAL(x2
- 1, y2
- 1));
2007 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
2008 REVERSE_FOR_VERTICAL(x2
- 1, y2
));
2010 if ( flags
& wxCONTROL_SELECTED
)
2012 dc
.SetPen(m_penLightGrey
);
2014 // overwrite the part of the (double!) border above this tab
2015 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
2016 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
2017 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
2018 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
2020 // and the shadow of the tab to the left of us
2021 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- 1),
2022 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
2030 // ----------------------------------------------------------------------------
2032 // ----------------------------------------------------------------------------
2034 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
2036 wxOrientation orient
) const
2038 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
2042 wxRect rectShaft
= GetSliderShaftRect(rect
, lenThumb
, orient
);
2043 if ( orient
== wxHORIZONTAL
)
2045 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
2046 size
.y
= rectShaft
.height
;
2050 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
2051 size
.x
= rectShaft
.width
;
2057 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
2058 int WXUNUSED(lenThumb
),
2059 wxOrientation
WXUNUSED(orient
),
2060 long WXUNUSED(style
)) const
2062 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
2065 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
2066 const wxRect
& rectOrig
,
2067 int WXUNUSED(lenThumb
),
2068 wxOrientation
WXUNUSED(orient
),
2070 long WXUNUSED(style
),
2073 wxRect rect
= rectOrig
;
2075 // draw the border first
2076 if ( flags
& wxCONTROL_FOCUSED
)
2078 DrawRect(dc
, &rect
, m_penBlack
);
2079 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
2081 else // not focused, normal
2083 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
2084 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
2087 // and the background
2088 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
2094 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
2095 const wxRect
& rectOrig
,
2096 wxOrientation orient
,
2097 int WXUNUSED(flags
),
2098 long WXUNUSED(style
))
2100 // draw the thumb border
2101 wxRect rect
= rectOrig
;
2102 DrawAntiRaisedBorder(dc
, &rect
);
2104 // draw the handle in the middle
2105 if ( orient
== wxVERTICAL
)
2107 rect
.height
= 2*BORDER_THICKNESS
;
2108 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2112 rect
.width
= 2*BORDER_THICKNESS
;
2113 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2116 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
2119 #endif // wxUSE_SLIDER
2123 // ----------------------------------------------------------------------------
2125 // ----------------------------------------------------------------------------
2127 // wxGTKMenuGeometryInfo: the wxMenuGeometryInfo used by wxGTKRenderer
2128 class WXDLLEXPORT wxGTKMenuGeometryInfo
: public wxMenuGeometryInfo
2131 virtual wxSize
GetSize() const { return m_size
; }
2133 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2134 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2136 wxCoord
GetItemHeight() const { return m_heightItem
; }
2139 // the total size of the menu
2142 // the offset of the start of the menu item label
2145 // the offset of the start of the accel label
2148 // the height of a normal (not separator) item
2149 wxCoord m_heightItem
;
2151 friend wxMenuGeometryInfo
*
2152 wxGTKRenderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2155 // FIXME: all constants are hardcoded but shouldn't be
2156 static const wxCoord MENU_LEFT_MARGIN
= 9;
2157 static const wxCoord MENU_RIGHT_MARGIN
= 6;
2159 static const wxCoord MENU_HORZ_MARGIN
= 6;
2160 static const wxCoord MENU_VERT_MARGIN
= 3;
2162 // the margin around bitmap/check marks (on each side)
2163 static const wxCoord MENU_BMP_MARGIN
= 2;
2165 // the margin between the labels and accel strings
2166 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2168 // the separator height in pixels: in fact, strangely enough, the real height
2169 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2171 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2173 // the size of the standard checkmark bitmap
2174 static const wxCoord MENU_CHECK_SIZE
= 9;
2176 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
2178 const wxString
& label
,
2182 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
);
2185 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
2187 const wxMenuGeometryInfo
& gi
,
2188 const wxString
& label
,
2189 const wxString
& accel
,
2190 const wxBitmap
& bitmap
,
2194 const wxGTKMenuGeometryInfo
& geomInfo
= (const wxGTKMenuGeometryInfo
&)gi
;
2199 rect
.width
= geomInfo
.GetSize().x
;
2200 rect
.height
= geomInfo
.GetItemHeight();
2202 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
, accel
, bitmap
, &geomInfo
);
2205 void wxGTKRenderer::DoDrawMenuItem(wxDC
& dc
,
2206 const wxRect
& rectOrig
,
2207 const wxString
& label
,
2210 const wxString
& accel
,
2211 const wxBitmap
& bitmap
,
2212 const wxGTKMenuGeometryInfo
*geometryInfo
)
2214 wxRect rect
= rectOrig
;
2216 // draw the selected item specially
2217 if ( flags
& wxCONTROL_SELECTED
)
2220 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
2222 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rectIn
);
2225 rect
.Deflate(MENU_HORZ_MARGIN
, MENU_VERT_MARGIN
);
2227 // draw the bitmap: use the bitmap provided or the standard checkmark for
2228 // the checkable items
2231 wxBitmap bmp
= bitmap
;
2232 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKABLE
) )
2234 bmp
= GetCheckBitmap(flags
);
2239 rect
.SetRight(geometryInfo
->GetLabelOffset());
2240 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2243 //else: menubar items don't have bitmaps
2248 rect
.x
= geometryInfo
->GetLabelOffset();
2249 rect
.SetRight(geometryInfo
->GetAccelOffset());
2252 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2254 // draw the accel string
2255 if ( !accel
.empty() )
2257 // menubar items shouldn't have them
2258 wxCHECK_RET( geometryInfo
, _T("accel strings only valid for menus") );
2260 rect
.x
= geometryInfo
->GetAccelOffset();
2261 rect
.SetRight(geometryInfo
->GetSize().x
);
2263 // NB: no accel index here
2264 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2267 // draw the submenu indicator
2268 if ( flags
& wxCONTROL_ISSUBMENU
)
2270 wxCHECK_RET( geometryInfo
, _T("wxCONTROL_ISSUBMENU only valid for menus") );
2272 rect
.x
= geometryInfo
->GetSize().x
- MENU_RIGHT_MARGIN
;
2273 rect
.width
= MENU_RIGHT_MARGIN
;
2275 DrawArrow(dc
, wxRIGHT
, rect
, flags
);
2279 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
2281 const wxMenuGeometryInfo
& geomInfo
)
2283 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2286 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2288 wxSize size
= sizeText
;
2290 // TODO: make this configurable
2291 size
.x
+= 2*MENU_HORZ_MARGIN
;
2292 size
.y
+= 2*MENU_VERT_MARGIN
;
2297 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
2298 const wxMenu
& menu
) const
2300 // prepare the dc: for now we draw all the items with the system font
2302 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2304 // the height of a normal item
2305 wxCoord heightText
= dc
.GetCharHeight();
2310 // the max length of label and accel strings: the menu width is the sum of
2311 // them, even if they're for different items (as the accels should be
2314 // the max length of the bitmap is never 0 as Windows always leaves enough
2315 // space for a check mark indicator
2316 wxCoord widthLabelMax
= 0,
2318 widthBmpMax
= MENU_LEFT_MARGIN
;
2320 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
2322 node
= node
->GetNext() )
2324 // height of this item
2327 wxMenuItem
*item
= node
->GetData();
2328 if ( item
->IsSeparator() )
2330 h
= MENU_SEPARATOR_HEIGHT
;
2332 else // not separator
2337 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2338 if ( widthLabel
> widthLabelMax
)
2340 widthLabelMax
= widthLabel
;
2344 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2345 if ( widthAccel
> widthAccelMax
)
2347 widthAccelMax
= widthAccel
;
2350 const wxBitmap
& bmp
= item
->GetBitmap();
2353 wxCoord widthBmp
= bmp
.GetWidth();
2354 if ( widthBmp
> widthBmpMax
)
2355 widthBmpMax
= widthBmp
;
2357 //else if ( item->IsCheckable() ): no need to check for this as
2358 // MENU_LEFT_MARGIN is big enough to show the check mark
2361 h
+= 2*MENU_VERT_MARGIN
;
2363 // remember the item position and height
2364 item
->SetGeometry(height
, h
);
2369 // bundle the metrics into a struct and return it
2370 wxGTKMenuGeometryInfo
*gi
= new wxGTKMenuGeometryInfo
;
2372 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2373 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2374 if ( widthAccelMax
> 0 )
2376 // if we actually have any accesl, add a margin
2377 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2380 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2382 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2383 gi
->m_size
.y
= height
;
2388 #endif // wxUSE_MENUS
2392 // ----------------------------------------------------------------------------
2394 // ----------------------------------------------------------------------------
2397 wxGTKRenderer::GetStatusBarBorders(wxCoord
* WXUNUSED(borderBetweenFields
)) const
2402 void wxGTKRenderer::DrawStatusField(wxDC
& WXUNUSED(dc
),
2403 const wxRect
& WXUNUSED(rect
),
2404 const wxString
& WXUNUSED(label
),
2405 int WXUNUSED(flags
), int WXUNUSED(style
))
2409 #endif // wxUSE_STATUSBAR
2411 // ----------------------------------------------------------------------------
2413 // ----------------------------------------------------------------------------
2415 void wxGTKRenderer::InitComboBitmaps()
2417 wxSize sizeArrow
= m_sizeScrollbarArrow
;
2423 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
2425 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
2428 static const int comboButtonFlags
[ComboState_Max
] =
2436 wxRect
rect(sizeArrow
);
2439 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
2441 int flags
= comboButtonFlags
[n
];
2443 dc
.SelectObject(m_bitmapsCombo
[n
]);
2444 DoDrawBackground(dc
, GetBackgroundColour(flags
), rect
);
2445 DrawArrow(dc
, wxDOWN
, rect
, flags
);
2449 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
2451 wxBitmap
*bmpPressed
,
2452 wxBitmap
*bmpDisabled
)
2454 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
2460 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
2462 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
2464 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
2466 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
2469 // ----------------------------------------------------------------------------
2471 // ----------------------------------------------------------------------------
2473 void wxGTKRenderer::DoDrawBackground(wxDC
& dc
,
2474 const wxColour
& col
,
2476 wxWindow
* WXUNUSED(window
))
2478 wxBrush
brush(col
, wxSOLID
);
2480 dc
.SetPen(*wxTRANSPARENT_PEN
);
2481 dc
.DrawRectangle(rect
);
2484 void wxGTKRenderer::DrawBackground(wxDC
& dc
,
2485 const wxColour
& col
,
2490 wxColour colBg
= col
.Ok() ? col
: GetBackgroundColour(flags
);
2491 DoDrawBackground(dc
, colBg
, rect
, window
);
2494 // ----------------------------------------------------------------------------
2496 // ----------------------------------------------------------------------------
2498 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
2502 static const wxDirection sides
[] =
2504 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
2507 wxRect rect1
, rect2
, rectInner
;
2513 rectInner
.Inflate(-2);
2515 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
2517 // find the side not to draw and also adjust the rectangles to compensate
2519 wxDirection sideToOmit
;
2523 sideToOmit
= wxDOWN
;
2525 rectInner
.height
+= 1;
2533 rectInner
.height
+= 1;
2537 sideToOmit
= wxRIGHT
;
2539 rectInner
.width
+= 1;
2543 sideToOmit
= wxLEFT
;
2547 rectInner
.width
+= 1;
2551 wxFAIL_MSG(_T("unknown arrow direction"));
2555 // the outer rect first
2557 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2559 wxDirection side
= sides
[n
];
2560 if ( side
== sideToOmit
)
2563 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
2566 // and then the inner one
2567 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2569 wxDirection side
= sides
[n
];
2570 if ( side
== sideToOmit
)
2573 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
2579 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
2581 const wxRect
& rectArrow
,
2584 // first of all, draw the border around it - but we don't want the border
2585 // on the side opposite to the arrow point
2586 wxRect rect
= rectArrow
;
2587 DrawArrowBorder(dc
, &rect
, dir
);
2589 // then the arrow itself
2590 DrawArrow(dc
, dir
, rect
, flags
);
2593 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
2594 // these people are just crazy :-(
2595 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2608 wxPoint ptArrow
[Point_Max
];
2610 wxColour colInside
= GetBackgroundColour(flags
);
2612 if ( flags
& wxCONTROL_DISABLED
)
2614 penShadow
[0] = m_penDarkGrey
;
2615 penShadow
[1] = m_penDarkGrey
;
2616 penShadow
[2] = wxNullPen
;
2617 penShadow
[3] = wxNullPen
;
2619 else if ( flags
& wxCONTROL_PRESSED
)
2621 penShadow
[0] = m_penDarkGrey
;
2622 penShadow
[1] = m_penHighlight
;
2623 penShadow
[2] = wxNullPen
;
2624 penShadow
[3] = m_penBlack
;
2626 else // normal arrow
2628 penShadow
[0] = m_penHighlight
;
2629 penShadow
[1] = m_penBlack
;
2630 penShadow
[2] = m_penDarkGrey
;
2631 penShadow
[3] = wxNullPen
;
2635 if ( dir
== wxUP
|| dir
== wxDOWN
)
2638 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2642 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2645 // draw the arrow interior
2646 dc
.SetPen(*wxTRANSPARENT_PEN
);
2647 dc
.SetBrush(wxBrush(colInside
, wxSOLID
));
2652 ptArrow
[Point_First
].x
= rect
.GetLeft();
2653 ptArrow
[Point_First
].y
= rect
.GetBottom();
2654 ptArrow
[Point_Second
].x
= middle
;
2655 ptArrow
[Point_Second
].y
= rect
.GetTop();
2656 ptArrow
[Point_Third
].x
= rect
.GetRight();
2657 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2661 ptArrow
[Point_First
] = rect
.GetPosition();
2662 ptArrow
[Point_Second
].x
= middle
;
2663 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2664 ptArrow
[Point_Third
].x
= rect
.GetRight();
2665 ptArrow
[Point_Third
].y
= rect
.GetTop();
2669 ptArrow
[Point_First
].x
= rect
.GetRight();
2670 ptArrow
[Point_First
].y
= rect
.GetTop();
2671 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2672 ptArrow
[Point_Second
].y
= middle
;
2673 ptArrow
[Point_Third
].x
= rect
.GetRight();
2674 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2678 ptArrow
[Point_First
] = rect
.GetPosition();
2679 ptArrow
[Point_Second
].x
= rect
.GetRight();
2680 ptArrow
[Point_Second
].y
= middle
;
2681 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2682 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2686 wxFAIL_MSG(_T("unknown arrow direction"));
2689 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2691 // draw the arrow border
2692 dc
.SetPen(penShadow
[0]);
2696 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2697 dc
.DrawPoint(ptArrow
[Point_First
]);
2698 if ( penShadow
[3].Ok() )
2700 dc
.SetPen(penShadow
[3]);
2701 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2702 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2704 dc
.SetPen(penShadow
[1]);
2705 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2706 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2707 dc
.DrawPoint(ptArrow
[Point_Third
]);
2708 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2709 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2710 if ( penShadow
[2].Ok() )
2712 dc
.SetPen(penShadow
[2]);
2713 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2714 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2715 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2716 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2721 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2722 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2723 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2724 if ( penShadow
[2].Ok() )
2726 dc
.SetPen(penShadow
[2]);
2727 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2728 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2730 dc
.SetPen(penShadow
[1]);
2731 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2732 dc
.DrawPoint(ptArrow
[Point_Third
]);
2736 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2737 dc
.DrawPoint(ptArrow
[Point_First
]);
2738 if ( penShadow
[2].Ok() )
2740 dc
.SetPen(penShadow
[2]);
2741 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2742 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2743 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2744 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2746 dc
.SetPen(penShadow
[1]);
2747 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2748 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2749 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2750 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2754 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2755 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2756 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2757 dc
.SetPen(penShadow
[1]);
2758 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2759 dc
.DrawPoint(ptArrow
[Point_Third
]);
2763 wxFAIL_MSG(_T("unknown arrow direction"));
2768 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2770 wxOrientation orient
)
2772 if ( orient
== wxVERTICAL
)
2774 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2776 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2778 rect
->Inflate(-1, 0);
2780 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2782 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2784 rect
->Inflate(-1, 0);
2788 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2790 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2792 rect
->Inflate(0, -1);
2794 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2796 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2798 rect
->Inflate(0, -1);
2802 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2803 wxOrientation orient
,
2807 // the thumb is never pressed never has focus border under GTK and the
2808 // scrollbar background never changes at all
2809 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2811 // we don't want the border in the direction of the scrollbar movement
2812 wxRect rectThumb
= rect
;
2813 DrawThumbBorder(dc
, &rectThumb
, orient
);
2815 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2816 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2819 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2820 wxOrientation orient
,
2822 int WXUNUSED(flags
))
2824 wxRect rectBar
= rect
;
2825 DrawThumbBorder(dc
, &rectBar
, orient
);
2826 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2829 void wxGTKRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2831 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2835 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2836 wxScrollBar::Element elem
,
2839 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2840 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2842 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2844 elem
= wxScrollBar::Element_Bar_2
;
2847 return StandardGetScrollbarRect(scrollbar
, elem
,
2849 GetScrollbarArrowSize(scrollbar
));
2852 wxCoord
wxGTKRenderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
2854 return StandardScrollBarSize(scrollbar
, GetScrollbarArrowSize(scrollbar
));
2857 wxHitTest
wxGTKRenderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
2858 const wxPoint
& pt
) const
2860 return StandardHitTestScrollbar(scrollbar
, pt
,
2861 GetScrollbarArrowSize(scrollbar
));
2864 wxCoord
wxGTKRenderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
2867 return StandardScrollbarToPixel(scrollbar
, thumbPos
,
2868 GetScrollbarArrowSize(scrollbar
));
2871 int wxGTKRenderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
2874 return StandardPixelToScrollbar(scrollbar
, coord
,
2875 GetScrollbarArrowSize(scrollbar
));
2877 #endif // wxUSE_SCROLLBAR
2879 // ----------------------------------------------------------------------------
2881 // ----------------------------------------------------------------------------
2883 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2886 if ( wxDynamicCast(window
, wxBitmapButton
) )
2891 #endif // wxUSE_BMPBUTTON
2892 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
2895 || wxDynamicCast(window
, wxButton
)
2896 # endif // wxUSE_BUTTON
2897 # if wxUSE_TOGGLEBTN
2898 || wxDynamicCast(window
, wxToggleButton
)
2899 # endif // wxUSE_TOGGLEBTN
2902 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2904 // TODO: this is ad hoc...
2905 size
->x
+= 3*window
->GetCharWidth();
2906 wxCoord minBtnHeight
= 18;
2907 if ( size
->y
< minBtnHeight
)
2908 size
->y
= minBtnHeight
;
2910 // button border width
2914 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
2916 if ( wxDynamicCast(window
, wxScrollBar
) )
2918 // we only set the width of vert scrollbars and height of the
2920 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2921 size
->y
= m_sizeScrollbarArrow
.x
;
2923 size
->x
= m_sizeScrollbarArrow
.x
;
2926 #endif // wxUSE_SCROLLBAR
2928 // take into account the border width
2929 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
2930 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
2931 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
2935 // ----------------------------------------------------------------------------
2936 // top level windows
2937 // ----------------------------------------------------------------------------
2939 void wxGTKRenderer::DrawFrameTitleBar(wxDC
& WXUNUSED(dc
),
2940 const wxRect
& WXUNUSED(rect
),
2941 const wxString
& WXUNUSED(title
),
2942 const wxIcon
& WXUNUSED(icon
),
2943 int WXUNUSED(flags
),
2944 int WXUNUSED(specialButton
),
2945 int WXUNUSED(specialButtonFlag
))
2949 void wxGTKRenderer::DrawFrameBorder(wxDC
& WXUNUSED(dc
),
2950 const wxRect
& WXUNUSED(rect
),
2951 int WXUNUSED(flags
))
2955 void wxGTKRenderer::DrawFrameBackground(wxDC
& WXUNUSED(dc
),
2956 const wxRect
& WXUNUSED(rect
),
2957 int WXUNUSED(flags
))
2961 void wxGTKRenderer::DrawFrameTitle(wxDC
& WXUNUSED(dc
),
2962 const wxRect
& WXUNUSED(rect
),
2963 const wxString
& WXUNUSED(title
),
2964 int WXUNUSED(flags
))
2968 void wxGTKRenderer::DrawFrameIcon(wxDC
& WXUNUSED(dc
),
2969 const wxRect
& WXUNUSED(rect
),
2970 const wxIcon
& WXUNUSED(icon
),
2971 int WXUNUSED(flags
))
2975 void wxGTKRenderer::DrawFrameButton(wxDC
& WXUNUSED(dc
),
2976 wxCoord
WXUNUSED(x
),
2977 wxCoord
WXUNUSED(y
),
2978 int WXUNUSED(button
),
2979 int WXUNUSED(flags
))
2984 wxGTKRenderer::GetFrameClientArea(const wxRect
& rect
,
2985 int WXUNUSED(flags
)) const
2991 wxGTKRenderer::GetFrameTotalSize(const wxSize
& clientSize
,
2992 int WXUNUSED(flags
)) const
2997 wxSize
wxGTKRenderer::GetFrameMinSize(int WXUNUSED(flags
)) const
3002 wxSize
wxGTKRenderer::GetFrameIconSize() const
3004 return wxSize(wxDefaultCoord
, wxDefaultCoord
);
3008 wxGTKRenderer::HitTestFrame(const wxRect
& WXUNUSED(rect
),
3009 const wxPoint
& WXUNUSED(pt
),
3010 int WXUNUSED(flags
)) const
3012 return wxHT_TOPLEVEL_CLIENT_AREA
;
3016 // ----------------------------------------------------------------------------
3018 // ----------------------------------------------------------------------------
3020 /* Copyright (c) Julian Smart */
3021 static const char *error_xpm
[] = {
3022 /* columns rows colors chars-per-pixel */
3036 " ................. ",
3037 " ................... ",
3038 " ....................... ",
3039 " ......................... ",
3040 " ........................... ",
3041 " ...........................X ",
3042 " .............................X ",
3043 " ............................... ",
3044 " ...............................X ",
3045 " .................................X ",
3046 " .................................X ",
3047 " .................................XX ",
3048 " ...ooooooooooooooooooooooooooo...XX ",
3049 " ....ooooooooooooooooooooooooooo....X ",
3050 " ....ooooooooooooooooooooooooooo....X ",
3051 " ....ooooooooooooooooooooooooooo....XX ",
3052 " ....ooooooooooooooooooooooooooo....XX ",
3053 " ....ooooooooooooooooooooooooooo....XX ",
3054 " ...ooooooooooooooooooooooooooo...XXX ",
3055 " ...ooooooooooooooooooooooooooo...XXX ",
3056 " .................................XX ",
3057 " .................................XX ",
3058 " ...............................XXX ",
3059 " ...............................XXX ",
3060 " .............................XXX ",
3061 " ...........................XXXX ",
3062 " ...........................XXX ",
3063 " .........................XXX ",
3064 " .......................XXXX ",
3065 " X...................XXXXX ",
3066 " X.................XXXXX ",
3067 " X.............XXXXX ",
3068 " XXXX.....XXXXXXXX ",
3079 /* Copyright (c) Julian Smart */
3080 static const char *info_xpm
[] = {
3081 /* columns rows colors chars-per-pixel */
3105 " .XXXOXXXXXXXoo. ",
3106 " .XOOXXX+XXXXXo. ",
3107 " .XOOOXX+++XXXXoo. ",
3108 " .XOOXXX+++XXXXXo. ",
3109 " .XOOOXXX+++XXXXXXo. ",
3110 " .XOOXXXX+++XXXXXXo. ",
3111 " .XXXXXXX+++XXXXXXX. ",
3112 " .XXXXXXX+++XXXXXXo. ",
3113 " .XXXXXXX+++XXXXXoo. ",
3114 " .XXXXXX+++XXXXXo. ",
3115 " .XXXXXXX+XXXXXXo. ",
3116 " .XXXXXXXXXXXXo. ",
3117 " .XXXXX+++XXXoo. ",
3143 /* Copyright (c) Julian Smart */
3144 static const char *warning_xpm
[] = {
3145 /* columns rows colors chars-per-pixel */
3175 " ..XXXXO@#XXX... ",
3176 " ...XXXXO@#XXXX.. ",
3177 " ..XXXXXO@#XXXX... ",
3178 " ...XXXXXo@OXXXXX.. ",
3179 " ...XXXXXXo@OXXXXXX.. ",
3180 " ..XXXXXXX$@OXXXXXX... ",
3181 " ...XXXXXXXX@XXXXXXXX.. ",
3182 " ...XXXXXXXXXXXXXXXXXX... ",
3183 " ..XXXXXXXXXXOXXXXXXXXX.. ",
3184 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
3185 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
3186 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
3187 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
3188 " .............................. ",
3189 " .............................. ",
3207 /* Copyright (c) Julian Smart */
3208 static const char *question_xpm
[] = {
3209 /* columns rows colors chars-per-pixel */
3239 " ..XXXXoooooXXXO+ ",
3240 " ..XXooooooooooooX@.. ",
3241 " ..XoooooooooooooooXX#. ",
3242 " $%XoooooooooooooooooXX#. ",
3243 " &.XoooooooXXXXXXooooooXX.. ",
3244 " .XooooooXX.$...$XXoooooX*. ",
3245 " $.XoooooX%.$ .*oooooo=.. ",
3246 " .XooooooX.. -.XoooooX.. ",
3247 " .XoooooX..+ .XoooooX;. ",
3248 " ...XXXX..: .XoooooX;. ",
3249 " ........ >.XoooooX;. ",
3283 wxBitmap
wxGTKArtProvider::CreateBitmap(const wxArtID
& id
,
3284 const wxArtClient
& WXUNUSED(client
),
3285 const wxSize
& WXUNUSED(size
))
3287 if ( id
== wxART_INFORMATION
)
3288 return wxBitmap(info_xpm
);
3289 if ( id
== wxART_ERROR
)
3290 return wxBitmap(error_xpm
);
3291 if ( id
== wxART_WARNING
)
3292 return wxBitmap(warning_xpm
);
3293 if ( id
== wxART_QUESTION
)
3294 return wxBitmap(question_xpm
);
3295 return wxNullBitmap
;
3299 // ============================================================================
3301 // ============================================================================
3303 // ----------------------------------------------------------------------------
3304 // wxGTKInputHandler
3305 // ----------------------------------------------------------------------------
3307 bool wxGTKInputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
3308 const wxKeyEvent
& WXUNUSED(event
),
3309 bool WXUNUSED(pressed
))
3314 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
3315 const wxMouseEvent
& event
)
3317 // clicking on the control gives it focus
3318 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
3320 control
->GetInputWindow()->SetFocus();
3328 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3329 const wxMouseEvent
& event
)
3331 if ( event
.Entering() )
3333 control
->GetInputWindow()->SetCurrent(true);
3335 else if ( event
.Leaving() )
3337 control
->GetInputWindow()->SetCurrent(false);
3349 // ----------------------------------------------------------------------------
3350 // wxGTKCheckboxInputHandler
3351 // ----------------------------------------------------------------------------
3353 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3354 const wxKeyEvent
& event
,
3359 int keycode
= event
.GetKeyCode();
3360 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
3362 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
3371 #endif // wxUSE_CHECKBOX
3375 // ----------------------------------------------------------------------------
3376 // wxGTKTextCtrlInputHandler
3377 // ----------------------------------------------------------------------------
3379 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
3380 const wxKeyEvent
& event
,
3383 // handle only GTK-specific text bindings here, the others are handled in
3387 wxControlAction action
;
3388 int keycode
= event
.GetKeyCode();
3389 if ( event
.ControlDown() )
3394 action
= wxACTION_TEXT_HOME
;
3398 action
= wxACTION_TEXT_LEFT
;
3402 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
3406 action
= wxACTION_TEXT_END
;
3410 action
= wxACTION_TEXT_RIGHT
;
3414 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
3418 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
3422 action
= wxACTION_TEXT_DOWN
;
3426 action
= wxACTION_TEXT_UP
;
3430 //delete the entire line
3431 control
->PerformAction(wxACTION_TEXT_HOME
);
3432 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
3436 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
3440 else if ( event
.AltDown() )
3445 action
= wxACTION_TEXT_WORD_LEFT
;
3449 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
3453 action
= wxACTION_TEXT_WORD_RIGHT
;
3458 if ( action
!= wxACTION_NONE
)
3460 control
->PerformAction(action
);
3466 return wxStdInputHandler::HandleKey(control
, event
, pressed
);
3469 #endif // wxUSE_TEXTCTRL