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"
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
,
177 virtual void DrawTextLine(wxDC
& dc
,
178 const wxString
& text
,
183 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
184 virtual void DrawTab(wxDC
& dc
,
187 const wxString
& label
,
188 const wxBitmap
& bitmap
= wxNullBitmap
,
190 int indexAccel
= -1);
192 virtual void DrawSliderShaft(wxDC
& dc
,
195 wxOrientation orient
,
198 wxRect
*rectShaft
= NULL
);
199 virtual void DrawSliderThumb(wxDC
& dc
,
201 wxOrientation orient
,
204 virtual void DrawSliderTicks(wxDC
& WXUNUSED(dc
),
205 const wxRect
& WXUNUSED(rect
),
206 int WXUNUSED(lenThumb
),
207 wxOrientation
WXUNUSED(orient
),
210 int WXUNUSED(step
) = 1,
211 int WXUNUSED(flags
) = 0,
212 long WXUNUSED(style
) = 0)
214 // we don't have the ticks in GTK version
217 virtual void DrawMenuBarItem(wxDC
& dc
,
219 const wxString
& label
,
221 int indexAccel
= -1);
222 virtual void DrawMenuItem(wxDC
& dc
,
224 const wxMenuGeometryInfo
& geometryInfo
,
225 const wxString
& label
,
226 const wxString
& accel
,
227 const wxBitmap
& bitmap
= wxNullBitmap
,
229 int indexAccel
= -1);
230 virtual void DrawMenuSeparator(wxDC
& dc
,
232 const wxMenuGeometryInfo
& geomInfo
);
234 virtual void DrawStatusField(wxDC
& dc
,
236 const wxString
& label
,
237 int flags
= 0, int style
= 0);
239 virtual void DrawFrameTitleBar(wxDC
& dc
,
241 const wxString
& title
,
244 int specialButton
= 0,
245 int specialButtonFlag
= 0);
246 virtual void DrawFrameBorder(wxDC
& dc
,
249 virtual void DrawFrameBackground(wxDC
& dc
,
252 virtual void DrawFrameTitle(wxDC
& dc
,
254 const wxString
& title
,
256 virtual void DrawFrameIcon(wxDC
& dc
,
260 virtual void DrawFrameButton(wxDC
& dc
,
261 wxCoord x
, wxCoord y
,
266 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
267 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
268 virtual wxSize
GetFrameMinSize(int flags
) const;
269 virtual wxSize
GetFrameIconSize() const;
270 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
272 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
274 wxBitmap
*bmpPressed
,
275 wxBitmap
*bmpDisabled
);
277 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
278 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
279 virtual bool AreScrollbarsInsideBorder() const;
281 // geometry and hit testing
282 virtual wxSize
GetScrollbarArrowSize() const
283 { return m_sizeScrollbarArrow
; }
284 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
285 wxScrollBar::Element elem
,
286 int thumbPos
= -1) const;
287 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
288 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
289 const wxPoint
& pt
) const;
290 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
292 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
293 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
294 { return fontHeight
+ 2; }
295 virtual wxSize
GetCheckBitmapSize() const
296 { return wxSize(10, 10); }
297 virtual wxSize
GetRadioBitmapSize() const
298 { return wxSize(11, 11); }
299 virtual wxCoord
GetCheckItemMargin() const
302 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
303 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
304 virtual wxSize
GetToolBarMargin() const
305 { return wxSize(6, 6); }
307 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
308 const wxRect
& rect
) const;
309 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
311 wxCoord
*extraSpaceBeyond
) const;
313 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
314 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
316 virtual wxCoord
GetSliderDim() const { return 15; }
317 virtual wxCoord
GetSliderTickLen() const { return 0; }
318 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
320 wxOrientation orient
,
321 long style
= 0) const;
322 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
324 wxOrientation orient
) const;
325 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
327 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
328 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
329 const wxMenu
& menu
) const;
331 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
333 // helpers for "wxBitmap wxColourScheme::Get()"
334 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
335 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
336 void DrawUndeterminedBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
339 // DrawBackground() helpers
341 // get the colour to use for background
342 wxColour
GetBackgroundColour(int flags
) const
344 if ( flags
& wxCONTROL_PRESSED
)
345 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
346 else if ( flags
& wxCONTROL_CURRENT
)
347 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
349 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
352 // draw the background with any colour, not only the default one(s)
353 void DoDrawBackground(wxDC
& dc
,
356 wxWindow
*window
= NULL
);
358 // DrawBorder() helpers: all of them shift and clip the DC after drawing
361 // just draw a rectangle with the given pen
362 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
364 // draw the lower left part of rectangle
365 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
367 // draw the rectange using the first brush for the left and top sides and
368 // the second one for the bottom and right ones
369 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
370 const wxPen
& pen1
, const wxPen
& pen2
);
372 // as DrawShadedRect() but the pixels in the bottom left and upper right
373 // border are drawn with the pen1, not pen2
374 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
375 const wxPen
& pen1
, const wxPen
& pen2
);
377 // used for drawing opened rectangles - draws only one side of it at once
378 // (and doesn't adjust the rect)
379 void DrawAntiShadedRectSide(wxDC
& dc
,
385 // draw an opened rect for the arrow in given direction
386 void DrawArrowBorder(wxDC
& dc
,
390 // draw two sides of the rectangle
391 void DrawThumbBorder(wxDC
& dc
,
393 wxOrientation orient
);
395 // draw the normal 3D border
396 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
398 // just as DrawRaisedBorder() except that the bottom left and up right
399 // pixels of the interior rect are drawn in another colour (i.e. the inner
400 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
401 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
403 // returns the size of the arrow for the scrollbar (depends on
405 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
408 if ( scrollbar
->IsVertical() )
410 size
= m_sizeScrollbarArrow
;
414 size
.x
= m_sizeScrollbarArrow
.y
;
415 size
.y
= m_sizeScrollbarArrow
.x
;
421 // get the line wrap indicator bitmap
422 wxBitmap
GetLineWrapBitmap() const;
424 // DrawCheckBitmap and DrawRadioBitmap helpers
426 // draw the check bitmaps once and cache them for later use
427 wxBitmap
GetCheckBitmap(int flags
);
429 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
431 void DrawUpZag(wxDC
& dc
,
432 wxCoord x1
, wxCoord x2
,
433 wxCoord y1
, wxCoord y2
);
434 void DrawDownZag(wxDC
& dc
,
435 wxCoord x1
, wxCoord x2
,
436 wxCoord y1
, wxCoord y2
);
438 // draw the radio button bitmap for the given state
439 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
441 // draw check/radio - the bitmap must be a valid one by now
442 void DoDrawCheckOrRadioBitmap(wxDC
& dc
,
443 const wxString
& label
,
444 const wxBitmap
& bitmap
,
445 const wxRect
& rectTotal
,
450 // common part of DrawMenuItem() and DrawMenuBarItem()
451 void DoDrawMenuItem(wxDC
& dc
,
453 const wxString
& label
,
456 const wxString
& accel
= wxEmptyString
,
457 const wxBitmap
& bitmap
= wxNullBitmap
,
458 const wxGTKMenuGeometryInfo
*geometryInfo
= NULL
);
460 // initialize the combo bitmaps
461 void InitComboBitmaps();
464 const wxColourScheme
*m_scheme
;
467 wxSize m_sizeScrollbarArrow
;
476 // the checkbox bitmaps: first row is for the normal, second for the
477 // pressed state and the columns are for checked, unchecked and
478 // undeterminated respectively
479 wxBitmap m_bitmapsCheckbox
[2][3];
481 // the line wrap bitmap (drawn at the end of wrapped lines)
482 wxBitmap m_bmpLineWrap
;
484 // the combobox bitmaps
494 wxBitmap m_bitmapsCombo
[ComboState_Max
];
497 // ----------------------------------------------------------------------------
498 // wxGTKInputHandler and derived classes: process the keyboard and mouse
499 // messages according to GTK standards
500 // ----------------------------------------------------------------------------
502 class wxGTKInputHandler
: public wxInputHandler
505 wxGTKInputHandler(wxGTKRenderer
*renderer
);
507 virtual bool HandleKey(wxInputConsumer
*control
,
508 const wxKeyEvent
& event
,
510 virtual bool HandleMouse(wxInputConsumer
*control
,
511 const wxMouseEvent
& event
);
512 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
515 wxGTKRenderer
*m_renderer
;
518 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
521 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
522 : wxStdScrollBarInputHandler(renderer
, handler
) { }
525 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
527 // only arrows and the thumb can be highlighted
528 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
531 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
534 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
536 // only arrows can be pressed
540 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
543 virtual bool IsAllowedButton(int WXUNUSED(button
)) { return true; }
547 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
548 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
552 class wxGTKCheckboxInputHandler
: public wxStdCheckboxInputHandler
555 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
556 : wxStdCheckboxInputHandler(handler
) { }
558 virtual bool HandleKey(wxInputConsumer
*control
,
559 const wxKeyEvent
& event
,
563 class wxGTKTextCtrlInputHandler
: public wxStdTextCtrlInputHandler
566 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
567 : wxStdTextCtrlInputHandler(handler
) { }
569 virtual bool HandleKey(wxInputConsumer
*control
,
570 const wxKeyEvent
& event
,
574 // ----------------------------------------------------------------------------
575 // wxGTKColourScheme: uses the standard GTK colours
576 // ----------------------------------------------------------------------------
578 class wxGTKColourScheme
: public wxColourScheme
581 virtual wxColour
Get(StdColour col
) const;
582 virtual wxColour
GetBackground(wxWindow
*win
) const;
585 // ----------------------------------------------------------------------------
587 // ----------------------------------------------------------------------------
589 class wxGTKArtProvider
: public wxArtProvider
592 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
593 const wxArtClient
& client
,
597 // ----------------------------------------------------------------------------
599 // ----------------------------------------------------------------------------
601 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
603 class wxGTKTheme
: public wxTheme
607 virtual ~wxGTKTheme();
609 virtual wxRenderer
*GetRenderer();
610 virtual wxArtProvider
*GetArtProvider();
611 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
612 virtual wxColourScheme
*GetColourScheme();
615 // get the default input handler
616 wxInputHandler
*GetDefaultInputHandler();
618 wxGTKRenderer
*m_renderer
;
620 wxGTKArtProvider
*m_artProvider
;
622 // the names of the already created handlers and the handlers themselves
623 // (these arrays are synchronized)
624 wxSortedArrayString m_handlerNames
;
625 wxArrayHandlers m_handlers
;
627 wxGTKInputHandler
*m_handlerDefault
;
629 wxGTKColourScheme
*m_scheme
;
631 WX_DECLARE_THEME(gtk
)
634 // ============================================================================
636 // ============================================================================
638 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
640 // ----------------------------------------------------------------------------
642 // ----------------------------------------------------------------------------
644 wxGTKTheme::wxGTKTheme()
648 m_handlerDefault
= NULL
;
649 m_artProvider
= NULL
;
652 wxGTKTheme::~wxGTKTheme()
654 size_t count
= m_handlers
.GetCount();
655 for ( size_t n
= 0; n
< count
; n
++ )
657 if ( m_handlers
[n
] != m_handlerDefault
)
658 delete m_handlers
[n
];
661 delete m_handlerDefault
;
664 wxArtProvider::RemoveProvider(m_artProvider
);
667 wxRenderer
*wxGTKTheme::GetRenderer()
671 m_renderer
= new wxGTKRenderer(GetColourScheme());
677 wxArtProvider
*wxGTKTheme::GetArtProvider()
679 if ( !m_artProvider
)
681 m_artProvider
= new wxGTKArtProvider
;
684 return m_artProvider
;
687 wxColourScheme
*wxGTKTheme::GetColourScheme()
691 m_scheme
= new wxGTKColourScheme
;
696 wxInputHandler
*wxGTKTheme::GetDefaultInputHandler()
698 if ( !m_handlerDefault
)
700 m_handlerDefault
= new wxGTKInputHandler(m_renderer
);
703 return m_handlerDefault
;
706 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
)
708 wxInputHandler
*handler
;
709 int n
= m_handlerNames
.Index(control
);
710 if ( n
== wxNOT_FOUND
)
712 // create a new handler
713 if ( control
== wxINP_HANDLER_SCROLLBAR
)
714 handler
= new wxGTKScrollBarInputHandler(m_renderer
,
715 GetDefaultInputHandler());
717 else if ( control
== wxINP_HANDLER_BUTTON
)
718 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
719 #endif // wxUSE_CHECKBOX
721 else if ( control
== wxINP_HANDLER_CHECKBOX
)
722 handler
= new wxGTKCheckboxInputHandler(GetDefaultInputHandler());
723 #endif // wxUSE_CHECKBOX
725 else if ( control
== wxINP_HANDLER_COMBOBOX
)
726 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
727 #endif // wxUSE_COMBOBOX
729 else if ( control
== wxINP_HANDLER_LISTBOX
)
730 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
731 #endif // wxUSE_LISTBOX
732 #if wxUSE_CHECKLISTBOX
733 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
734 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
735 #endif // wxUSE_CHECKLISTBOX
737 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
738 handler
= new wxGTKTextCtrlInputHandler(GetDefaultInputHandler());
739 #endif // wxUSE_TEXTCTRL
741 else if ( control
== wxINP_HANDLER_SLIDER
)
742 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
743 #endif // wxUSE_SLIDER
745 else if ( control
== wxINP_HANDLER_SPINBTN
)
746 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
747 #endif // wxUSE_SPINBTN
749 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
750 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
751 #endif // wxUSE_NOTEBOOK
753 else if ( control
== wxINP_HANDLER_TOOLBAR
)
754 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
755 #endif // wxUSE_TOOLBAR
756 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
757 handler
= new wxStdFrameInputHandler(GetDefaultInputHandler());
759 handler
= GetDefaultInputHandler();
761 n
= m_handlerNames
.Add(control
);
762 m_handlers
.Insert(handler
, n
);
764 else // we already have it
766 handler
= m_handlers
[n
];
772 // ============================================================================
774 // ============================================================================
776 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
779 if ( win
->UseBgCol() )
781 // use the user specified colour
782 col
= win
->GetBackgroundColour();
785 if ( !win
->ShouldInheritColours() )
787 // doesn't depend on the state
795 int flags
= win
->GetStateFlags();
797 // the colour set by the user should be used for the normal state
798 // and for the states for which we don't have any specific colours
799 if ( !col
.Ok() || (flags
!= 0) )
801 if ( wxDynamicCast(win
, wxScrollBar
) )
802 col
= Get(SCROLLBAR
);
803 else if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
804 col
= Get(CONTROL_CURRENT
);
805 else if ( flags
& wxCONTROL_PRESSED
)
806 col
= Get(CONTROL_PRESSED
);
815 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
819 case WINDOW
: return *wxWHITE
;
821 case SHADOW_DARK
: return *wxBLACK
;
822 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
823 case SHADOW_IN
: return wxColour(0xd6d6d6);
824 case SHADOW_OUT
: return wxColour(0x969696);
826 case CONTROL
: return wxColour(0xd6d6d6);
827 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
828 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
830 case CONTROL_TEXT
: return *wxBLACK
;
831 case CONTROL_TEXT_DISABLED
:
832 return wxColour(0x757575);
833 case CONTROL_TEXT_DISABLED_SHADOW
:
837 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
839 case HIGHLIGHT
: return wxColour(0x9c0000);
840 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
842 case GAUGE
: return Get(CONTROL_CURRENT
);
846 wxFAIL_MSG(_T("invalid standard colour"));
851 // ============================================================================
853 // ============================================================================
855 // ----------------------------------------------------------------------------
857 // ----------------------------------------------------------------------------
859 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
863 m_sizeScrollbarArrow
= wxSize(15, 14);
866 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
867 m_penDarkGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_OUT
), 0, wxSOLID
);
868 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
), 0, wxSOLID
);
869 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
870 m_penHighlight
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
), 0, wxSOLID
);
873 // ----------------------------------------------------------------------------
875 // ----------------------------------------------------------------------------
877 void wxGTKRenderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
881 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
882 dc
.DrawRectangle(*rect
);
888 void wxGTKRenderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
890 // draw the bottom and right sides
892 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
893 rect
->GetRight() + 1, rect
->GetBottom());
894 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
895 rect
->GetRight(), rect
->GetBottom());
902 void wxGTKRenderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
903 const wxPen
& pen1
, const wxPen
& pen2
)
905 // draw the rectangle
907 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
908 rect
->GetLeft(), rect
->GetBottom());
909 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
910 rect
->GetRight(), rect
->GetTop());
912 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
913 rect
->GetRight(), rect
->GetBottom());
914 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
915 rect
->GetRight() + 1, rect
->GetBottom());
921 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
927 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
932 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
933 rect
.GetLeft(), rect
.GetBottom() + 1);
937 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
938 rect
.GetRight() + 1, rect
.GetTop());
942 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
943 rect
.GetRight(), rect
.GetBottom() + 1);
947 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
948 rect
.GetRight() + 1, rect
.GetBottom());
952 wxFAIL_MSG(_T("unknown rectangle side"));
956 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
957 const wxPen
& pen1
, const wxPen
& pen2
)
959 // draw the rectangle
961 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
962 rect
->GetLeft(), rect
->GetBottom() + 1);
963 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
964 rect
->GetRight() + 1, rect
->GetTop());
966 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
967 rect
->GetRight(), rect
->GetBottom());
968 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
969 rect
->GetRight() + 1, rect
->GetBottom());
975 void wxGTKRenderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
977 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
978 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
981 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
983 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
984 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
987 void wxGTKRenderer::DrawBorder(wxDC
& dc
,
989 const wxRect
& rectTotal
,
995 wxRect rect
= rectTotal
;
999 case wxBORDER_SUNKEN
:
1000 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1002 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1003 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1007 case wxBORDER_STATIC
:
1008 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1010 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1014 case wxBORDER_RAISED
:
1015 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1017 DrawRaisedBorder(dc
, &rect
);
1021 case wxBORDER_DOUBLE
:
1022 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1024 DrawShadedRect(dc
, &rect
, m_penLightGrey
, m_penBlack
);
1025 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penDarkGrey
);
1026 DrawRect(dc
, &rect
, m_penLightGrey
);
1030 case wxBORDER_SIMPLE
:
1031 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1033 DrawRect(dc
, &rect
, m_penBlack
);
1038 wxFAIL_MSG(_T("unknown border type"));
1041 case wxBORDER_DEFAULT
:
1050 wxRect
wxGTKRenderer::GetBorderDimensions(wxBorder border
) const
1055 case wxBORDER_RAISED
:
1056 case wxBORDER_SUNKEN
:
1057 width
= 2*BORDER_THICKNESS
;
1060 case wxBORDER_SIMPLE
:
1061 case wxBORDER_STATIC
:
1062 width
= BORDER_THICKNESS
;
1065 case wxBORDER_DOUBLE
:
1066 width
= 3*BORDER_THICKNESS
;
1070 wxFAIL_MSG(_T("unknown border type"));
1073 case wxBORDER_DEFAULT
:
1083 rect
.height
= width
;
1088 bool wxGTKRenderer::AreScrollbarsInsideBorder() const
1090 // no, the scrollbars are outside the border in GTK+
1094 // ----------------------------------------------------------------------------
1096 // ----------------------------------------------------------------------------
1098 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
1100 const wxRect
& rectOrig
,
1104 wxRect rect
= rectOrig
;
1106 if ( border
!= wxBORDER_NONE
)
1108 if ( flags
& wxCONTROL_FOCUSED
)
1110 DrawRect(dc
, &rect
, m_penBlack
);
1111 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1115 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1116 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penHighlight
);
1124 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
1125 const wxRect
& rectTotal
,
1129 wxRect rect
= rectTotal
;
1131 if ( flags
& wxCONTROL_PRESSED
)
1133 // button pressed: draw a black border around it and an inward shade
1134 DrawRect(dc
, &rect
, m_penBlack
);
1136 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1138 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1139 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penDarkGrey
);
1144 // button not pressed
1146 if ( flags
& wxCONTROL_ISDEFAULT
)
1151 if ( flags
& wxCONTROL_FOCUSED
)
1153 // button is currently default: add an extra border around it
1154 DrawRect(dc
, &rect
, m_penBlack
);
1157 // now draw a normal button
1158 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1160 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1161 DrawAntiShadedRect(dc
, &rect
,
1162 wxPen(GetBackgroundColour(flags
), 0, wxSOLID
),
1173 // ----------------------------------------------------------------------------
1175 // ----------------------------------------------------------------------------
1177 void wxGTKRenderer::DrawHorizontalLine(wxDC
& dc
,
1178 wxCoord y
, wxCoord x1
, wxCoord x2
)
1180 dc
.SetPen(m_penDarkGrey
);
1181 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1182 dc
.SetPen(m_penHighlight
);
1184 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1187 void wxGTKRenderer::DrawVerticalLine(wxDC
& dc
,
1188 wxCoord x
, wxCoord y1
, wxCoord y2
)
1190 dc
.SetPen(m_penDarkGrey
);
1191 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1192 dc
.SetPen(m_penHighlight
);
1194 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1197 void wxGTKRenderer::DrawFrame(wxDC
& dc
,
1198 const wxString
& label
,
1204 wxCoord height
= 0; // of the label
1205 wxRect rectFrame
= rect
;
1206 if ( !label
.empty() )
1208 // the text should touch the top border of the rect, so the frame
1209 // itself should be lower
1210 dc
.GetTextExtent(label
, NULL
, &height
);
1211 rectFrame
.y
+= height
/ 2;
1212 rectFrame
.height
-= height
/ 2;
1214 // TODO: the +4 should be customizable
1217 rectText
.x
= rectFrame
.x
+ 4;
1218 rectText
.y
= rect
.y
;
1219 rectText
.width
= rectFrame
.width
- 8;
1220 rectText
.height
= height
;
1223 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1225 rectLabel
.width
+= 2;
1227 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1229 // GTK+ does it like this
1230 dc
.SetPen(m_penHighlight
);
1231 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
1232 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
1236 // just draw the complete frame
1237 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1238 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1242 // ----------------------------------------------------------------------------
1244 // ----------------------------------------------------------------------------
1246 void wxGTKRenderer::DrawLabel(wxDC
& dc
,
1247 const wxString
& label
,
1254 DrawButtonLabel(dc
, label
, wxNullBitmap
, rect
, flags
,
1255 alignment
, indexAccel
, rectBounds
);
1258 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
1259 const wxString
& label
,
1260 const wxBitmap
& image
,
1267 if ( flags
& wxCONTROL_DISABLED
)
1269 // make the text grey and draw a shade for it
1270 dc
.SetTextForeground(*wxWHITE
); // FIXME hardcoded colour
1271 wxRect rectShadow
= rect
;
1274 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1275 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT_DISABLED
));
1279 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT
));
1282 dc
.DrawLabel(label
, image
, rect
, alignment
, indexAccel
, rectBounds
);
1285 void wxGTKRenderer::DrawItem(wxDC
& dc
,
1286 const wxString
& label
,
1290 wxLogTrace(_T("listbox"), _T("drawing item '%s' at (%d, %d)-(%d, %d)"),
1293 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1296 if ( flags
& wxCONTROL_SELECTED
)
1298 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
), wxSOLID
));
1299 dc
.SetPen(*wxTRANSPARENT_PEN
);
1300 dc
.DrawRectangle(rect
);
1302 colFg
= dc
.GetTextForeground();
1303 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
1306 if ( flags
& wxCONTROL_FOCUSED
)
1308 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1309 wxRect rectFocus
= rect
;
1310 DrawRect(dc
, &rectFocus
, m_penBlack
);
1313 wxRect rectText
= rect
;
1316 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
1318 if ( flags
& wxCONTROL_SELECTED
)
1320 dc
.SetBackgroundMode(wxTRANSPARENT
);
1323 // restore the text colour
1326 dc
.SetTextForeground(colFg
);
1330 void wxGTKRenderer::DrawCheckItem(wxDC
& dc
,
1331 const wxString
& label
,
1332 const wxBitmap
& bitmap
,
1336 wxRect rectBitmap
= rect
;
1338 rectBitmap
.width
= GetCheckBitmapSize().x
;
1340 // never draw the focus rect around the check indicators here
1341 DrawCheckButton(dc
, wxEmptyString
, bitmap
, rectBitmap
, flags
& ~wxCONTROL_FOCUSED
);
1343 wxRect rectLabel
= rect
;
1344 wxCoord shift
= rectBitmap
.width
+ 2*GetCheckItemMargin();
1345 rectLabel
.x
+= shift
;
1346 rectLabel
.width
-= shift
;
1347 DrawItem(dc
, label
, rectLabel
, flags
);
1350 // ----------------------------------------------------------------------------
1351 // check/radion buttons
1352 // ----------------------------------------------------------------------------
1354 void wxGTKRenderer::DrawUndeterminedBitmap(wxDC
& dc
,
1355 const wxRect
& rectTotal
,
1358 // FIXME: For sure it is not GTK look but it is better than nothing.
1359 // Show me correct look and I will immediatelly make it better (ABX)
1360 wxRect rect
= rectTotal
;
1362 wxColour col1
, col2
;
1366 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1367 col2
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1371 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1372 col2
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1375 dc
.SetPen(*wxTRANSPARENT_PEN
);
1376 dc
.SetBrush(wxBrush(col1
, wxSOLID
));
1377 dc
.DrawRectangle(rect
);
1379 dc
.SetBrush(wxBrush(col2
, wxSOLID
));
1380 dc
.DrawRectangle(rect
);
1383 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1384 const wxRect
& rectTotal
,
1387 wxRect rect
= rectTotal
;
1388 DrawAntiRaisedBorder(dc
, &rect
);
1390 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1391 dc
.SetPen(wxPen(col
, 0, wxSOLID
));
1392 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1395 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1396 //else: it is SHADOW_IN, leave as is
1398 dc
.SetPen(*wxTRANSPARENT_PEN
);
1399 dc
.SetBrush(wxBrush(col
, wxSOLID
));
1400 dc
.DrawRectangle(rect
);
1403 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1405 wxRect rect
= rectTotal
;
1406 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1407 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1409 dc
.SetPen(*wxTRANSPARENT_PEN
);
1410 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), wxSOLID
));
1411 dc
.DrawRectangle(rect
);
1414 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1420 xRight
= rect
.GetRight(),
1421 yBottom
= rect
.GetBottom();
1423 wxCoord yMid
= (y
+ yBottom
) / 2;
1425 // this looks ugly when the background colour of the control is not the
1426 // same ours - radiobox is not transparent as it should be
1428 // first fill the middle: as FloodFill() is not implemented on all
1429 // platforms, this is the only thing to do
1430 wxColour colBg
= flags
& wxCONTROL_CURRENT
1431 ? wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
)
1432 : wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1433 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
1434 dc
.SetPen(*wxTRANSPARENT_PEN
);
1435 dc
.DrawRectangle(rect
);
1438 // then draw the upper half
1439 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1440 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1441 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1444 if ( flags
& wxCONTROL_CHECKED
)
1445 dc
.SetPen(m_penBlack
);
1446 else if ( flags
& wxCONTROL_PRESSED
)
1447 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1448 else // unchecked and unpressed
1452 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1454 // and then the lower one
1455 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1456 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1457 if ( !(flags
& wxCONTROL_CHECKED
) )
1458 dc
.SetPen(m_penDarkGrey
);
1459 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1461 if ( !(flags
& wxCONTROL_CHECKED
) )
1462 drawIt
= true; // with the same pen
1463 else if ( flags
& wxCONTROL_PRESSED
)
1465 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1468 else // checked and unpressed
1472 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1475 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1481 wxCoord xMid
= (x1
+ x2
) / 2;
1482 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1483 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1486 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1492 wxCoord xMid
= (x1
+ x2
) / 2;
1493 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1494 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1497 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1499 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1501 // init the bitmaps once only
1503 wxSize size
= GetCheckBitmapSize();
1504 rect
.width
= size
.x
;
1505 rect
.height
= size
.y
;
1506 for ( int i
= 0; i
< 2; i
++ )
1508 for ( int j
= 0; j
< 3; j
++ )
1509 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1515 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1516 DrawCheckBitmap(dc
, rect
);
1519 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1520 DrawUncheckBitmap(dc
, rect
, false);
1522 // normal undeterminated
1523 dc
.SelectObject(m_bitmapsCheckbox
[0][2]);
1524 DrawUndeterminedBitmap(dc
, rect
, false);
1527 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1529 // pressed unchecked
1530 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1531 DrawUncheckBitmap(dc
, rect
, true);
1533 // pressed undeterminated
1534 dc
.SelectObject(m_bitmapsCheckbox
[1][2]);
1535 DrawUndeterminedBitmap(dc
, rect
, true);
1538 int row
= flags
& wxCONTROL_PRESSED
1541 int col
= flags
& wxCONTROL_CHECKED
1543 : ( flags
& wxCONTROL_UNDETERMINED
1547 return m_bitmapsCheckbox
[row
][col
];
1550 wxBitmap
wxGTKRenderer::GetLineWrapBitmap() const
1552 if ( !m_bmpLineWrap
.Ok() )
1554 // the line wrap bitmap as used by GTK+
1555 #define line_wrap_width 6
1556 #define line_wrap_height 9
1557 static const char line_wrap_bits
[] =
1559 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1562 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1563 if ( !bmpLineWrap
.Ok() )
1565 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1569 wxConstCast(this, wxGTKRenderer
)->m_bmpLineWrap
= bmpLineWrap
;
1573 return m_bmpLineWrap
;
1576 void wxGTKRenderer::DrawCheckButton(wxDC
& dc
,
1577 const wxString
& label
,
1578 const wxBitmap
& bitmapOrig
,
1579 const wxRect
& rectTotal
,
1585 if ( bitmapOrig
.Ok() )
1587 bitmap
= bitmapOrig
;
1591 bitmap
= GetCheckBitmap(flags
);
1594 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1595 flags
, align
, indexAccel
);
1598 void wxGTKRenderer::DoDrawCheckOrRadioBitmap(wxDC
& dc
,
1599 const wxString
& label
,
1600 const wxBitmap
& bitmap
,
1601 const wxRect
& rectTotal
,
1606 wxRect rect
= rectTotal
;
1608 if ( flags
& wxCONTROL_FOCUSED
)
1610 // draw the focus border around everything
1611 DrawRect(dc
, &rect
, m_penBlack
);
1615 // the border does not offset the string under GTK
1619 // calculate the position of the bitmap and of the label
1621 yBmp
= rect
.y
+ (rect
.height
- bitmap
.GetHeight()) / 2;
1624 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
1625 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
1627 if ( align
== wxALIGN_RIGHT
)
1629 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
1630 rectLabel
.x
= rect
.x
+ 2;
1631 rectLabel
.SetRight(xBmp
);
1633 else // normal (checkbox to the left of the text) case
1636 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 4;
1637 rectLabel
.SetRight(rect
.GetRight());
1640 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
1642 DrawLabel(dc
, label
, rectLabel
, flags
,
1643 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1646 void wxGTKRenderer::DrawRadioButton(wxDC
& dc
,
1647 const wxString
& label
,
1648 const wxBitmap
& bitmapOrig
,
1649 const wxRect
& rectTotal
,
1655 if ( bitmapOrig
.Ok() )
1657 bitmap
= bitmapOrig
;
1662 wxSize size
= GetRadioBitmapSize();
1663 rect
.width
= size
.x
;
1664 rect
.height
= size
.y
;
1665 bitmap
.Create(rect
.width
, rect
.height
);
1667 dc
.SelectObject(bitmap
);
1668 dc
.SetBackground(*wxLIGHT_GREY_BRUSH
);
1670 DrawRadioBitmap(dc
, rect
, flags
);
1672 // must unselect the bitmap before setting a mask for it because of the
1674 dc
.SelectObject(wxNullBitmap
);
1675 bitmap
.SetMask(new wxMask(bitmap
, *wxLIGHT_GREY
));
1678 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1679 flags
, align
, indexAccel
);
1682 void wxGTKRenderer::DrawToolBarButton(wxDC
& dc
,
1683 const wxString
& label
,
1684 const wxBitmap
& bitmap
,
1685 const wxRect
& rectOrig
,
1687 long WXUNUSED(style
),
1690 // we don't draw the separators at all
1691 if ( !label
.empty() || bitmap
.Ok() )
1693 wxRect rect
= rectOrig
;
1694 rect
.Deflate(BORDER_THICKNESS
);
1696 if ( flags
& wxCONTROL_PRESSED
)
1698 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
, &rect
);
1700 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), rect
);
1702 else if ( flags
& wxCONTROL_CURRENT
)
1704 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rect
);
1706 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rect
);
1709 if(tbarStyle
& wxTB_TEXT
)
1711 if(tbarStyle
& wxTB_HORIZONTAL
)
1713 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1717 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
1722 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
1723 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
1724 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
1729 // ----------------------------------------------------------------------------
1731 // ----------------------------------------------------------------------------
1733 wxRect
wxGTKRenderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
1734 const wxRect
& rect
) const
1736 wxRect rectTotal
= rect
;
1737 rectTotal
.Inflate(2*BORDER_THICKNESS
);
1741 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1743 wxCoord
*extraSpaceBeyond
) const
1745 wxRect rectText
= rect
;
1746 rectText
.Deflate(2*BORDER_THICKNESS
);
1748 if ( text
->WrapLines() )
1750 // leave enough for the line wrap bitmap indicator
1751 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1753 rectText
.width
-= widthMark
;
1755 if ( extraSpaceBeyond
)
1756 *extraSpaceBeyond
= widthMark
;
1762 void wxGTKRenderer::DrawTextLine(wxDC
& dc
,
1763 const wxString
& text
,
1769 // TODO: GTK+ draws selection even for unfocused controls, just with
1770 // different colours
1771 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
1774 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1776 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1778 // for a mono bitmap he colours it appears in depends on the current text
1779 // colours, so set them correctly
1781 if ( bmpLineWrap
.GetDepth() == 1 )
1783 colFgOld
= dc
.GetTextForeground();
1785 // FIXME: I wonder what should we do if the background is black too?
1786 dc
.SetTextForeground(*wxBLACK
);
1789 dc
.DrawBitmap(bmpLineWrap
,
1790 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1792 if ( colFgOld
.Ok() )
1794 // restore old colour
1795 dc
.SetTextForeground(colFgOld
);
1799 // ----------------------------------------------------------------------------
1801 // ----------------------------------------------------------------------------
1803 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1804 const wxRect
& rectOrig
,
1806 const wxString
& label
,
1807 const wxBitmap
& bitmap
,
1811 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1812 #define REVERSE_FOR_VERTICAL(X,Y) \
1813 SELECT_FOR_VERTICAL(X,Y) \
1815 SELECT_FOR_VERTICAL(Y,X)
1817 wxRect rect
= rectOrig
;
1819 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1821 // the current tab is drawn indented (to the top for default case) and
1822 // bigger than the other ones
1823 const wxSize indent
= GetTabIndent();
1824 if ( flags
& wxCONTROL_SELECTED
)
1826 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1827 SELECT_FOR_VERTICAL( 0, indent
.y
));
1831 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1838 rect
.height
+= indent
.y
;
1845 rect
.width
+= indent
.x
;
1850 // selected tab has different colour
1851 wxColour col
= flags
& wxCONTROL_SELECTED
1852 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1853 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1854 DoDrawBackground(dc
, col
, rect
);
1856 if ( flags
& wxCONTROL_FOCUSED
)
1858 // draw the focus rect
1859 wxRect rectBorder
= rect
;
1860 rectBorder
.Deflate(4, 3);
1861 if ( dir
== wxBOTTOM
)
1862 rectBorder
.Offset(0, -1);
1863 if ( dir
== wxRIGHT
)
1864 rectBorder
.Offset(-1, 0);
1866 DrawRect(dc
, &rectBorder
, m_penBlack
);
1869 // draw the text, image and the focus around them (if necessary)
1870 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1871 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1873 rectLabel
.Deflate(1, 1);
1876 // draw it horizontally into memory and rotate for screen
1878 wxBitmap bitmapRotated
,
1879 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1880 rectLabel
.y
+ rectLabel
.height
);
1881 dcMem
.SelectObject(bitmapMem
);
1882 dcMem
.SetBackground(dc
.GetBackground());
1883 dcMem
.SetFont(dc
.GetFont());
1884 dcMem
.SetTextForeground(dc
.GetTextForeground());
1886 bitmapRotated
= wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) );
1887 dcMem
.DrawLabel(label
, bitmapRotated
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1888 dcMem
.SelectObject(wxNullBitmap
);
1889 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1890 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
1891 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1895 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1898 // now draw the tab itself
1899 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1900 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1901 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1902 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1908 // left orientation looks like top but IsVertical makes x and y reversed
1910 // top is not vertical so use coordinates in written order
1911 dc
.SetPen(m_penHighlight
);
1912 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1913 REVERSE_FOR_VERTICAL(x
, y
));
1914 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
),
1915 REVERSE_FOR_VERTICAL(x2
, y
));
1917 dc
.SetPen(m_penBlack
);
1918 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1919 REVERSE_FOR_VERTICAL(x2
, y
));
1921 dc
.SetPen(m_penDarkGrey
);
1922 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1923 REVERSE_FOR_VERTICAL(x2
- 1, y
+ 1));
1925 if ( flags
& wxCONTROL_SELECTED
)
1927 dc
.SetPen(m_penLightGrey
);
1929 // overwrite the part of the border below this tab
1930 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1931 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1933 // and the shadow of the tab to the left of us
1934 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ 2),
1935 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1940 // right orientation looks like bottom but IsVertical makes x and y reversed
1942 // bottom is not vertical so use coordinates in written order
1943 dc
.SetPen(m_penHighlight
);
1945 // we need to continue one pixel further to overwrite the corner of
1946 // the border for the selected tab
1947 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
1948 REVERSE_FOR_VERTICAL(x
, y2
));
1950 // it doesn't work like this (TODO: implement it properly)
1952 // erase the corner of the tab to the right
1953 dc
.SetPen(m_penLightGrey
);
1954 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1955 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 2));
1956 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 1));
1959 dc
.SetPen(m_penBlack
);
1960 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
),
1961 REVERSE_FOR_VERTICAL(x2
, y2
));
1962 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
1963 REVERSE_FOR_VERTICAL(x2
, y2
));
1965 dc
.SetPen(m_penDarkGrey
);
1966 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 2, y2
- 1),
1967 REVERSE_FOR_VERTICAL(x2
- 1, y2
- 1));
1968 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
1969 REVERSE_FOR_VERTICAL(x2
- 1, y2
));
1971 if ( flags
& wxCONTROL_SELECTED
)
1973 dc
.SetPen(m_penLightGrey
);
1975 // overwrite the part of the (double!) border above this tab
1976 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
1977 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
1978 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
1979 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1981 // and the shadow of the tab to the left of us
1982 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- 1),
1983 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
1989 // ----------------------------------------------------------------------------
1991 // ----------------------------------------------------------------------------
1993 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1995 wxOrientation orient
) const
1997 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
2001 wxRect rectShaft
= GetSliderShaftRect(rect
, lenThumb
, orient
);
2002 if ( orient
== wxHORIZONTAL
)
2004 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
2005 size
.y
= rectShaft
.height
;
2009 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
2010 size
.x
= rectShaft
.width
;
2016 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
2017 int WXUNUSED(lenThumb
),
2018 wxOrientation
WXUNUSED(orient
),
2019 long WXUNUSED(style
)) const
2021 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
2024 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
2025 const wxRect
& rectOrig
,
2026 int WXUNUSED(lenThumb
),
2027 wxOrientation
WXUNUSED(orient
),
2029 long WXUNUSED(style
),
2032 wxRect rect
= rectOrig
;
2034 // draw the border first
2035 if ( flags
& wxCONTROL_FOCUSED
)
2037 DrawRect(dc
, &rect
, m_penBlack
);
2038 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
2040 else // not focused, normal
2042 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
2043 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
2046 // and the background
2047 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
2053 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
2054 const wxRect
& rectOrig
,
2055 wxOrientation orient
,
2056 int WXUNUSED(flags
),
2057 long WXUNUSED(style
))
2059 // draw the thumb border
2060 wxRect rect
= rectOrig
;
2061 DrawAntiRaisedBorder(dc
, &rect
);
2063 // draw the handle in the middle
2064 if ( orient
== wxVERTICAL
)
2066 rect
.height
= 2*BORDER_THICKNESS
;
2067 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2071 rect
.width
= 2*BORDER_THICKNESS
;
2072 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2075 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
2078 // ----------------------------------------------------------------------------
2080 // ----------------------------------------------------------------------------
2082 // wxGTKMenuGeometryInfo: the wxMenuGeometryInfo used by wxGTKRenderer
2083 class WXDLLEXPORT wxGTKMenuGeometryInfo
: public wxMenuGeometryInfo
2086 virtual wxSize
GetSize() const { return m_size
; }
2088 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2089 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2091 wxCoord
GetItemHeight() const { return m_heightItem
; }
2094 // the total size of the menu
2097 // the offset of the start of the menu item label
2100 // the offset of the start of the accel label
2103 // the height of a normal (not separator) item
2104 wxCoord m_heightItem
;
2106 friend wxMenuGeometryInfo
*
2107 wxGTKRenderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2110 // FIXME: all constants are hardcoded but shouldn't be
2111 static const wxCoord MENU_LEFT_MARGIN
= 9;
2112 static const wxCoord MENU_RIGHT_MARGIN
= 6;
2114 static const wxCoord MENU_HORZ_MARGIN
= 6;
2115 static const wxCoord MENU_VERT_MARGIN
= 3;
2117 // the margin around bitmap/check marks (on each side)
2118 static const wxCoord MENU_BMP_MARGIN
= 2;
2120 // the margin between the labels and accel strings
2121 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2123 // the separator height in pixels: in fact, strangely enough, the real height
2124 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2126 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2128 // the size of the standard checkmark bitmap
2129 static const wxCoord MENU_CHECK_SIZE
= 9;
2131 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
2133 const wxString
& label
,
2137 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
);
2140 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
2142 const wxMenuGeometryInfo
& gi
,
2143 const wxString
& label
,
2144 const wxString
& accel
,
2145 const wxBitmap
& bitmap
,
2149 const wxGTKMenuGeometryInfo
& geomInfo
= (const wxGTKMenuGeometryInfo
&)gi
;
2154 rect
.width
= geomInfo
.GetSize().x
;
2155 rect
.height
= geomInfo
.GetItemHeight();
2157 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
, accel
, bitmap
, &geomInfo
);
2160 void wxGTKRenderer::DoDrawMenuItem(wxDC
& dc
,
2161 const wxRect
& rectOrig
,
2162 const wxString
& label
,
2165 const wxString
& accel
,
2166 const wxBitmap
& bitmap
,
2167 const wxGTKMenuGeometryInfo
*geometryInfo
)
2169 wxRect rect
= rectOrig
;
2171 // draw the selected item specially
2172 if ( flags
& wxCONTROL_SELECTED
)
2175 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
2177 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rectIn
);
2180 rect
.Deflate(MENU_HORZ_MARGIN
, MENU_VERT_MARGIN
);
2182 // draw the bitmap: use the bitmap provided or the standard checkmark for
2183 // the checkable items
2186 wxBitmap bmp
= bitmap
;
2187 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKABLE
) )
2189 bmp
= GetCheckBitmap(flags
);
2194 rect
.SetRight(geometryInfo
->GetLabelOffset());
2195 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2198 //else: menubar items don't have bitmaps
2203 rect
.x
= geometryInfo
->GetLabelOffset();
2204 rect
.SetRight(geometryInfo
->GetAccelOffset());
2207 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2209 // draw the accel string
2210 if ( !accel
.empty() )
2212 // menubar items shouldn't have them
2213 wxCHECK_RET( geometryInfo
, _T("accel strings only valid for menus") );
2215 rect
.x
= geometryInfo
->GetAccelOffset();
2216 rect
.SetRight(geometryInfo
->GetSize().x
);
2218 // NB: no accel index here
2219 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2222 // draw the submenu indicator
2223 if ( flags
& wxCONTROL_ISSUBMENU
)
2225 wxCHECK_RET( geometryInfo
, _T("wxCONTROL_ISSUBMENU only valid for menus") );
2227 rect
.x
= geometryInfo
->GetSize().x
- MENU_RIGHT_MARGIN
;
2228 rect
.width
= MENU_RIGHT_MARGIN
;
2230 DrawArrow(dc
, wxRIGHT
, rect
, flags
);
2234 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
2236 const wxMenuGeometryInfo
& geomInfo
)
2238 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2241 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2243 wxSize size
= sizeText
;
2245 // TODO: make this configurable
2246 size
.x
+= 2*MENU_HORZ_MARGIN
;
2247 size
.y
+= 2*MENU_VERT_MARGIN
;
2252 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
2253 const wxMenu
& menu
) const
2255 // prepare the dc: for now we draw all the items with the system font
2257 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2259 // the height of a normal item
2260 wxCoord heightText
= dc
.GetCharHeight();
2265 // the max length of label and accel strings: the menu width is the sum of
2266 // them, even if they're for different items (as the accels should be
2269 // the max length of the bitmap is never 0 as Windows always leaves enough
2270 // space for a check mark indicator
2271 wxCoord widthLabelMax
= 0,
2273 widthBmpMax
= MENU_LEFT_MARGIN
;
2275 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
2277 node
= node
->GetNext() )
2279 // height of this item
2282 wxMenuItem
*item
= node
->GetData();
2283 if ( item
->IsSeparator() )
2285 h
= MENU_SEPARATOR_HEIGHT
;
2287 else // not separator
2292 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2293 if ( widthLabel
> widthLabelMax
)
2295 widthLabelMax
= widthLabel
;
2299 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2300 if ( widthAccel
> widthAccelMax
)
2302 widthAccelMax
= widthAccel
;
2305 const wxBitmap
& bmp
= item
->GetBitmap();
2308 wxCoord widthBmp
= bmp
.GetWidth();
2309 if ( widthBmp
> widthBmpMax
)
2310 widthBmpMax
= widthBmp
;
2312 //else if ( item->IsCheckable() ): no need to check for this as
2313 // MENU_LEFT_MARGIN is big enough to show the check mark
2316 h
+= 2*MENU_VERT_MARGIN
;
2318 // remember the item position and height
2319 item
->SetGeometry(height
, h
);
2324 // bundle the metrics into a struct and return it
2325 wxGTKMenuGeometryInfo
*gi
= new wxGTKMenuGeometryInfo
;
2327 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2328 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2329 if ( widthAccelMax
> 0 )
2331 // if we actually have any accesl, add a margin
2332 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2335 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2337 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2338 gi
->m_size
.y
= height
;
2343 // ----------------------------------------------------------------------------
2345 // ----------------------------------------------------------------------------
2348 wxGTKRenderer::GetStatusBarBorders(wxCoord
* WXUNUSED(borderBetweenFields
)) const
2353 void wxGTKRenderer::DrawStatusField(wxDC
& WXUNUSED(dc
),
2354 const wxRect
& WXUNUSED(rect
),
2355 const wxString
& WXUNUSED(label
),
2356 int WXUNUSED(flags
), int WXUNUSED(style
))
2360 // ----------------------------------------------------------------------------
2362 // ----------------------------------------------------------------------------
2364 void wxGTKRenderer::InitComboBitmaps()
2366 wxSize sizeArrow
= m_sizeScrollbarArrow
;
2372 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
2374 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
2377 static const int comboButtonFlags
[ComboState_Max
] =
2385 wxRect
rect(sizeArrow
);
2388 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
2390 int flags
= comboButtonFlags
[n
];
2392 dc
.SelectObject(m_bitmapsCombo
[n
]);
2393 DoDrawBackground(dc
, GetBackgroundColour(flags
), rect
);
2394 DrawArrow(dc
, wxDOWN
, rect
, flags
);
2398 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
2400 wxBitmap
*bmpPressed
,
2401 wxBitmap
*bmpDisabled
)
2403 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
2409 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
2411 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
2413 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
2415 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
2418 // ----------------------------------------------------------------------------
2420 // ----------------------------------------------------------------------------
2422 void wxGTKRenderer::DoDrawBackground(wxDC
& dc
,
2423 const wxColour
& col
,
2425 wxWindow
* WXUNUSED(window
))
2427 wxBrush
brush(col
, wxSOLID
);
2429 dc
.SetPen(*wxTRANSPARENT_PEN
);
2430 dc
.DrawRectangle(rect
);
2433 void wxGTKRenderer::DrawBackground(wxDC
& dc
,
2434 const wxColour
& col
,
2439 wxColour colBg
= col
.Ok() ? col
: GetBackgroundColour(flags
);
2440 DoDrawBackground(dc
, colBg
, rect
, window
);
2443 // ----------------------------------------------------------------------------
2445 // ----------------------------------------------------------------------------
2447 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
2451 static const wxDirection sides
[] =
2453 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
2456 wxRect rect1
, rect2
, rectInner
;
2462 rectInner
.Inflate(-2);
2464 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
2466 // find the side not to draw and also adjust the rectangles to compensate
2468 wxDirection sideToOmit
;
2472 sideToOmit
= wxDOWN
;
2474 rectInner
.height
+= 1;
2482 rectInner
.height
+= 1;
2486 sideToOmit
= wxRIGHT
;
2488 rectInner
.width
+= 1;
2492 sideToOmit
= wxLEFT
;
2496 rectInner
.width
+= 1;
2500 wxFAIL_MSG(_T("unknown arrow direction"));
2504 // the outer rect first
2506 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2508 wxDirection side
= sides
[n
];
2509 if ( side
== sideToOmit
)
2512 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
2515 // and then the inner one
2516 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2518 wxDirection side
= sides
[n
];
2519 if ( side
== sideToOmit
)
2522 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
2528 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
2530 const wxRect
& rectArrow
,
2533 // first of all, draw the border around it - but we don't want the border
2534 // on the side opposite to the arrow point
2535 wxRect rect
= rectArrow
;
2536 DrawArrowBorder(dc
, &rect
, dir
);
2538 // then the arrow itself
2539 DrawArrow(dc
, dir
, rect
, flags
);
2542 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
2543 // these people are just crazy :-(
2544 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2557 wxPoint ptArrow
[Point_Max
];
2559 wxColour colInside
= GetBackgroundColour(flags
);
2561 if ( flags
& wxCONTROL_DISABLED
)
2563 penShadow
[0] = m_penDarkGrey
;
2564 penShadow
[1] = m_penDarkGrey
;
2565 penShadow
[2] = wxNullPen
;
2566 penShadow
[3] = wxNullPen
;
2568 else if ( flags
& wxCONTROL_PRESSED
)
2570 penShadow
[0] = m_penDarkGrey
;
2571 penShadow
[1] = m_penHighlight
;
2572 penShadow
[2] = wxNullPen
;
2573 penShadow
[3] = m_penBlack
;
2575 else // normal arrow
2577 penShadow
[0] = m_penHighlight
;
2578 penShadow
[1] = m_penBlack
;
2579 penShadow
[2] = m_penDarkGrey
;
2580 penShadow
[3] = wxNullPen
;
2584 if ( dir
== wxUP
|| dir
== wxDOWN
)
2587 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2591 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2594 // draw the arrow interior
2595 dc
.SetPen(*wxTRANSPARENT_PEN
);
2596 dc
.SetBrush(wxBrush(colInside
, wxSOLID
));
2601 ptArrow
[Point_First
].x
= rect
.GetLeft();
2602 ptArrow
[Point_First
].y
= rect
.GetBottom();
2603 ptArrow
[Point_Second
].x
= middle
;
2604 ptArrow
[Point_Second
].y
= rect
.GetTop();
2605 ptArrow
[Point_Third
].x
= rect
.GetRight();
2606 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2610 ptArrow
[Point_First
] = rect
.GetPosition();
2611 ptArrow
[Point_Second
].x
= middle
;
2612 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2613 ptArrow
[Point_Third
].x
= rect
.GetRight();
2614 ptArrow
[Point_Third
].y
= rect
.GetTop();
2618 ptArrow
[Point_First
].x
= rect
.GetRight();
2619 ptArrow
[Point_First
].y
= rect
.GetTop();
2620 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2621 ptArrow
[Point_Second
].y
= middle
;
2622 ptArrow
[Point_Third
].x
= rect
.GetRight();
2623 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2627 ptArrow
[Point_First
] = rect
.GetPosition();
2628 ptArrow
[Point_Second
].x
= rect
.GetRight();
2629 ptArrow
[Point_Second
].y
= middle
;
2630 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2631 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2635 wxFAIL_MSG(_T("unknown arrow direction"));
2638 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2640 // draw the arrow border
2641 dc
.SetPen(penShadow
[0]);
2645 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2646 dc
.DrawPoint(ptArrow
[Point_First
]);
2647 if ( penShadow
[3].Ok() )
2649 dc
.SetPen(penShadow
[3]);
2650 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2651 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2653 dc
.SetPen(penShadow
[1]);
2654 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2655 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2656 dc
.DrawPoint(ptArrow
[Point_Third
]);
2657 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2658 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2659 if ( penShadow
[2].Ok() )
2661 dc
.SetPen(penShadow
[2]);
2662 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2663 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2664 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2665 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2670 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2671 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2672 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2673 if ( penShadow
[2].Ok() )
2675 dc
.SetPen(penShadow
[2]);
2676 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2677 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2679 dc
.SetPen(penShadow
[1]);
2680 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2681 dc
.DrawPoint(ptArrow
[Point_Third
]);
2685 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2686 dc
.DrawPoint(ptArrow
[Point_First
]);
2687 if ( penShadow
[2].Ok() )
2689 dc
.SetPen(penShadow
[2]);
2690 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2691 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2692 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2693 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2695 dc
.SetPen(penShadow
[1]);
2696 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2697 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2698 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2699 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2703 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2704 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2705 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2706 dc
.SetPen(penShadow
[1]);
2707 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2708 dc
.DrawPoint(ptArrow
[Point_Third
]);
2712 wxFAIL_MSG(_T("unknown arrow direction"));
2717 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2719 wxOrientation orient
)
2721 if ( orient
== wxVERTICAL
)
2723 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2725 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2727 rect
->Inflate(-1, 0);
2729 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2731 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2733 rect
->Inflate(-1, 0);
2737 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2739 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2741 rect
->Inflate(0, -1);
2743 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2745 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2747 rect
->Inflate(0, -1);
2751 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2752 wxOrientation orient
,
2756 // the thumb is never pressed never has focus border under GTK and the
2757 // scrollbar background never changes at all
2758 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2760 // we don't want the border in the direction of the scrollbar movement
2761 wxRect rectThumb
= rect
;
2762 DrawThumbBorder(dc
, &rectThumb
, orient
);
2764 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2765 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2768 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2769 wxOrientation orient
,
2771 int WXUNUSED(flags
))
2773 wxRect rectBar
= rect
;
2774 DrawThumbBorder(dc
, &rectBar
, orient
);
2775 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2778 void wxGTKRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2780 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2783 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2784 wxScrollBar::Element elem
,
2787 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2788 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2790 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2792 elem
= wxScrollBar::Element_Bar_2
;
2795 return StandardGetScrollbarRect(scrollbar
, elem
,
2797 GetScrollbarArrowSize(scrollbar
));
2800 wxCoord
wxGTKRenderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
2802 return StandardScrollBarSize(scrollbar
, GetScrollbarArrowSize(scrollbar
));
2805 wxHitTest
wxGTKRenderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
2806 const wxPoint
& pt
) const
2808 return StandardHitTestScrollbar(scrollbar
, pt
,
2809 GetScrollbarArrowSize(scrollbar
));
2812 wxCoord
wxGTKRenderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
2815 return StandardScrollbarToPixel(scrollbar
, thumbPos
,
2816 GetScrollbarArrowSize(scrollbar
));
2819 int wxGTKRenderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
2822 return StandardPixelToScrollbar(scrollbar
, coord
,
2823 GetScrollbarArrowSize(scrollbar
));
2826 // ----------------------------------------------------------------------------
2828 // ----------------------------------------------------------------------------
2830 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2833 if ( wxDynamicCast(window
, wxBitmapButton
) )
2838 #endif // wxUSE_BMPBUTTON
2839 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
2842 || wxDynamicCast(window
, wxButton
)
2843 # endif // wxUSE_BUTTON
2844 # if wxUSE_TOGGLEBTN
2845 || wxDynamicCast(window
, wxToggleButton
)
2846 # endif // wxUSE_TOGGLEBTN
2849 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2851 // TODO: this is ad hoc...
2852 size
->x
+= 3*window
->GetCharWidth();
2853 wxCoord minBtnHeight
= 18;
2854 if ( size
->y
< minBtnHeight
)
2855 size
->y
= minBtnHeight
;
2857 // button border width
2861 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
2862 if ( wxDynamicCast(window
, wxScrollBar
) )
2864 // we only set the width of vert scrollbars and height of the
2866 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2867 size
->y
= m_sizeScrollbarArrow
.x
;
2869 size
->x
= m_sizeScrollbarArrow
.x
;
2873 // take into account the border width
2874 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
2875 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
2876 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
2880 // ----------------------------------------------------------------------------
2881 // top level windows
2882 // ----------------------------------------------------------------------------
2884 void wxGTKRenderer::DrawFrameTitleBar(wxDC
& WXUNUSED(dc
),
2885 const wxRect
& WXUNUSED(rect
),
2886 const wxString
& WXUNUSED(title
),
2887 const wxIcon
& WXUNUSED(icon
),
2888 int WXUNUSED(flags
),
2889 int WXUNUSED(specialButton
),
2890 int WXUNUSED(specialButtonFlag
))
2894 void wxGTKRenderer::DrawFrameBorder(wxDC
& WXUNUSED(dc
),
2895 const wxRect
& WXUNUSED(rect
),
2896 int WXUNUSED(flags
))
2900 void wxGTKRenderer::DrawFrameBackground(wxDC
& WXUNUSED(dc
),
2901 const wxRect
& WXUNUSED(rect
),
2902 int WXUNUSED(flags
))
2906 void wxGTKRenderer::DrawFrameTitle(wxDC
& WXUNUSED(dc
),
2907 const wxRect
& WXUNUSED(rect
),
2908 const wxString
& WXUNUSED(title
),
2909 int WXUNUSED(flags
))
2913 void wxGTKRenderer::DrawFrameIcon(wxDC
& WXUNUSED(dc
),
2914 const wxRect
& WXUNUSED(rect
),
2915 const wxIcon
& WXUNUSED(icon
),
2916 int WXUNUSED(flags
))
2920 void wxGTKRenderer::DrawFrameButton(wxDC
& WXUNUSED(dc
),
2921 wxCoord
WXUNUSED(x
),
2922 wxCoord
WXUNUSED(y
),
2923 int WXUNUSED(button
),
2924 int WXUNUSED(flags
))
2929 wxGTKRenderer::GetFrameClientArea(const wxRect
& rect
,
2930 int WXUNUSED(flags
)) const
2936 wxGTKRenderer::GetFrameTotalSize(const wxSize
& clientSize
,
2937 int WXUNUSED(flags
)) const
2942 wxSize
wxGTKRenderer::GetFrameMinSize(int WXUNUSED(flags
)) const
2947 wxSize
wxGTKRenderer::GetFrameIconSize() const
2949 return wxSize(wxDefaultCoord
, wxDefaultCoord
);
2953 wxGTKRenderer::HitTestFrame(const wxRect
& WXUNUSED(rect
),
2954 const wxPoint
& WXUNUSED(pt
),
2955 int WXUNUSED(flags
)) const
2957 return wxHT_TOPLEVEL_CLIENT_AREA
;
2961 // ----------------------------------------------------------------------------
2963 // ----------------------------------------------------------------------------
2965 /* Copyright (c) Julian Smart */
2966 static const char *error_xpm
[] = {
2967 /* columns rows colors chars-per-pixel */
2981 " ................. ",
2982 " ................... ",
2983 " ....................... ",
2984 " ......................... ",
2985 " ........................... ",
2986 " ...........................X ",
2987 " .............................X ",
2988 " ............................... ",
2989 " ...............................X ",
2990 " .................................X ",
2991 " .................................X ",
2992 " .................................XX ",
2993 " ...ooooooooooooooooooooooooooo...XX ",
2994 " ....ooooooooooooooooooooooooooo....X ",
2995 " ....ooooooooooooooooooooooooooo....X ",
2996 " ....ooooooooooooooooooooooooooo....XX ",
2997 " ....ooooooooooooooooooooooooooo....XX ",
2998 " ....ooooooooooooooooooooooooooo....XX ",
2999 " ...ooooooooooooooooooooooooooo...XXX ",
3000 " ...ooooooooooooooooooooooooooo...XXX ",
3001 " .................................XX ",
3002 " .................................XX ",
3003 " ...............................XXX ",
3004 " ...............................XXX ",
3005 " .............................XXX ",
3006 " ...........................XXXX ",
3007 " ...........................XXX ",
3008 " .........................XXX ",
3009 " .......................XXXX ",
3010 " X...................XXXXX ",
3011 " X.................XXXXX ",
3012 " X.............XXXXX ",
3013 " XXXX.....XXXXXXXX ",
3024 /* Copyright (c) Julian Smart */
3025 static const char *info_xpm
[] = {
3026 /* columns rows colors chars-per-pixel */
3050 " .XXXOXXXXXXXoo. ",
3051 " .XOOXXX+XXXXXo. ",
3052 " .XOOOXX+++XXXXoo. ",
3053 " .XOOXXX+++XXXXXo. ",
3054 " .XOOOXXX+++XXXXXXo. ",
3055 " .XOOXXXX+++XXXXXXo. ",
3056 " .XXXXXXX+++XXXXXXX. ",
3057 " .XXXXXXX+++XXXXXXo. ",
3058 " .XXXXXXX+++XXXXXoo. ",
3059 " .XXXXXX+++XXXXXo. ",
3060 " .XXXXXXX+XXXXXXo. ",
3061 " .XXXXXXXXXXXXo. ",
3062 " .XXXXX+++XXXoo. ",
3088 /* Copyright (c) Julian Smart */
3089 static const char *warning_xpm
[] = {
3090 /* columns rows colors chars-per-pixel */
3120 " ..XXXXO@#XXX... ",
3121 " ...XXXXO@#XXXX.. ",
3122 " ..XXXXXO@#XXXX... ",
3123 " ...XXXXXo@OXXXXX.. ",
3124 " ...XXXXXXo@OXXXXXX.. ",
3125 " ..XXXXXXX$@OXXXXXX... ",
3126 " ...XXXXXXXX@XXXXXXXX.. ",
3127 " ...XXXXXXXXXXXXXXXXXX... ",
3128 " ..XXXXXXXXXXOXXXXXXXXX.. ",
3129 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
3130 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
3131 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
3132 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
3133 " .............................. ",
3134 " .............................. ",
3152 /* Copyright (c) Julian Smart */
3153 static const char *question_xpm
[] = {
3154 /* columns rows colors chars-per-pixel */
3184 " ..XXXXoooooXXXO+ ",
3185 " ..XXooooooooooooX@.. ",
3186 " ..XoooooooooooooooXX#. ",
3187 " $%XoooooooooooooooooXX#. ",
3188 " &.XoooooooXXXXXXooooooXX.. ",
3189 " .XooooooXX.$...$XXoooooX*. ",
3190 " $.XoooooX%.$ .*oooooo=.. ",
3191 " .XooooooX.. -.XoooooX.. ",
3192 " .XoooooX..+ .XoooooX;. ",
3193 " ...XXXX..: .XoooooX;. ",
3194 " ........ >.XoooooX;. ",
3228 wxBitmap
wxGTKArtProvider::CreateBitmap(const wxArtID
& id
,
3229 const wxArtClient
& WXUNUSED(client
),
3230 const wxSize
& WXUNUSED(size
))
3232 if ( id
== wxART_INFORMATION
)
3233 return wxBitmap(info_xpm
);
3234 if ( id
== wxART_ERROR
)
3235 return wxBitmap(error_xpm
);
3236 if ( id
== wxART_WARNING
)
3237 return wxBitmap(warning_xpm
);
3238 if ( id
== wxART_QUESTION
)
3239 return wxBitmap(question_xpm
);
3240 return wxNullBitmap
;
3244 // ============================================================================
3246 // ============================================================================
3248 // ----------------------------------------------------------------------------
3249 // wxGTKInputHandler
3250 // ----------------------------------------------------------------------------
3252 wxGTKInputHandler::wxGTKInputHandler(wxGTKRenderer
*renderer
)
3254 m_renderer
= renderer
;
3257 bool wxGTKInputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
3258 const wxKeyEvent
& WXUNUSED(event
),
3259 bool WXUNUSED(pressed
))
3264 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
3265 const wxMouseEvent
& event
)
3267 // clicking on the control gives it focus
3268 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
3270 control
->GetInputWindow()->SetFocus();
3278 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3279 const wxMouseEvent
& event
)
3281 if ( event
.Entering() )
3283 control
->GetInputWindow()->SetCurrent(true);
3285 else if ( event
.Leaving() )
3287 control
->GetInputWindow()->SetCurrent(false);
3297 // ----------------------------------------------------------------------------
3298 // wxGTKCheckboxInputHandler
3299 // ----------------------------------------------------------------------------
3301 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3302 const wxKeyEvent
& event
,
3307 int keycode
= event
.GetKeyCode();
3308 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
3310 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
3319 // ----------------------------------------------------------------------------
3320 // wxGTKTextCtrlInputHandler
3321 // ----------------------------------------------------------------------------
3323 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
3324 const wxKeyEvent
& event
,
3327 // handle only GTK-specific text bindings here, the others are handled in
3331 wxControlAction action
;
3332 int keycode
= event
.GetKeyCode();
3333 if ( event
.ControlDown() )
3338 action
= wxACTION_TEXT_HOME
;
3342 action
= wxACTION_TEXT_LEFT
;
3346 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
3350 action
= wxACTION_TEXT_END
;
3354 action
= wxACTION_TEXT_RIGHT
;
3358 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
3362 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
3366 action
= wxACTION_TEXT_DOWN
;
3370 action
= wxACTION_TEXT_UP
;
3374 //delete the entire line
3375 control
->PerformAction(wxACTION_TEXT_HOME
);
3376 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
3380 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
3384 else if ( event
.AltDown() )
3389 action
= wxACTION_TEXT_WORD_LEFT
;
3393 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
3397 action
= wxACTION_TEXT_WORD_RIGHT
;
3402 if ( action
!= wxACTION_NONE
)
3404 control
->PerformAction(action
);
3410 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);