1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: 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"
50 #include "wx/notebook.h"
51 #include "wx/spinbutt.h"
52 #include "wx/toplevel.h"
53 #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/inphand.h"
61 #include "wx/univ/colschem.h"
62 #include "wx/univ/theme.h"
64 class WXDLLEXPORT wxGTKMenuGeometryInfo
;
66 // ----------------------------------------------------------------------------
67 // constants (to be removed, for testing only)
68 // ----------------------------------------------------------------------------
70 static const size_t BORDER_THICKNESS
= 1;
72 // ----------------------------------------------------------------------------
73 // wxGTKRenderer: draw the GUI elements in GTK style
74 // ----------------------------------------------------------------------------
76 class wxGTKRenderer
: public wxRenderer
79 wxGTKRenderer(const wxColourScheme
*scheme
);
81 // implement the base class pure virtuals
82 virtual void DrawBackground(wxDC
& dc
,
86 wxWindow
*window
= NULL
);
87 virtual void DrawLabel(wxDC
& dc
,
88 const wxString
& label
,
91 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
93 wxRect
*rectBounds
= NULL
);
94 virtual void DrawButtonLabel(wxDC
& dc
,
95 const wxString
& label
,
96 const wxBitmap
& image
,
99 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
101 wxRect
*rectBounds
= NULL
);
102 virtual void DrawBorder(wxDC
& dc
,
106 wxRect
*rectIn
= (wxRect
*)NULL
);
107 virtual void DrawHorizontalLine(wxDC
& dc
,
108 wxCoord y
, wxCoord x1
, wxCoord x2
);
109 virtual void DrawVerticalLine(wxDC
& dc
,
110 wxCoord x
, wxCoord y1
, wxCoord y2
);
111 virtual void DrawFrame(wxDC
& dc
,
112 const wxString
& label
,
115 int alignment
= wxALIGN_LEFT
,
116 int indexAccel
= -1);
117 virtual void DrawTextBorder(wxDC
& dc
,
121 wxRect
*rectIn
= (wxRect
*)NULL
);
122 virtual void DrawButtonBorder(wxDC
& dc
,
125 wxRect
*rectIn
= (wxRect
*)NULL
);
126 virtual void DrawArrow(wxDC
& dc
,
130 virtual void DrawScrollbarArrow(wxDC
& dc
,
134 virtual void DrawScrollbarThumb(wxDC
& dc
,
135 wxOrientation orient
,
138 virtual void DrawScrollbarShaft(wxDC
& dc
,
139 wxOrientation orient
,
142 virtual void DrawScrollCorner(wxDC
& dc
,
144 virtual void DrawItem(wxDC
& dc
,
145 const wxString
& label
,
148 virtual void DrawCheckItem(wxDC
& dc
,
149 const wxString
& label
,
150 const wxBitmap
& bitmap
,
153 virtual void DrawCheckButton(wxDC
& dc
,
154 const wxString
& label
,
155 const wxBitmap
& bitmap
,
158 wxAlignment align
= wxALIGN_LEFT
,
159 int indexAccel
= -1);
161 virtual void DrawRadioButton(wxDC
& dc
,
162 const wxString
& label
,
163 const wxBitmap
& bitmap
,
166 wxAlignment align
= wxALIGN_LEFT
,
167 int indexAccel
= -1);
169 virtual void DrawToolBarButton(wxDC
& dc
,
170 const wxString
& label
,
171 const wxBitmap
& bitmap
,
176 virtual void DrawTextLine(wxDC
& dc
,
177 const wxString
& text
,
182 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
183 virtual void DrawTab(wxDC
& dc
,
186 const wxString
& label
,
187 const wxBitmap
& bitmap
= wxNullBitmap
,
189 int indexAccel
= -1);
191 virtual void DrawSliderShaft(wxDC
& dc
,
194 wxOrientation orient
,
197 wxRect
*rectShaft
= NULL
);
198 virtual void DrawSliderThumb(wxDC
& dc
,
200 wxOrientation orient
,
203 virtual void DrawSliderTicks(wxDC
& WXUNUSED(dc
),
204 const wxRect
& WXUNUSED(rect
),
205 int WXUNUSED(lenThumb
),
206 wxOrientation
WXUNUSED(orient
),
209 int WXUNUSED(step
) = 1,
210 int WXUNUSED(flags
) = 0,
211 long WXUNUSED(style
) = 0)
213 // we don't have the ticks in GTK version
216 virtual void DrawMenuBarItem(wxDC
& dc
,
218 const wxString
& label
,
220 int indexAccel
= -1);
221 virtual void DrawMenuItem(wxDC
& dc
,
223 const wxMenuGeometryInfo
& geometryInfo
,
224 const wxString
& label
,
225 const wxString
& accel
,
226 const wxBitmap
& bitmap
= wxNullBitmap
,
228 int indexAccel
= -1);
229 virtual void DrawMenuSeparator(wxDC
& dc
,
231 const wxMenuGeometryInfo
& geomInfo
);
233 virtual void DrawStatusField(wxDC
& dc
,
235 const wxString
& label
,
236 int flags
= 0, int style
= 0);
238 virtual void DrawFrameTitleBar(wxDC
& dc
,
240 const wxString
& title
,
243 int specialButton
= 0,
244 int specialButtonFlag
= 0);
245 virtual void DrawFrameBorder(wxDC
& dc
,
248 virtual void DrawFrameBackground(wxDC
& dc
,
251 virtual void DrawFrameTitle(wxDC
& dc
,
253 const wxString
& title
,
255 virtual void DrawFrameIcon(wxDC
& dc
,
259 virtual void DrawFrameButton(wxDC
& dc
,
260 wxCoord x
, wxCoord y
,
265 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
266 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
267 virtual wxSize
GetFrameMinSize(int flags
) const;
268 virtual wxSize
GetFrameIconSize() const;
269 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
271 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
273 wxBitmap
*bmpPressed
,
274 wxBitmap
*bmpDisabled
);
276 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
277 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
278 virtual bool AreScrollbarsInsideBorder() const;
280 // geometry and hit testing
281 virtual wxSize
GetScrollbarArrowSize() const
282 { return m_sizeScrollbarArrow
; }
283 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
284 wxScrollBar::Element elem
,
285 int thumbPos
= -1) const;
286 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
287 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
288 const wxPoint
& pt
) const;
289 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
291 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
292 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
293 { return fontHeight
+ 2; }
294 virtual wxSize
GetCheckBitmapSize() const
295 { return wxSize(10, 10); }
296 virtual wxSize
GetRadioBitmapSize() const
297 { return wxSize(11, 11); }
298 virtual wxCoord
GetCheckItemMargin() const
301 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
302 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
303 virtual wxSize
GetToolBarMargin() const
304 { return wxSize(6, 6); }
306 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
307 const wxRect
& rect
) const;
308 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
310 wxCoord
*extraSpaceBeyond
) const;
312 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
313 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
315 virtual wxCoord
GetSliderDim() const { return 15; }
316 virtual wxCoord
GetSliderTickLen() const { return 0; }
317 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
319 wxOrientation orient
,
320 long style
= 0) const;
321 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
323 wxOrientation orient
) const;
324 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
326 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
327 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
328 const wxMenu
& menu
) const;
330 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
332 // helpers for "wxBitmap wxColourScheme::Get()"
333 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
334 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
335 void DrawUndeterminedBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
338 // DrawBackground() helpers
340 // get the colour to use for background
341 wxColour
GetBackgroundColour(int flags
) const
343 if ( flags
& wxCONTROL_PRESSED
)
344 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
345 else if ( flags
& wxCONTROL_CURRENT
)
346 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
348 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
351 // draw the background with any colour, not only the default one(s)
352 void DoDrawBackground(wxDC
& dc
,
355 wxWindow
*window
= NULL
);
357 // DrawBorder() helpers: all of them shift and clip the DC after drawing
360 // just draw a rectangle with the given pen
361 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
363 // draw the lower left part of rectangle
364 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
366 // draw the rectange using the first brush for the left and top sides and
367 // the second one for the bottom and right ones
368 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
369 const wxPen
& pen1
, const wxPen
& pen2
);
371 // as DrawShadedRect() but the pixels in the bottom left and upper right
372 // border are drawn with the pen1, not pen2
373 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
374 const wxPen
& pen1
, const wxPen
& pen2
);
376 // used for drawing opened rectangles - draws only one side of it at once
377 // (and doesn't adjust the rect)
378 void DrawAntiShadedRectSide(wxDC
& dc
,
384 // draw an opened rect for the arrow in given direction
385 void DrawArrowBorder(wxDC
& dc
,
389 // draw two sides of the rectangle
390 void DrawThumbBorder(wxDC
& dc
,
392 wxOrientation orient
);
394 // draw the normal 3D border
395 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
397 // just as DrawRaisedBorder() except that the bottom left and up right
398 // pixels of the interior rect are drawn in another colour (i.e. the inner
399 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
400 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
402 // returns the size of the arrow for the scrollbar (depends on
404 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
407 if ( scrollbar
->IsVertical() )
409 size
= m_sizeScrollbarArrow
;
413 size
.x
= m_sizeScrollbarArrow
.y
;
414 size
.y
= m_sizeScrollbarArrow
.x
;
420 // get the line wrap indicator bitmap
421 wxBitmap
GetLineWrapBitmap() const;
423 // DrawCheckBitmap and DrawRadioBitmap helpers
425 // draw the check bitmaps once and cache them for later use
426 wxBitmap
GetCheckBitmap(int flags
);
428 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
430 void DrawUpZag(wxDC
& dc
,
431 wxCoord x1
, wxCoord x2
,
432 wxCoord y1
, wxCoord y2
);
433 void DrawDownZag(wxDC
& dc
,
434 wxCoord x1
, wxCoord x2
,
435 wxCoord y1
, wxCoord y2
);
437 // draw the radio button bitmap for the given state
438 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
440 // draw check/radio - the bitmap must be a valid one by now
441 void DoDrawCheckOrRadioBitmap(wxDC
& dc
,
442 const wxString
& label
,
443 const wxBitmap
& bitmap
,
444 const wxRect
& rectTotal
,
449 // common part of DrawMenuItem() and DrawMenuBarItem()
450 void DoDrawMenuItem(wxDC
& dc
,
452 const wxString
& label
,
455 const wxString
& accel
= wxEmptyString
,
456 const wxBitmap
& bitmap
= wxNullBitmap
,
457 const wxGTKMenuGeometryInfo
*geometryInfo
= NULL
);
459 // initialize the combo bitmaps
460 void InitComboBitmaps();
463 const wxColourScheme
*m_scheme
;
466 wxSize m_sizeScrollbarArrow
;
475 // the checkbox bitmaps: first row is for the normal, second for the
476 // pressed state and the columns are for checked, unchecked and
477 // undeterminated respectively
478 wxBitmap m_bitmapsCheckbox
[2][3];
480 // the line wrap bitmap (drawn at the end of wrapped lines)
481 wxBitmap m_bmpLineWrap
;
483 // the combobox bitmaps
493 wxBitmap m_bitmapsCombo
[ComboState_Max
];
496 // ----------------------------------------------------------------------------
497 // wxGTKInputHandler and derived classes: process the keyboard and mouse
498 // messages according to GTK standards
499 // ----------------------------------------------------------------------------
501 class wxGTKInputHandler
: public wxInputHandler
504 wxGTKInputHandler(wxGTKRenderer
*renderer
);
506 virtual bool HandleKey(wxInputConsumer
*control
,
507 const wxKeyEvent
& event
,
509 virtual bool HandleMouse(wxInputConsumer
*control
,
510 const wxMouseEvent
& event
);
511 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
514 wxGTKRenderer
*m_renderer
;
517 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
520 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
521 : wxStdScrollBarInputHandler(renderer
, handler
) { }
524 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
526 // only arrows and the thumb can be highlighted
527 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
530 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
533 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
535 // only arrows can be pressed
539 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
542 virtual bool IsAllowedButton(int WXUNUSED(button
)) { return true; }
546 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
547 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
551 class wxGTKCheckboxInputHandler
: public wxStdCheckboxInputHandler
554 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
555 : wxStdCheckboxInputHandler(handler
) { }
557 virtual bool HandleKey(wxInputConsumer
*control
,
558 const wxKeyEvent
& event
,
562 class wxGTKTextCtrlInputHandler
: public wxStdTextCtrlInputHandler
565 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
566 : wxStdTextCtrlInputHandler(handler
) { }
568 virtual bool HandleKey(wxInputConsumer
*control
,
569 const wxKeyEvent
& event
,
573 // ----------------------------------------------------------------------------
574 // wxGTKColourScheme: uses the standard GTK colours
575 // ----------------------------------------------------------------------------
577 class wxGTKColourScheme
: public wxColourScheme
580 virtual wxColour
Get(StdColour col
) const;
581 virtual wxColour
GetBackground(wxWindow
*win
) const;
584 // ----------------------------------------------------------------------------
586 // ----------------------------------------------------------------------------
588 class wxGTKArtProvider
: public wxArtProvider
591 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
592 const wxArtClient
& client
,
596 // ----------------------------------------------------------------------------
598 // ----------------------------------------------------------------------------
600 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
602 class wxGTKTheme
: public wxTheme
606 virtual ~wxGTKTheme();
608 virtual wxRenderer
*GetRenderer();
609 virtual wxArtProvider
*GetArtProvider();
610 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
611 virtual wxColourScheme
*GetColourScheme();
614 // get the default input handler
615 wxInputHandler
*GetDefaultInputHandler();
617 wxGTKRenderer
*m_renderer
;
619 wxGTKArtProvider
*m_artProvider
;
621 // the names of the already created handlers and the handlers themselves
622 // (these arrays are synchronized)
623 wxSortedArrayString m_handlerNames
;
624 wxArrayHandlers m_handlers
;
626 wxGTKInputHandler
*m_handlerDefault
;
628 wxGTKColourScheme
*m_scheme
;
630 WX_DECLARE_THEME(gtk
)
633 // ============================================================================
635 // ============================================================================
637 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
639 // ----------------------------------------------------------------------------
641 // ----------------------------------------------------------------------------
643 wxGTKTheme::wxGTKTheme()
647 m_handlerDefault
= NULL
;
648 m_artProvider
= NULL
;
651 wxGTKTheme::~wxGTKTheme()
653 size_t count
= m_handlers
.GetCount();
654 for ( size_t n
= 0; n
< count
; n
++ )
656 if ( m_handlers
[n
] != m_handlerDefault
)
657 delete m_handlers
[n
];
660 delete m_handlerDefault
;
663 wxArtProvider::RemoveProvider(m_artProvider
);
666 wxRenderer
*wxGTKTheme::GetRenderer()
670 m_renderer
= new wxGTKRenderer(GetColourScheme());
676 wxArtProvider
*wxGTKTheme::GetArtProvider()
678 if ( !m_artProvider
)
680 m_artProvider
= new wxGTKArtProvider
;
683 return m_artProvider
;
686 wxColourScheme
*wxGTKTheme::GetColourScheme()
690 m_scheme
= new wxGTKColourScheme
;
695 wxInputHandler
*wxGTKTheme::GetDefaultInputHandler()
697 if ( !m_handlerDefault
)
699 m_handlerDefault
= new wxGTKInputHandler(m_renderer
);
702 return m_handlerDefault
;
705 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
)
707 wxInputHandler
*handler
;
708 int n
= m_handlerNames
.Index(control
);
709 if ( n
== wxNOT_FOUND
)
711 // create a new handler
712 if ( control
== wxINP_HANDLER_SCROLLBAR
)
713 handler
= new wxGTKScrollBarInputHandler(m_renderer
,
714 GetDefaultInputHandler());
716 else if ( control
== wxINP_HANDLER_BUTTON
)
717 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
718 #endif // wxUSE_CHECKBOX
720 else if ( control
== wxINP_HANDLER_CHECKBOX
)
721 handler
= new wxGTKCheckboxInputHandler(GetDefaultInputHandler());
722 #endif // wxUSE_CHECKBOX
724 else if ( control
== wxINP_HANDLER_COMBOBOX
)
725 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
726 #endif // wxUSE_COMBOBOX
728 else if ( control
== wxINP_HANDLER_LISTBOX
)
729 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
730 #endif // wxUSE_LISTBOX
731 #if wxUSE_CHECKLISTBOX
732 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
733 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
734 #endif // wxUSE_CHECKLISTBOX
736 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
737 handler
= new wxGTKTextCtrlInputHandler(GetDefaultInputHandler());
738 #endif // wxUSE_TEXTCTRL
740 else if ( control
== wxINP_HANDLER_SLIDER
)
741 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
742 #endif // wxUSE_SLIDER
744 else if ( control
== wxINP_HANDLER_SPINBTN
)
745 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
746 #endif // wxUSE_SPINBTN
748 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
749 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
750 #endif // wxUSE_NOTEBOOK
752 else if ( control
== wxINP_HANDLER_TOOLBAR
)
753 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
754 #endif // wxUSE_TOOLBAR
755 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
756 handler
= new wxStdFrameInputHandler(GetDefaultInputHandler());
758 handler
= GetDefaultInputHandler();
760 n
= m_handlerNames
.Add(control
);
761 m_handlers
.Insert(handler
, n
);
763 else // we already have it
765 handler
= m_handlers
[n
];
771 // ============================================================================
773 // ============================================================================
775 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
778 if ( win
->UseBgCol() )
780 // use the user specified colour
781 col
= win
->GetBackgroundColour();
784 if ( !win
->ShouldInheritColours() )
786 // doesn't depend on the state
794 int flags
= win
->GetStateFlags();
796 // the colour set by the user should be used for the normal state
797 // and for the states for which we don't have any specific colours
798 if ( !col
.Ok() || (flags
!= 0) )
800 if ( wxDynamicCast(win
, wxScrollBar
) )
801 col
= Get(SCROLLBAR
);
802 else if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
803 col
= Get(CONTROL_CURRENT
);
804 else if ( flags
& wxCONTROL_PRESSED
)
805 col
= Get(CONTROL_PRESSED
);
814 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
818 case WINDOW
: return *wxWHITE
;
820 case SHADOW_DARK
: return *wxBLACK
;
821 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
822 case SHADOW_IN
: return wxColour(0xd6d6d6);
823 case SHADOW_OUT
: return wxColour(0x969696);
825 case CONTROL
: return wxColour(0xd6d6d6);
826 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
827 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
829 case CONTROL_TEXT
: return *wxBLACK
;
830 case CONTROL_TEXT_DISABLED
:
831 return wxColour(0x757575);
832 case CONTROL_TEXT_DISABLED_SHADOW
:
836 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
838 case HIGHLIGHT
: return wxColour(0x9c0000);
839 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
841 case GAUGE
: return Get(CONTROL_CURRENT
);
845 wxFAIL_MSG(_T("invalid standard colour"));
850 // ============================================================================
852 // ============================================================================
854 // ----------------------------------------------------------------------------
856 // ----------------------------------------------------------------------------
858 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
862 m_sizeScrollbarArrow
= wxSize(15, 14);
865 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
866 m_penDarkGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_OUT
), 0, wxSOLID
);
867 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
), 0, wxSOLID
);
868 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
869 m_penHighlight
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
), 0, wxSOLID
);
872 // ----------------------------------------------------------------------------
874 // ----------------------------------------------------------------------------
876 void wxGTKRenderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
880 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
881 dc
.DrawRectangle(*rect
);
887 void wxGTKRenderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
889 // draw the bottom and right sides
891 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
892 rect
->GetRight() + 1, rect
->GetBottom());
893 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
894 rect
->GetRight(), rect
->GetBottom());
901 void wxGTKRenderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
902 const wxPen
& pen1
, const wxPen
& pen2
)
904 // draw the rectangle
906 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
907 rect
->GetLeft(), rect
->GetBottom());
908 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
909 rect
->GetRight(), rect
->GetTop());
911 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
912 rect
->GetRight(), rect
->GetBottom());
913 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
914 rect
->GetRight() + 1, rect
->GetBottom());
920 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
926 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
931 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
932 rect
.GetLeft(), rect
.GetBottom() + 1);
936 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
937 rect
.GetRight() + 1, rect
.GetTop());
941 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
942 rect
.GetRight(), rect
.GetBottom() + 1);
946 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
947 rect
.GetRight() + 1, rect
.GetBottom());
951 wxFAIL_MSG(_T("unknown rectangle side"));
955 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
956 const wxPen
& pen1
, const wxPen
& pen2
)
958 // draw the rectangle
960 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
961 rect
->GetLeft(), rect
->GetBottom() + 1);
962 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
963 rect
->GetRight() + 1, rect
->GetTop());
965 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
966 rect
->GetRight(), rect
->GetBottom());
967 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
968 rect
->GetRight() + 1, rect
->GetBottom());
974 void wxGTKRenderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
976 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
977 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
980 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
982 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
983 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
986 void wxGTKRenderer::DrawBorder(wxDC
& dc
,
988 const wxRect
& rectTotal
,
994 wxRect rect
= rectTotal
;
998 case wxBORDER_SUNKEN
:
999 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1001 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1002 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1006 case wxBORDER_STATIC
:
1007 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1009 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1013 case wxBORDER_RAISED
:
1014 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1016 DrawRaisedBorder(dc
, &rect
);
1020 case wxBORDER_DOUBLE
:
1021 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1023 DrawShadedRect(dc
, &rect
, m_penLightGrey
, m_penBlack
);
1024 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penDarkGrey
);
1025 DrawRect(dc
, &rect
, m_penLightGrey
);
1029 case wxBORDER_SIMPLE
:
1030 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1032 DrawRect(dc
, &rect
, m_penBlack
);
1037 wxFAIL_MSG(_T("unknown border type"));
1040 case wxBORDER_DEFAULT
:
1049 wxRect
wxGTKRenderer::GetBorderDimensions(wxBorder border
) const
1054 case wxBORDER_RAISED
:
1055 case wxBORDER_SUNKEN
:
1056 width
= 2*BORDER_THICKNESS
;
1059 case wxBORDER_SIMPLE
:
1060 case wxBORDER_STATIC
:
1061 width
= BORDER_THICKNESS
;
1064 case wxBORDER_DOUBLE
:
1065 width
= 3*BORDER_THICKNESS
;
1069 wxFAIL_MSG(_T("unknown border type"));
1072 case wxBORDER_DEFAULT
:
1082 rect
.height
= width
;
1087 bool wxGTKRenderer::AreScrollbarsInsideBorder() const
1089 // no, the scrollbars are outside the border in GTK+
1093 // ----------------------------------------------------------------------------
1095 // ----------------------------------------------------------------------------
1097 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
1099 const wxRect
& rectOrig
,
1103 wxRect rect
= rectOrig
;
1105 if ( border
!= wxBORDER_NONE
)
1107 if ( flags
& wxCONTROL_FOCUSED
)
1109 DrawRect(dc
, &rect
, m_penBlack
);
1110 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1114 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1115 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penHighlight
);
1123 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
1124 const wxRect
& rectTotal
,
1128 wxRect rect
= rectTotal
;
1130 if ( flags
& wxCONTROL_PRESSED
)
1132 // button pressed: draw a black border around it and an inward shade
1133 DrawRect(dc
, &rect
, m_penBlack
);
1135 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1137 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1138 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penDarkGrey
);
1143 // button not pressed
1145 if ( flags
& wxCONTROL_ISDEFAULT
)
1150 if ( flags
& wxCONTROL_FOCUSED
)
1152 // button is currently default: add an extra border around it
1153 DrawRect(dc
, &rect
, m_penBlack
);
1156 // now draw a normal button
1157 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1159 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1160 DrawAntiShadedRect(dc
, &rect
,
1161 wxPen(GetBackgroundColour(flags
), 0, wxSOLID
),
1172 // ----------------------------------------------------------------------------
1174 // ----------------------------------------------------------------------------
1176 void wxGTKRenderer::DrawHorizontalLine(wxDC
& dc
,
1177 wxCoord y
, wxCoord x1
, wxCoord x2
)
1179 dc
.SetPen(m_penDarkGrey
);
1180 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1181 dc
.SetPen(m_penHighlight
);
1183 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1186 void wxGTKRenderer::DrawVerticalLine(wxDC
& dc
,
1187 wxCoord x
, wxCoord y1
, wxCoord y2
)
1189 dc
.SetPen(m_penDarkGrey
);
1190 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1191 dc
.SetPen(m_penHighlight
);
1193 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1196 void wxGTKRenderer::DrawFrame(wxDC
& dc
,
1197 const wxString
& label
,
1203 wxCoord height
= 0; // of the label
1204 wxRect rectFrame
= rect
;
1205 if ( !label
.empty() )
1207 // the text should touch the top border of the rect, so the frame
1208 // itself should be lower
1209 dc
.GetTextExtent(label
, NULL
, &height
);
1210 rectFrame
.y
+= height
/ 2;
1211 rectFrame
.height
-= height
/ 2;
1213 // TODO: the +4 should be customizable
1216 rectText
.x
= rectFrame
.x
+ 4;
1217 rectText
.y
= rect
.y
;
1218 rectText
.width
= rectFrame
.width
- 8;
1219 rectText
.height
= height
;
1222 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1224 rectLabel
.width
+= 2;
1226 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1228 // GTK+ does it like this
1229 dc
.SetPen(m_penHighlight
);
1230 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
1231 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
1235 // just draw the complete frame
1236 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1237 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1241 // ----------------------------------------------------------------------------
1243 // ----------------------------------------------------------------------------
1245 void wxGTKRenderer::DrawLabel(wxDC
& dc
,
1246 const wxString
& label
,
1253 DrawButtonLabel(dc
, label
, wxNullBitmap
, rect
, flags
,
1254 alignment
, indexAccel
, rectBounds
);
1257 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
1258 const wxString
& label
,
1259 const wxBitmap
& image
,
1266 if ( flags
& wxCONTROL_DISABLED
)
1268 // make the text grey and draw a shade for it
1269 dc
.SetTextForeground(*wxWHITE
); // FIXME hardcoded colour
1270 wxRect rectShadow
= rect
;
1273 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1274 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT_DISABLED
));
1278 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT
));
1281 dc
.DrawLabel(label
, image
, rect
, alignment
, indexAccel
, rectBounds
);
1284 void wxGTKRenderer::DrawItem(wxDC
& dc
,
1285 const wxString
& label
,
1289 wxLogTrace(_T("listbox"), _T("drawing item '%s' at (%d, %d)-(%d, %d)"),
1292 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1295 if ( flags
& wxCONTROL_SELECTED
)
1297 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
), wxSOLID
));
1298 dc
.SetPen(*wxTRANSPARENT_PEN
);
1299 dc
.DrawRectangle(rect
);
1301 colFg
= dc
.GetTextForeground();
1302 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
1305 if ( flags
& wxCONTROL_FOCUSED
)
1307 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1308 wxRect rectFocus
= rect
;
1309 DrawRect(dc
, &rectFocus
, m_penBlack
);
1312 wxRect rectText
= rect
;
1315 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
1317 if ( flags
& wxCONTROL_SELECTED
)
1319 dc
.SetBackgroundMode(wxTRANSPARENT
);
1322 // restore the text colour
1325 dc
.SetTextForeground(colFg
);
1329 void wxGTKRenderer::DrawCheckItem(wxDC
& dc
,
1330 const wxString
& label
,
1331 const wxBitmap
& bitmap
,
1335 wxRect rectBitmap
= rect
;
1337 rectBitmap
.width
= GetCheckBitmapSize().x
;
1339 // never draw the focus rect around the check indicators here
1340 DrawCheckButton(dc
, wxEmptyString
, bitmap
, rectBitmap
, flags
& ~wxCONTROL_FOCUSED
);
1342 wxRect rectLabel
= rect
;
1343 wxCoord shift
= rectBitmap
.width
+ 2*GetCheckItemMargin();
1344 rectLabel
.x
+= shift
;
1345 rectLabel
.width
-= shift
;
1346 DrawItem(dc
, label
, rectLabel
, flags
);
1349 // ----------------------------------------------------------------------------
1350 // check/radion buttons
1351 // ----------------------------------------------------------------------------
1353 void wxGTKRenderer::DrawUndeterminedBitmap(wxDC
& dc
,
1354 const wxRect
& rectTotal
,
1357 // FIXME: For sure it is not GTK look but it is better than nothing.
1358 // Show me correct look and I will immediatelly make it better (ABX)
1359 wxRect rect
= rectTotal
;
1361 wxColour col1
, col2
;
1365 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1366 col2
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1370 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1371 col2
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1374 dc
.SetPen(*wxTRANSPARENT_PEN
);
1375 dc
.SetBrush(wxBrush(col1
, wxSOLID
));
1376 dc
.DrawRectangle(rect
);
1378 dc
.SetBrush(wxBrush(col2
, wxSOLID
));
1379 dc
.DrawRectangle(rect
);
1382 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1383 const wxRect
& rectTotal
,
1386 wxRect rect
= rectTotal
;
1387 DrawAntiRaisedBorder(dc
, &rect
);
1389 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1390 dc
.SetPen(wxPen(col
, 0, wxSOLID
));
1391 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1394 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1395 //else: it is SHADOW_IN, leave as is
1397 dc
.SetPen(*wxTRANSPARENT_PEN
);
1398 dc
.SetBrush(wxBrush(col
, wxSOLID
));
1399 dc
.DrawRectangle(rect
);
1402 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1404 wxRect rect
= rectTotal
;
1405 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1406 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1408 dc
.SetPen(*wxTRANSPARENT_PEN
);
1409 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), wxSOLID
));
1410 dc
.DrawRectangle(rect
);
1413 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1419 xRight
= rect
.GetRight(),
1420 yBottom
= rect
.GetBottom();
1422 wxCoord yMid
= (y
+ yBottom
) / 2;
1424 // this looks ugly when the background colour of the control is not the
1425 // same ours - radiobox is not transparent as it should be
1427 // first fill the middle: as FloodFill() is not implemented on all
1428 // platforms, this is the only thing to do
1429 wxColour colBg
= flags
& wxCONTROL_CURRENT
1430 ? wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
)
1431 : wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1432 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
1433 dc
.SetPen(*wxTRANSPARENT_PEN
);
1434 dc
.DrawRectangle(rect
);
1437 // then draw the upper half
1438 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1439 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1440 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1443 if ( flags
& wxCONTROL_CHECKED
)
1444 dc
.SetPen(m_penBlack
);
1445 else if ( flags
& wxCONTROL_PRESSED
)
1446 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1447 else // unchecked and unpressed
1451 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1453 // and then the lower one
1454 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1455 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1456 if ( !(flags
& wxCONTROL_CHECKED
) )
1457 dc
.SetPen(m_penDarkGrey
);
1458 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1460 if ( !(flags
& wxCONTROL_CHECKED
) )
1461 drawIt
= true; // with the same pen
1462 else if ( flags
& wxCONTROL_PRESSED
)
1464 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1467 else // checked and unpressed
1471 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1474 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1480 wxCoord xMid
= (x1
+ x2
) / 2;
1481 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1482 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1485 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1491 wxCoord xMid
= (x1
+ x2
) / 2;
1492 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1493 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1496 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1498 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1500 // init the bitmaps once only
1502 wxSize size
= GetCheckBitmapSize();
1503 rect
.width
= size
.x
;
1504 rect
.height
= size
.y
;
1505 for ( int i
= 0; i
< 2; i
++ )
1507 for ( int j
= 0; j
< 3; j
++ )
1508 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1514 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1515 DrawCheckBitmap(dc
, rect
);
1518 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1519 DrawUncheckBitmap(dc
, rect
, false);
1521 // normal undeterminated
1522 dc
.SelectObject(m_bitmapsCheckbox
[0][2]);
1523 DrawUndeterminedBitmap(dc
, rect
, false);
1526 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1528 // pressed unchecked
1529 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1530 DrawUncheckBitmap(dc
, rect
, true);
1532 // pressed undeterminated
1533 dc
.SelectObject(m_bitmapsCheckbox
[1][2]);
1534 DrawUndeterminedBitmap(dc
, rect
, true);
1537 int row
= flags
& wxCONTROL_PRESSED
1540 int col
= flags
& wxCONTROL_CHECKED
1542 : ( flags
& wxCONTROL_UNDETERMINED
1546 return m_bitmapsCheckbox
[row
][col
];
1549 wxBitmap
wxGTKRenderer::GetLineWrapBitmap() const
1551 if ( !m_bmpLineWrap
.Ok() )
1553 // the line wrap bitmap as used by GTK+
1554 #define line_wrap_width 6
1555 #define line_wrap_height 9
1556 static const char line_wrap_bits
[] =
1558 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1561 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1562 if ( !bmpLineWrap
.Ok() )
1564 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1568 wxConstCast(this, wxGTKRenderer
)->m_bmpLineWrap
= bmpLineWrap
;
1572 return m_bmpLineWrap
;
1575 void wxGTKRenderer::DrawCheckButton(wxDC
& dc
,
1576 const wxString
& label
,
1577 const wxBitmap
& bitmapOrig
,
1578 const wxRect
& rectTotal
,
1584 if ( bitmapOrig
.Ok() )
1586 bitmap
= bitmapOrig
;
1590 bitmap
= GetCheckBitmap(flags
);
1593 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1594 flags
, align
, indexAccel
);
1597 void wxGTKRenderer::DoDrawCheckOrRadioBitmap(wxDC
& dc
,
1598 const wxString
& label
,
1599 const wxBitmap
& bitmap
,
1600 const wxRect
& rectTotal
,
1605 wxRect rect
= rectTotal
;
1607 if ( flags
& wxCONTROL_FOCUSED
)
1609 // draw the focus border around everything
1610 DrawRect(dc
, &rect
, m_penBlack
);
1614 // the border does not offset the string under GTK
1618 // calculate the position of the bitmap and of the label
1620 yBmp
= rect
.y
+ (rect
.height
- bitmap
.GetHeight()) / 2;
1623 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
1624 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
1626 if ( align
== wxALIGN_RIGHT
)
1628 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
1629 rectLabel
.x
= rect
.x
+ 2;
1630 rectLabel
.SetRight(xBmp
);
1632 else // normal (checkbox to the left of the text) case
1635 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 4;
1636 rectLabel
.SetRight(rect
.GetRight());
1639 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
1641 DrawLabel(dc
, label
, rectLabel
, flags
,
1642 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1645 void wxGTKRenderer::DrawRadioButton(wxDC
& dc
,
1646 const wxString
& label
,
1647 const wxBitmap
& bitmapOrig
,
1648 const wxRect
& rectTotal
,
1654 if ( bitmapOrig
.Ok() )
1656 bitmap
= bitmapOrig
;
1661 wxSize size
= GetRadioBitmapSize();
1662 rect
.width
= size
.x
;
1663 rect
.height
= size
.y
;
1664 bitmap
.Create(rect
.width
, rect
.height
);
1666 dc
.SelectObject(bitmap
);
1667 dc
.SetBackground(*wxLIGHT_GREY_BRUSH
);
1669 DrawRadioBitmap(dc
, rect
, flags
);
1671 // must unselect the bitmap before setting a mask for it because of the
1673 dc
.SelectObject(wxNullBitmap
);
1674 bitmap
.SetMask(new wxMask(bitmap
, *wxLIGHT_GREY
));
1677 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1678 flags
, align
, indexAccel
);
1681 void wxGTKRenderer::DrawToolBarButton(wxDC
& dc
,
1682 const wxString
& label
,
1683 const wxBitmap
& bitmap
,
1684 const wxRect
& rectOrig
,
1686 long WXUNUSED(style
))
1688 // we don't draw the separators at all
1689 if ( !label
.empty() || bitmap
.Ok() )
1691 wxRect rect
= rectOrig
;
1692 rect
.Deflate(BORDER_THICKNESS
);
1694 if ( flags
& wxCONTROL_PRESSED
)
1696 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
, &rect
);
1698 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), rect
);
1700 else if ( flags
& wxCONTROL_CURRENT
)
1702 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rect
);
1704 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rect
);
1707 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1711 // ----------------------------------------------------------------------------
1713 // ----------------------------------------------------------------------------
1715 wxRect
wxGTKRenderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
1716 const wxRect
& rect
) const
1718 wxRect rectTotal
= rect
;
1719 rectTotal
.Inflate(2*BORDER_THICKNESS
);
1723 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1725 wxCoord
*extraSpaceBeyond
) const
1727 wxRect rectText
= rect
;
1728 rectText
.Deflate(2*BORDER_THICKNESS
);
1730 if ( text
->WrapLines() )
1732 // leave enough for the line wrap bitmap indicator
1733 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1735 rectText
.width
-= widthMark
;
1737 if ( extraSpaceBeyond
)
1738 *extraSpaceBeyond
= widthMark
;
1744 void wxGTKRenderer::DrawTextLine(wxDC
& dc
,
1745 const wxString
& text
,
1751 // TODO: GTK+ draws selection even for unfocused controls, just with
1752 // different colours
1753 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
1756 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1758 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1760 // for a mono bitmap he colours it appears in depends on the current text
1761 // colours, so set them correctly
1763 if ( bmpLineWrap
.GetDepth() == 1 )
1765 colFgOld
= dc
.GetTextForeground();
1767 // FIXME: I wonder what should we do if the background is black too?
1768 dc
.SetTextForeground(*wxBLACK
);
1771 dc
.DrawBitmap(bmpLineWrap
,
1772 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1774 if ( colFgOld
.Ok() )
1776 // restore old colour
1777 dc
.SetTextForeground(colFgOld
);
1781 // ----------------------------------------------------------------------------
1783 // ----------------------------------------------------------------------------
1785 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1786 const wxRect
& rectOrig
,
1788 const wxString
& label
,
1789 const wxBitmap
& bitmap
,
1793 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1794 #define REVERSE_FOR_VERTICAL(X,Y) \
1795 SELECT_FOR_VERTICAL(X,Y) \
1797 SELECT_FOR_VERTICAL(Y,X)
1799 wxRect rect
= rectOrig
;
1801 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1803 // the current tab is drawn indented (to the top for default case) and
1804 // bigger than the other ones
1805 const wxSize indent
= GetTabIndent();
1806 if ( flags
& wxCONTROL_SELECTED
)
1808 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1809 SELECT_FOR_VERTICAL( 0, indent
.y
));
1813 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1820 rect
.height
+= indent
.y
;
1827 rect
.width
+= indent
.x
;
1832 // selected tab has different colour
1833 wxColour col
= flags
& wxCONTROL_SELECTED
1834 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1835 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1836 DoDrawBackground(dc
, col
, rect
);
1838 if ( flags
& wxCONTROL_FOCUSED
)
1840 // draw the focus rect
1841 wxRect rectBorder
= rect
;
1842 rectBorder
.Deflate(4, 3);
1843 if ( dir
== wxBOTTOM
)
1844 rectBorder
.Offset(0, -1);
1845 if ( dir
== wxRIGHT
)
1846 rectBorder
.Offset(-1, 0);
1848 DrawRect(dc
, &rectBorder
, m_penBlack
);
1851 // draw the text, image and the focus around them (if necessary)
1852 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1853 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1855 rectLabel
.Deflate(1, 1);
1858 // draw it horizontally into memory and rotate for screen
1860 wxBitmap bitmapRotated
,
1861 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1862 rectLabel
.y
+ rectLabel
.height
);
1863 dcMem
.SelectObject(bitmapMem
);
1864 dcMem
.SetBackground(dc
.GetBackground());
1865 dcMem
.SetFont(dc
.GetFont());
1866 dcMem
.SetTextForeground(dc
.GetTextForeground());
1868 bitmapRotated
= wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) );
1869 dcMem
.DrawLabel(label
, bitmapRotated
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1870 dcMem
.SelectObject(wxNullBitmap
);
1871 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1872 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
1873 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1877 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1880 // now draw the tab itself
1881 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1882 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1883 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1884 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1890 // left orientation looks like top but IsVertical makes x and y reversed
1892 // top is not vertical so use coordinates in written order
1893 dc
.SetPen(m_penHighlight
);
1894 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1895 REVERSE_FOR_VERTICAL(x
, y
));
1896 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
),
1897 REVERSE_FOR_VERTICAL(x2
, y
));
1899 dc
.SetPen(m_penBlack
);
1900 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1901 REVERSE_FOR_VERTICAL(x2
, y
));
1903 dc
.SetPen(m_penDarkGrey
);
1904 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1905 REVERSE_FOR_VERTICAL(x2
- 1, y
+ 1));
1907 if ( flags
& wxCONTROL_SELECTED
)
1909 dc
.SetPen(m_penLightGrey
);
1911 // overwrite the part of the border below this tab
1912 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1913 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1915 // and the shadow of the tab to the left of us
1916 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ 2),
1917 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1922 // right orientation looks like bottom but IsVertical makes x and y reversed
1924 // bottom is not vertical so use coordinates in written order
1925 dc
.SetPen(m_penHighlight
);
1927 // we need to continue one pixel further to overwrite the corner of
1928 // the border for the selected tab
1929 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
1930 REVERSE_FOR_VERTICAL(x
, y2
));
1932 // it doesn't work like this (TODO: implement it properly)
1934 // erase the corner of the tab to the right
1935 dc
.SetPen(m_penLightGrey
);
1936 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1937 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 2));
1938 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 1));
1941 dc
.SetPen(m_penBlack
);
1942 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
),
1943 REVERSE_FOR_VERTICAL(x2
, y2
));
1944 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
1945 REVERSE_FOR_VERTICAL(x2
, y2
));
1947 dc
.SetPen(m_penDarkGrey
);
1948 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 2, y2
- 1),
1949 REVERSE_FOR_VERTICAL(x2
- 1, y2
- 1));
1950 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
1951 REVERSE_FOR_VERTICAL(x2
- 1, y2
));
1953 if ( flags
& wxCONTROL_SELECTED
)
1955 dc
.SetPen(m_penLightGrey
);
1957 // overwrite the part of the (double!) border above this tab
1958 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
1959 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
1960 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
1961 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1963 // and the shadow of the tab to the left of us
1964 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- 1),
1965 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
1971 // ----------------------------------------------------------------------------
1973 // ----------------------------------------------------------------------------
1975 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1977 wxOrientation orient
) const
1979 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1983 wxRect rectShaft
= GetSliderShaftRect(rect
, lenThumb
, orient
);
1984 if ( orient
== wxHORIZONTAL
)
1986 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1987 size
.y
= rectShaft
.height
;
1991 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1992 size
.x
= rectShaft
.width
;
1998 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1999 int WXUNUSED(lenThumb
),
2000 wxOrientation
WXUNUSED(orient
),
2001 long WXUNUSED(style
)) const
2003 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
2006 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
2007 const wxRect
& rectOrig
,
2008 int WXUNUSED(lenThumb
),
2009 wxOrientation
WXUNUSED(orient
),
2011 long WXUNUSED(style
),
2014 wxRect rect
= rectOrig
;
2016 // draw the border first
2017 if ( flags
& wxCONTROL_FOCUSED
)
2019 DrawRect(dc
, &rect
, m_penBlack
);
2020 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
2022 else // not focused, normal
2024 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
2025 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
2028 // and the background
2029 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
2035 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
2036 const wxRect
& rectOrig
,
2037 wxOrientation orient
,
2038 int WXUNUSED(flags
),
2039 long WXUNUSED(style
))
2041 // draw the thumb border
2042 wxRect rect
= rectOrig
;
2043 DrawAntiRaisedBorder(dc
, &rect
);
2045 // draw the handle in the middle
2046 if ( orient
== wxVERTICAL
)
2048 rect
.height
= 2*BORDER_THICKNESS
;
2049 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2053 rect
.width
= 2*BORDER_THICKNESS
;
2054 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2057 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
2060 // ----------------------------------------------------------------------------
2062 // ----------------------------------------------------------------------------
2064 // wxGTKMenuGeometryInfo: the wxMenuGeometryInfo used by wxGTKRenderer
2065 class WXDLLEXPORT wxGTKMenuGeometryInfo
: public wxMenuGeometryInfo
2068 virtual wxSize
GetSize() const { return m_size
; }
2070 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2071 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2073 wxCoord
GetItemHeight() const { return m_heightItem
; }
2076 // the total size of the menu
2079 // the offset of the start of the menu item label
2082 // the offset of the start of the accel label
2085 // the height of a normal (not separator) item
2086 wxCoord m_heightItem
;
2088 friend wxMenuGeometryInfo
*
2089 wxGTKRenderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2092 // FIXME: all constants are hardcoded but shouldn't be
2093 static const wxCoord MENU_LEFT_MARGIN
= 9;
2094 static const wxCoord MENU_RIGHT_MARGIN
= 6;
2096 static const wxCoord MENU_HORZ_MARGIN
= 6;
2097 static const wxCoord MENU_VERT_MARGIN
= 3;
2099 // the margin around bitmap/check marks (on each side)
2100 static const wxCoord MENU_BMP_MARGIN
= 2;
2102 // the margin between the labels and accel strings
2103 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2105 // the separator height in pixels: in fact, strangely enough, the real height
2106 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2108 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2110 // the size of the standard checkmark bitmap
2111 static const wxCoord MENU_CHECK_SIZE
= 9;
2113 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
2115 const wxString
& label
,
2119 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
);
2122 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
2124 const wxMenuGeometryInfo
& gi
,
2125 const wxString
& label
,
2126 const wxString
& accel
,
2127 const wxBitmap
& bitmap
,
2131 const wxGTKMenuGeometryInfo
& geomInfo
= (const wxGTKMenuGeometryInfo
&)gi
;
2136 rect
.width
= geomInfo
.GetSize().x
;
2137 rect
.height
= geomInfo
.GetItemHeight();
2139 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
, accel
, bitmap
, &geomInfo
);
2142 void wxGTKRenderer::DoDrawMenuItem(wxDC
& dc
,
2143 const wxRect
& rectOrig
,
2144 const wxString
& label
,
2147 const wxString
& accel
,
2148 const wxBitmap
& bitmap
,
2149 const wxGTKMenuGeometryInfo
*geometryInfo
)
2151 wxRect rect
= rectOrig
;
2153 // draw the selected item specially
2154 if ( flags
& wxCONTROL_SELECTED
)
2157 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
2159 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rectIn
);
2162 rect
.Deflate(MENU_HORZ_MARGIN
, MENU_VERT_MARGIN
);
2164 // draw the bitmap: use the bitmap provided or the standard checkmark for
2165 // the checkable items
2168 wxBitmap bmp
= bitmap
;
2169 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKABLE
) )
2171 bmp
= GetCheckBitmap(flags
);
2176 rect
.SetRight(geometryInfo
->GetLabelOffset());
2177 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2180 //else: menubar items don't have bitmaps
2185 rect
.x
= geometryInfo
->GetLabelOffset();
2186 rect
.SetRight(geometryInfo
->GetAccelOffset());
2189 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2191 // draw the accel string
2192 if ( !accel
.empty() )
2194 // menubar items shouldn't have them
2195 wxCHECK_RET( geometryInfo
, _T("accel strings only valid for menus") );
2197 rect
.x
= geometryInfo
->GetAccelOffset();
2198 rect
.SetRight(geometryInfo
->GetSize().x
);
2200 // NB: no accel index here
2201 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2204 // draw the submenu indicator
2205 if ( flags
& wxCONTROL_ISSUBMENU
)
2207 wxCHECK_RET( geometryInfo
, _T("wxCONTROL_ISSUBMENU only valid for menus") );
2209 rect
.x
= geometryInfo
->GetSize().x
- MENU_RIGHT_MARGIN
;
2210 rect
.width
= MENU_RIGHT_MARGIN
;
2212 DrawArrow(dc
, wxRIGHT
, rect
, flags
);
2216 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
2218 const wxMenuGeometryInfo
& geomInfo
)
2220 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2223 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2225 wxSize size
= sizeText
;
2227 // TODO: make this configurable
2228 size
.x
+= 2*MENU_HORZ_MARGIN
;
2229 size
.y
+= 2*MENU_VERT_MARGIN
;
2234 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
2235 const wxMenu
& menu
) const
2237 // prepare the dc: for now we draw all the items with the system font
2239 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2241 // the height of a normal item
2242 wxCoord heightText
= dc
.GetCharHeight();
2247 // the max length of label and accel strings: the menu width is the sum of
2248 // them, even if they're for different items (as the accels should be
2251 // the max length of the bitmap is never 0 as Windows always leaves enough
2252 // space for a check mark indicator
2253 wxCoord widthLabelMax
= 0,
2255 widthBmpMax
= MENU_LEFT_MARGIN
;
2257 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
2259 node
= node
->GetNext() )
2261 // height of this item
2264 wxMenuItem
*item
= node
->GetData();
2265 if ( item
->IsSeparator() )
2267 h
= MENU_SEPARATOR_HEIGHT
;
2269 else // not separator
2274 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2275 if ( widthLabel
> widthLabelMax
)
2277 widthLabelMax
= widthLabel
;
2281 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2282 if ( widthAccel
> widthAccelMax
)
2284 widthAccelMax
= widthAccel
;
2287 const wxBitmap
& bmp
= item
->GetBitmap();
2290 wxCoord widthBmp
= bmp
.GetWidth();
2291 if ( widthBmp
> widthBmpMax
)
2292 widthBmpMax
= widthBmp
;
2294 //else if ( item->IsCheckable() ): no need to check for this as
2295 // MENU_LEFT_MARGIN is big enough to show the check mark
2298 h
+= 2*MENU_VERT_MARGIN
;
2300 // remember the item position and height
2301 item
->SetGeometry(height
, h
);
2306 // bundle the metrics into a struct and return it
2307 wxGTKMenuGeometryInfo
*gi
= new wxGTKMenuGeometryInfo
;
2309 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2310 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2311 if ( widthAccelMax
> 0 )
2313 // if we actually have any accesl, add a margin
2314 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2317 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2319 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2320 gi
->m_size
.y
= height
;
2325 // ----------------------------------------------------------------------------
2327 // ----------------------------------------------------------------------------
2330 wxGTKRenderer::GetStatusBarBorders(wxCoord
* WXUNUSED(borderBetweenFields
)) const
2335 void wxGTKRenderer::DrawStatusField(wxDC
& WXUNUSED(dc
),
2336 const wxRect
& WXUNUSED(rect
),
2337 const wxString
& WXUNUSED(label
),
2338 int WXUNUSED(flags
), int WXUNUSED(style
))
2342 // ----------------------------------------------------------------------------
2344 // ----------------------------------------------------------------------------
2346 void wxGTKRenderer::InitComboBitmaps()
2348 wxSize sizeArrow
= m_sizeScrollbarArrow
;
2354 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
2356 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
2359 static const int comboButtonFlags
[ComboState_Max
] =
2367 wxRect
rect(sizeArrow
);
2370 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
2372 int flags
= comboButtonFlags
[n
];
2374 dc
.SelectObject(m_bitmapsCombo
[n
]);
2375 DoDrawBackground(dc
, GetBackgroundColour(flags
), rect
);
2376 DrawArrow(dc
, wxDOWN
, rect
, flags
);
2380 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
2382 wxBitmap
*bmpPressed
,
2383 wxBitmap
*bmpDisabled
)
2385 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
2391 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
2393 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
2395 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
2397 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
2400 // ----------------------------------------------------------------------------
2402 // ----------------------------------------------------------------------------
2404 void wxGTKRenderer::DoDrawBackground(wxDC
& dc
,
2405 const wxColour
& col
,
2407 wxWindow
* WXUNUSED(window
))
2409 wxBrush
brush(col
, wxSOLID
);
2411 dc
.SetPen(*wxTRANSPARENT_PEN
);
2412 dc
.DrawRectangle(rect
);
2415 void wxGTKRenderer::DrawBackground(wxDC
& dc
,
2416 const wxColour
& col
,
2421 wxColour colBg
= col
.Ok() ? col
: GetBackgroundColour(flags
);
2422 DoDrawBackground(dc
, colBg
, rect
, window
);
2425 // ----------------------------------------------------------------------------
2427 // ----------------------------------------------------------------------------
2429 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
2433 static const wxDirection sides
[] =
2435 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
2438 wxRect rect1
, rect2
, rectInner
;
2444 rectInner
.Inflate(-2);
2446 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
2448 // find the side not to draw and also adjust the rectangles to compensate
2450 wxDirection sideToOmit
;
2454 sideToOmit
= wxDOWN
;
2456 rectInner
.height
+= 1;
2464 rectInner
.height
+= 1;
2468 sideToOmit
= wxRIGHT
;
2470 rectInner
.width
+= 1;
2474 sideToOmit
= wxLEFT
;
2478 rectInner
.width
+= 1;
2482 wxFAIL_MSG(_T("unknown arrow direction"));
2486 // the outer rect first
2488 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2490 wxDirection side
= sides
[n
];
2491 if ( side
== sideToOmit
)
2494 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
2497 // and then the inner one
2498 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2500 wxDirection side
= sides
[n
];
2501 if ( side
== sideToOmit
)
2504 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
2510 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
2512 const wxRect
& rectArrow
,
2515 // first of all, draw the border around it - but we don't want the border
2516 // on the side opposite to the arrow point
2517 wxRect rect
= rectArrow
;
2518 DrawArrowBorder(dc
, &rect
, dir
);
2520 // then the arrow itself
2521 DrawArrow(dc
, dir
, rect
, flags
);
2524 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
2525 // these people are just crazy :-(
2526 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2539 wxPoint ptArrow
[Point_Max
];
2541 wxColour colInside
= GetBackgroundColour(flags
);
2543 if ( flags
& wxCONTROL_DISABLED
)
2545 penShadow
[0] = m_penDarkGrey
;
2546 penShadow
[1] = m_penDarkGrey
;
2547 penShadow
[2] = wxNullPen
;
2548 penShadow
[3] = wxNullPen
;
2550 else if ( flags
& wxCONTROL_PRESSED
)
2552 penShadow
[0] = m_penDarkGrey
;
2553 penShadow
[1] = m_penHighlight
;
2554 penShadow
[2] = wxNullPen
;
2555 penShadow
[3] = m_penBlack
;
2557 else // normal arrow
2559 penShadow
[0] = m_penHighlight
;
2560 penShadow
[1] = m_penBlack
;
2561 penShadow
[2] = m_penDarkGrey
;
2562 penShadow
[3] = wxNullPen
;
2566 if ( dir
== wxUP
|| dir
== wxDOWN
)
2569 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2573 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2576 // draw the arrow interior
2577 dc
.SetPen(*wxTRANSPARENT_PEN
);
2578 dc
.SetBrush(wxBrush(colInside
, wxSOLID
));
2583 ptArrow
[Point_First
].x
= rect
.GetLeft();
2584 ptArrow
[Point_First
].y
= rect
.GetBottom();
2585 ptArrow
[Point_Second
].x
= middle
;
2586 ptArrow
[Point_Second
].y
= rect
.GetTop();
2587 ptArrow
[Point_Third
].x
= rect
.GetRight();
2588 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2592 ptArrow
[Point_First
] = rect
.GetPosition();
2593 ptArrow
[Point_Second
].x
= middle
;
2594 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2595 ptArrow
[Point_Third
].x
= rect
.GetRight();
2596 ptArrow
[Point_Third
].y
= rect
.GetTop();
2600 ptArrow
[Point_First
].x
= rect
.GetRight();
2601 ptArrow
[Point_First
].y
= rect
.GetTop();
2602 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2603 ptArrow
[Point_Second
].y
= middle
;
2604 ptArrow
[Point_Third
].x
= rect
.GetRight();
2605 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2609 ptArrow
[Point_First
] = rect
.GetPosition();
2610 ptArrow
[Point_Second
].x
= rect
.GetRight();
2611 ptArrow
[Point_Second
].y
= middle
;
2612 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2613 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2617 wxFAIL_MSG(_T("unknown arrow direction"));
2620 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2622 // draw the arrow border
2623 dc
.SetPen(penShadow
[0]);
2627 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2628 dc
.DrawPoint(ptArrow
[Point_First
]);
2629 if ( penShadow
[3].Ok() )
2631 dc
.SetPen(penShadow
[3]);
2632 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2633 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2635 dc
.SetPen(penShadow
[1]);
2636 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2637 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2638 dc
.DrawPoint(ptArrow
[Point_Third
]);
2639 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2640 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2641 if ( penShadow
[2].Ok() )
2643 dc
.SetPen(penShadow
[2]);
2644 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2645 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2646 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2647 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2652 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2653 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2654 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2655 if ( penShadow
[2].Ok() )
2657 dc
.SetPen(penShadow
[2]);
2658 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2659 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2661 dc
.SetPen(penShadow
[1]);
2662 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2663 dc
.DrawPoint(ptArrow
[Point_Third
]);
2667 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2668 dc
.DrawPoint(ptArrow
[Point_First
]);
2669 if ( penShadow
[2].Ok() )
2671 dc
.SetPen(penShadow
[2]);
2672 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2673 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2674 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2675 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2677 dc
.SetPen(penShadow
[1]);
2678 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2679 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2680 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2681 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2685 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2686 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2687 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2688 dc
.SetPen(penShadow
[1]);
2689 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2690 dc
.DrawPoint(ptArrow
[Point_Third
]);
2694 wxFAIL_MSG(_T("unknown arrow direction"));
2699 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2701 wxOrientation orient
)
2703 if ( orient
== wxVERTICAL
)
2705 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2707 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2709 rect
->Inflate(-1, 0);
2711 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2713 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2715 rect
->Inflate(-1, 0);
2719 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2721 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2723 rect
->Inflate(0, -1);
2725 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2727 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2729 rect
->Inflate(0, -1);
2733 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2734 wxOrientation orient
,
2738 // the thumb is never pressed never has focus border under GTK and the
2739 // scrollbar background never changes at all
2740 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2742 // we don't want the border in the direction of the scrollbar movement
2743 wxRect rectThumb
= rect
;
2744 DrawThumbBorder(dc
, &rectThumb
, orient
);
2746 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2747 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2750 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2751 wxOrientation orient
,
2753 int WXUNUSED(flags
))
2755 wxRect rectBar
= rect
;
2756 DrawThumbBorder(dc
, &rectBar
, orient
);
2757 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2760 void wxGTKRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2762 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2765 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2766 wxScrollBar::Element elem
,
2769 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2770 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2772 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2774 elem
= wxScrollBar::Element_Bar_2
;
2777 return StandardGetScrollbarRect(scrollbar
, elem
,
2779 GetScrollbarArrowSize(scrollbar
));
2782 wxCoord
wxGTKRenderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
2784 return StandardScrollBarSize(scrollbar
, GetScrollbarArrowSize(scrollbar
));
2787 wxHitTest
wxGTKRenderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
2788 const wxPoint
& pt
) const
2790 return StandardHitTestScrollbar(scrollbar
, pt
,
2791 GetScrollbarArrowSize(scrollbar
));
2794 wxCoord
wxGTKRenderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
2797 return StandardScrollbarToPixel(scrollbar
, thumbPos
,
2798 GetScrollbarArrowSize(scrollbar
));
2801 int wxGTKRenderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
2804 return StandardPixelToScrollbar(scrollbar
, coord
,
2805 GetScrollbarArrowSize(scrollbar
));
2808 // ----------------------------------------------------------------------------
2810 // ----------------------------------------------------------------------------
2812 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2815 if ( wxDynamicCast(window
, wxBitmapButton
) )
2820 #endif // wxUSE_BMPBUTTON
2821 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
2824 || wxDynamicCast(window
, wxButton
)
2825 # endif // wxUSE_BUTTON
2826 # if wxUSE_TOGGLEBTN
2827 || wxDynamicCast(window
, wxToggleButton
)
2828 # endif // wxUSE_TOGGLEBTN
2831 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2833 // TODO: this is ad hoc...
2834 size
->x
+= 3*window
->GetCharWidth();
2835 wxCoord minBtnHeight
= 18;
2836 if ( size
->y
< minBtnHeight
)
2837 size
->y
= minBtnHeight
;
2839 // button border width
2843 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
2844 if ( wxDynamicCast(window
, wxScrollBar
) )
2846 // we only set the width of vert scrollbars and height of the
2848 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2849 size
->y
= m_sizeScrollbarArrow
.x
;
2851 size
->x
= m_sizeScrollbarArrow
.x
;
2855 // take into account the border width
2856 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
2857 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
2858 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
2862 // ----------------------------------------------------------------------------
2863 // top level windows
2864 // ----------------------------------------------------------------------------
2866 void wxGTKRenderer::DrawFrameTitleBar(wxDC
& WXUNUSED(dc
),
2867 const wxRect
& WXUNUSED(rect
),
2868 const wxString
& WXUNUSED(title
),
2869 const wxIcon
& WXUNUSED(icon
),
2870 int WXUNUSED(flags
),
2871 int WXUNUSED(specialButton
),
2872 int WXUNUSED(specialButtonFlag
))
2876 void wxGTKRenderer::DrawFrameBorder(wxDC
& WXUNUSED(dc
),
2877 const wxRect
& WXUNUSED(rect
),
2878 int WXUNUSED(flags
))
2882 void wxGTKRenderer::DrawFrameBackground(wxDC
& WXUNUSED(dc
),
2883 const wxRect
& WXUNUSED(rect
),
2884 int WXUNUSED(flags
))
2888 void wxGTKRenderer::DrawFrameTitle(wxDC
& WXUNUSED(dc
),
2889 const wxRect
& WXUNUSED(rect
),
2890 const wxString
& WXUNUSED(title
),
2891 int WXUNUSED(flags
))
2895 void wxGTKRenderer::DrawFrameIcon(wxDC
& WXUNUSED(dc
),
2896 const wxRect
& WXUNUSED(rect
),
2897 const wxIcon
& WXUNUSED(icon
),
2898 int WXUNUSED(flags
))
2902 void wxGTKRenderer::DrawFrameButton(wxDC
& WXUNUSED(dc
),
2903 wxCoord
WXUNUSED(x
),
2904 wxCoord
WXUNUSED(y
),
2905 int WXUNUSED(button
),
2906 int WXUNUSED(flags
))
2911 wxGTKRenderer::GetFrameClientArea(const wxRect
& rect
,
2912 int WXUNUSED(flags
)) const
2918 wxGTKRenderer::GetFrameTotalSize(const wxSize
& clientSize
,
2919 int WXUNUSED(flags
)) const
2924 wxSize
wxGTKRenderer::GetFrameMinSize(int WXUNUSED(flags
)) const
2929 wxSize
wxGTKRenderer::GetFrameIconSize() const
2931 return wxSize(wxDefaultCoord
, wxDefaultCoord
);
2935 wxGTKRenderer::HitTestFrame(const wxRect
& WXUNUSED(rect
),
2936 const wxPoint
& WXUNUSED(pt
),
2937 int WXUNUSED(flags
)) const
2939 return wxHT_TOPLEVEL_CLIENT_AREA
;
2943 // ----------------------------------------------------------------------------
2945 // ----------------------------------------------------------------------------
2947 /* Copyright (c) Julian Smart */
2948 static const char *error_xpm
[] = {
2949 /* columns rows colors chars-per-pixel */
2963 " ................. ",
2964 " ................... ",
2965 " ....................... ",
2966 " ......................... ",
2967 " ........................... ",
2968 " ...........................X ",
2969 " .............................X ",
2970 " ............................... ",
2971 " ...............................X ",
2972 " .................................X ",
2973 " .................................X ",
2974 " .................................XX ",
2975 " ...ooooooooooooooooooooooooooo...XX ",
2976 " ....ooooooooooooooooooooooooooo....X ",
2977 " ....ooooooooooooooooooooooooooo....X ",
2978 " ....ooooooooooooooooooooooooooo....XX ",
2979 " ....ooooooooooooooooooooooooooo....XX ",
2980 " ....ooooooooooooooooooooooooooo....XX ",
2981 " ...ooooooooooooooooooooooooooo...XXX ",
2982 " ...ooooooooooooooooooooooooooo...XXX ",
2983 " .................................XX ",
2984 " .................................XX ",
2985 " ...............................XXX ",
2986 " ...............................XXX ",
2987 " .............................XXX ",
2988 " ...........................XXXX ",
2989 " ...........................XXX ",
2990 " .........................XXX ",
2991 " .......................XXXX ",
2992 " X...................XXXXX ",
2993 " X.................XXXXX ",
2994 " X.............XXXXX ",
2995 " XXXX.....XXXXXXXX ",
3006 /* Copyright (c) Julian Smart */
3007 static const char *info_xpm
[] = {
3008 /* columns rows colors chars-per-pixel */
3032 " .XXXOXXXXXXXoo. ",
3033 " .XOOXXX+XXXXXo. ",
3034 " .XOOOXX+++XXXXoo. ",
3035 " .XOOXXX+++XXXXXo. ",
3036 " .XOOOXXX+++XXXXXXo. ",
3037 " .XOOXXXX+++XXXXXXo. ",
3038 " .XXXXXXX+++XXXXXXX. ",
3039 " .XXXXXXX+++XXXXXXo. ",
3040 " .XXXXXXX+++XXXXXoo. ",
3041 " .XXXXXX+++XXXXXo. ",
3042 " .XXXXXXX+XXXXXXo. ",
3043 " .XXXXXXXXXXXXo. ",
3044 " .XXXXX+++XXXoo. ",
3070 /* Copyright (c) Julian Smart */
3071 static const char *warning_xpm
[] = {
3072 /* columns rows colors chars-per-pixel */
3102 " ..XXXXO@#XXX... ",
3103 " ...XXXXO@#XXXX.. ",
3104 " ..XXXXXO@#XXXX... ",
3105 " ...XXXXXo@OXXXXX.. ",
3106 " ...XXXXXXo@OXXXXXX.. ",
3107 " ..XXXXXXX$@OXXXXXX... ",
3108 " ...XXXXXXXX@XXXXXXXX.. ",
3109 " ...XXXXXXXXXXXXXXXXXX... ",
3110 " ..XXXXXXXXXXOXXXXXXXXX.. ",
3111 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
3112 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
3113 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
3114 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
3115 " .............................. ",
3116 " .............................. ",
3134 /* Copyright (c) Julian Smart */
3135 static const char *question_xpm
[] = {
3136 /* columns rows colors chars-per-pixel */
3166 " ..XXXXoooooXXXO+ ",
3167 " ..XXooooooooooooX@.. ",
3168 " ..XoooooooooooooooXX#. ",
3169 " $%XoooooooooooooooooXX#. ",
3170 " &.XoooooooXXXXXXooooooXX.. ",
3171 " .XooooooXX.$...$XXoooooX*. ",
3172 " $.XoooooX%.$ .*oooooo=.. ",
3173 " .XooooooX.. -.XoooooX.. ",
3174 " .XoooooX..+ .XoooooX;. ",
3175 " ...XXXX..: .XoooooX;. ",
3176 " ........ >.XoooooX;. ",
3210 wxBitmap
wxGTKArtProvider::CreateBitmap(const wxArtID
& id
,
3211 const wxArtClient
& WXUNUSED(client
),
3212 const wxSize
& WXUNUSED(size
))
3214 if ( id
== wxART_INFORMATION
)
3215 return wxBitmap(info_xpm
);
3216 if ( id
== wxART_ERROR
)
3217 return wxBitmap(error_xpm
);
3218 if ( id
== wxART_WARNING
)
3219 return wxBitmap(warning_xpm
);
3220 if ( id
== wxART_QUESTION
)
3221 return wxBitmap(question_xpm
);
3222 return wxNullBitmap
;
3226 // ============================================================================
3228 // ============================================================================
3230 // ----------------------------------------------------------------------------
3231 // wxGTKInputHandler
3232 // ----------------------------------------------------------------------------
3234 wxGTKInputHandler::wxGTKInputHandler(wxGTKRenderer
*renderer
)
3236 m_renderer
= renderer
;
3239 bool wxGTKInputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
3240 const wxKeyEvent
& WXUNUSED(event
),
3241 bool WXUNUSED(pressed
))
3246 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
3247 const wxMouseEvent
& event
)
3249 // clicking on the control gives it focus
3250 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
3252 control
->GetInputWindow()->SetFocus();
3260 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3261 const wxMouseEvent
& event
)
3263 if ( event
.Entering() )
3265 control
->GetInputWindow()->SetCurrent(true);
3267 else if ( event
.Leaving() )
3269 control
->GetInputWindow()->SetCurrent(false);
3279 // ----------------------------------------------------------------------------
3280 // wxGTKCheckboxInputHandler
3281 // ----------------------------------------------------------------------------
3283 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3284 const wxKeyEvent
& event
,
3289 int keycode
= event
.GetKeyCode();
3290 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
3292 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
3301 // ----------------------------------------------------------------------------
3302 // wxGTKTextCtrlInputHandler
3303 // ----------------------------------------------------------------------------
3305 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
3306 const wxKeyEvent
& event
,
3309 // handle only GTK-specific text bindings here, the others are handled in
3313 wxControlAction action
;
3314 int keycode
= event
.GetKeyCode();
3315 if ( event
.ControlDown() )
3320 action
= wxACTION_TEXT_HOME
;
3324 action
= wxACTION_TEXT_LEFT
;
3328 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
3332 action
= wxACTION_TEXT_END
;
3336 action
= wxACTION_TEXT_RIGHT
;
3340 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
3344 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
3348 action
= wxACTION_TEXT_DOWN
;
3352 action
= wxACTION_TEXT_UP
;
3356 //delete the entire line
3357 control
->PerformAction(wxACTION_TEXT_HOME
);
3358 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
3362 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
3366 else if ( event
.AltDown() )
3371 action
= wxACTION_TEXT_WORD_LEFT
;
3375 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
3379 action
= wxACTION_TEXT_WORD_RIGHT
;
3384 if ( action
!= wxACTION_NONE
)
3386 control
->PerformAction(action
);
3392 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);