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"
56 #include "wx/univ/renderer.h"
57 #include "wx/univ/inphand.h"
58 #include "wx/univ/colschem.h"
59 #include "wx/univ/theme.h"
61 class WXDLLEXPORT wxGTKMenuGeometryInfo
;
63 // ----------------------------------------------------------------------------
64 // constants (to be removed, for testing only)
65 // ----------------------------------------------------------------------------
67 static const size_t BORDER_THICKNESS
= 1;
69 // ----------------------------------------------------------------------------
70 // wxGTKRenderer: draw the GUI elements in GTK style
71 // ----------------------------------------------------------------------------
73 class wxGTKRenderer
: public wxRenderer
76 wxGTKRenderer(const wxColourScheme
*scheme
);
78 // implement the base class pure virtuals
79 virtual void DrawBackground(wxDC
& dc
,
83 wxWindow
*window
= NULL
);
84 virtual void DrawLabel(wxDC
& dc
,
85 const wxString
& label
,
88 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
90 wxRect
*rectBounds
= NULL
);
91 virtual void DrawButtonLabel(wxDC
& dc
,
92 const wxString
& label
,
93 const wxBitmap
& image
,
96 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
98 wxRect
*rectBounds
= NULL
);
99 virtual void DrawBorder(wxDC
& dc
,
103 wxRect
*rectIn
= (wxRect
*)NULL
);
104 virtual void DrawHorizontalLine(wxDC
& dc
,
105 wxCoord y
, wxCoord x1
, wxCoord x2
);
106 virtual void DrawVerticalLine(wxDC
& dc
,
107 wxCoord x
, wxCoord y1
, wxCoord y2
);
108 virtual void DrawFrame(wxDC
& dc
,
109 const wxString
& label
,
112 int alignment
= wxALIGN_LEFT
,
113 int indexAccel
= -1);
114 virtual void DrawTextBorder(wxDC
& dc
,
118 wxRect
*rectIn
= (wxRect
*)NULL
);
119 virtual void DrawButtonBorder(wxDC
& dc
,
122 wxRect
*rectIn
= (wxRect
*)NULL
);
123 virtual void DrawArrow(wxDC
& dc
,
127 virtual void DrawScrollbarArrow(wxDC
& dc
,
131 virtual void DrawScrollbarThumb(wxDC
& dc
,
132 wxOrientation orient
,
135 virtual void DrawScrollbarShaft(wxDC
& dc
,
136 wxOrientation orient
,
139 virtual void DrawScrollCorner(wxDC
& dc
,
141 virtual void DrawItem(wxDC
& dc
,
142 const wxString
& label
,
145 virtual void DrawCheckItem(wxDC
& dc
,
146 const wxString
& label
,
147 const wxBitmap
& bitmap
,
150 virtual void DrawCheckButton(wxDC
& dc
,
151 const wxString
& label
,
152 const wxBitmap
& bitmap
,
155 wxAlignment align
= wxALIGN_LEFT
,
156 int indexAccel
= -1);
158 virtual void DrawRadioButton(wxDC
& dc
,
159 const wxString
& label
,
160 const wxBitmap
& bitmap
,
163 wxAlignment align
= wxALIGN_LEFT
,
164 int indexAccel
= -1);
166 virtual void DrawToolBarButton(wxDC
& dc
,
167 const wxString
& label
,
168 const wxBitmap
& bitmap
,
173 virtual void DrawTextLine(wxDC
& dc
,
174 const wxString
& text
,
179 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
180 virtual void DrawTab(wxDC
& dc
,
183 const wxString
& label
,
184 const wxBitmap
& bitmap
= wxNullBitmap
,
186 int indexAccel
= -1);
188 virtual void DrawSliderShaft(wxDC
& dc
,
191 wxOrientation orient
,
194 wxRect
*rectShaft
= NULL
);
195 virtual void DrawSliderThumb(wxDC
& dc
,
197 wxOrientation orient
,
200 virtual void DrawSliderTicks(wxDC
& WXUNUSED(dc
),
201 const wxRect
& WXUNUSED(rect
),
202 int WXUNUSED(lenThumb
),
203 wxOrientation
WXUNUSED(orient
),
206 int WXUNUSED(step
) = 1,
207 int WXUNUSED(flags
) = 0,
208 long WXUNUSED(style
) = 0)
210 // we don't have the ticks in GTK version
213 virtual void DrawMenuBarItem(wxDC
& dc
,
215 const wxString
& label
,
217 int indexAccel
= -1);
218 virtual void DrawMenuItem(wxDC
& dc
,
220 const wxMenuGeometryInfo
& geometryInfo
,
221 const wxString
& label
,
222 const wxString
& accel
,
223 const wxBitmap
& bitmap
= wxNullBitmap
,
225 int indexAccel
= -1);
226 virtual void DrawMenuSeparator(wxDC
& dc
,
228 const wxMenuGeometryInfo
& geomInfo
);
230 virtual void DrawStatusField(wxDC
& dc
,
232 const wxString
& label
,
233 int flags
= 0, int style
= 0);
235 virtual void DrawFrameTitleBar(wxDC
& dc
,
237 const wxString
& title
,
240 int specialButton
= 0,
241 int specialButtonFlag
= 0);
242 virtual void DrawFrameBorder(wxDC
& dc
,
245 virtual void DrawFrameBackground(wxDC
& dc
,
248 virtual void DrawFrameTitle(wxDC
& dc
,
250 const wxString
& title
,
252 virtual void DrawFrameIcon(wxDC
& dc
,
256 virtual void DrawFrameButton(wxDC
& dc
,
257 wxCoord x
, wxCoord y
,
262 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
263 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
264 virtual wxSize
GetFrameMinSize(int flags
) const;
265 virtual wxSize
GetFrameIconSize() const;
266 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
268 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
270 wxBitmap
*bmpPressed
,
271 wxBitmap
*bmpDisabled
);
273 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
274 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
275 virtual bool AreScrollbarsInsideBorder() const;
277 // geometry and hit testing
278 virtual wxSize
GetScrollbarArrowSize() const
279 { return m_sizeScrollbarArrow
; }
280 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
281 wxScrollBar::Element elem
,
282 int thumbPos
= -1) const;
283 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
284 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
285 const wxPoint
& pt
) const;
286 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
288 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
289 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
290 { return fontHeight
+ 2; }
291 virtual wxSize
GetCheckBitmapSize() const
292 { return wxSize(10, 10); }
293 virtual wxSize
GetRadioBitmapSize() const
294 { return wxSize(11, 11); }
295 virtual wxCoord
GetCheckItemMargin() const
298 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
299 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
300 virtual wxSize
GetToolBarMargin() const
301 { return wxSize(6, 6); }
303 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
304 const wxRect
& rect
) const;
305 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
307 wxCoord
*extraSpaceBeyond
) const;
309 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
310 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
312 virtual wxCoord
GetSliderDim() const { return 15; }
313 virtual wxCoord
GetSliderTickLen() const { return 0; }
314 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
316 wxOrientation orient
,
317 long style
= 0) const;
318 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
320 wxOrientation orient
) const;
321 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
323 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
324 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
325 const wxMenu
& menu
) const;
327 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
329 // helpers for "wxBitmap wxColourScheme::Get()"
330 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
331 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
332 void DrawUndeterminedBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
335 // DrawBackground() helpers
337 // get the colour to use for background
338 wxColour
GetBackgroundColour(int flags
) const
340 if ( flags
& wxCONTROL_PRESSED
)
341 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
342 else if ( flags
& wxCONTROL_CURRENT
)
343 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
345 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
348 // draw the background with any colour, not only the default one(s)
349 void DoDrawBackground(wxDC
& dc
,
352 wxWindow
*window
= NULL
);
354 // DrawBorder() helpers: all of them shift and clip the DC after drawing
357 // just draw a rectangle with the given pen
358 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
360 // draw the lower left part of rectangle
361 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
363 // draw the rectange using the first brush for the left and top sides and
364 // the second one for the bottom and right ones
365 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
366 const wxPen
& pen1
, const wxPen
& pen2
);
368 // as DrawShadedRect() but the pixels in the bottom left and upper right
369 // border are drawn with the pen1, not pen2
370 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
371 const wxPen
& pen1
, const wxPen
& pen2
);
373 // used for drawing opened rectangles - draws only one side of it at once
374 // (and doesn't adjust the rect)
375 void DrawAntiShadedRectSide(wxDC
& dc
,
381 // draw an opened rect for the arrow in given direction
382 void DrawArrowBorder(wxDC
& dc
,
386 // draw two sides of the rectangle
387 void DrawThumbBorder(wxDC
& dc
,
389 wxOrientation orient
);
391 // draw the normal 3D border
392 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
394 // just as DrawRaisedBorder() except that the bottom left and up right
395 // pixels of the interior rect are drawn in another colour (i.e. the inner
396 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
397 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
399 // returns the size of the arrow for the scrollbar (depends on
401 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
404 if ( scrollbar
->IsVertical() )
406 size
= m_sizeScrollbarArrow
;
410 size
.x
= m_sizeScrollbarArrow
.y
;
411 size
.y
= m_sizeScrollbarArrow
.x
;
417 // get the line wrap indicator bitmap
418 wxBitmap
GetLineWrapBitmap() const;
420 // DrawCheckBitmap and DrawRadioBitmap helpers
422 // draw the check bitmaps once and cache them for later use
423 wxBitmap
GetCheckBitmap(int flags
);
425 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
427 void DrawUpZag(wxDC
& dc
,
428 wxCoord x1
, wxCoord x2
,
429 wxCoord y1
, wxCoord y2
);
430 void DrawDownZag(wxDC
& dc
,
431 wxCoord x1
, wxCoord x2
,
432 wxCoord y1
, wxCoord y2
);
434 // draw the radio button bitmap for the given state
435 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
437 // draw check/radio - the bitmap must be a valid one by now
438 void DoDrawCheckOrRadioBitmap(wxDC
& dc
,
439 const wxString
& label
,
440 const wxBitmap
& bitmap
,
441 const wxRect
& rectTotal
,
446 // common part of DrawMenuItem() and DrawMenuBarItem()
447 void DoDrawMenuItem(wxDC
& dc
,
449 const wxString
& label
,
452 const wxString
& accel
= wxEmptyString
,
453 const wxBitmap
& bitmap
= wxNullBitmap
,
454 const wxGTKMenuGeometryInfo
*geometryInfo
= NULL
);
456 // initialize the combo bitmaps
457 void InitComboBitmaps();
460 const wxColourScheme
*m_scheme
;
463 wxSize m_sizeScrollbarArrow
;
472 // the checkbox bitmaps: first row is for the normal, second for the
473 // pressed state and the columns are for checked, unchecked and
474 // undeterminated respectively
475 wxBitmap m_bitmapsCheckbox
[2][3];
477 // the line wrap bitmap (drawn at the end of wrapped lines)
478 wxBitmap m_bmpLineWrap
;
480 // the combobox bitmaps
490 wxBitmap m_bitmapsCombo
[ComboState_Max
];
493 // ----------------------------------------------------------------------------
494 // wxGTKInputHandler and derived classes: process the keyboard and mouse
495 // messages according to GTK standards
496 // ----------------------------------------------------------------------------
498 class wxGTKInputHandler
: public wxInputHandler
501 wxGTKInputHandler(wxGTKRenderer
*renderer
);
503 virtual bool HandleKey(wxInputConsumer
*control
,
504 const wxKeyEvent
& event
,
506 virtual bool HandleMouse(wxInputConsumer
*control
,
507 const wxMouseEvent
& event
);
508 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
511 wxGTKRenderer
*m_renderer
;
514 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
517 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
518 : wxStdScrollBarInputHandler(renderer
, handler
) { }
521 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
523 // only arrows and the thumb can be highlighted
524 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
527 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
530 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
532 // only arrows can be pressed
536 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
539 virtual bool IsAllowedButton(int WXUNUSED(button
)) { return true; }
543 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
544 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
548 class wxGTKCheckboxInputHandler
: public wxStdCheckboxInputHandler
551 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
552 : wxStdCheckboxInputHandler(handler
) { }
554 virtual bool HandleKey(wxInputConsumer
*control
,
555 const wxKeyEvent
& event
,
559 class wxGTKTextCtrlInputHandler
: public wxStdTextCtrlInputHandler
562 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
563 : wxStdTextCtrlInputHandler(handler
) { }
565 virtual bool HandleKey(wxInputConsumer
*control
,
566 const wxKeyEvent
& event
,
570 // ----------------------------------------------------------------------------
571 // wxGTKColourScheme: uses the standard GTK colours
572 // ----------------------------------------------------------------------------
574 class wxGTKColourScheme
: public wxColourScheme
577 virtual wxColour
Get(StdColour col
) const;
578 virtual wxColour
GetBackground(wxWindow
*win
) const;
581 // ----------------------------------------------------------------------------
583 // ----------------------------------------------------------------------------
585 class wxGTKArtProvider
: public wxArtProvider
588 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
589 const wxArtClient
& client
,
593 // ----------------------------------------------------------------------------
595 // ----------------------------------------------------------------------------
597 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
599 class wxGTKTheme
: public wxTheme
603 virtual ~wxGTKTheme();
605 virtual wxRenderer
*GetRenderer();
606 virtual wxArtProvider
*GetArtProvider();
607 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
608 virtual wxColourScheme
*GetColourScheme();
611 // get the default input handler
612 wxInputHandler
*GetDefaultInputHandler();
614 wxGTKRenderer
*m_renderer
;
616 wxGTKArtProvider
*m_artProvider
;
618 // the names of the already created handlers and the handlers themselves
619 // (these arrays are synchronized)
620 wxSortedArrayString m_handlerNames
;
621 wxArrayHandlers m_handlers
;
623 wxGTKInputHandler
*m_handlerDefault
;
625 wxGTKColourScheme
*m_scheme
;
627 WX_DECLARE_THEME(gtk
)
630 // ============================================================================
632 // ============================================================================
634 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
636 // ----------------------------------------------------------------------------
638 // ----------------------------------------------------------------------------
640 wxGTKTheme::wxGTKTheme()
644 m_handlerDefault
= NULL
;
645 m_artProvider
= NULL
;
648 wxGTKTheme::~wxGTKTheme()
650 size_t count
= m_handlers
.GetCount();
651 for ( size_t n
= 0; n
< count
; n
++ )
653 if ( m_handlers
[n
] != m_handlerDefault
)
654 delete m_handlers
[n
];
657 delete m_handlerDefault
;
660 wxArtProvider::RemoveProvider(m_artProvider
);
663 wxRenderer
*wxGTKTheme::GetRenderer()
667 m_renderer
= new wxGTKRenderer(GetColourScheme());
673 wxArtProvider
*wxGTKTheme::GetArtProvider()
675 if ( !m_artProvider
)
677 m_artProvider
= new wxGTKArtProvider
;
680 return m_artProvider
;
683 wxColourScheme
*wxGTKTheme::GetColourScheme()
687 m_scheme
= new wxGTKColourScheme
;
692 wxInputHandler
*wxGTKTheme::GetDefaultInputHandler()
694 if ( !m_handlerDefault
)
696 m_handlerDefault
= new wxGTKInputHandler(m_renderer
);
699 return m_handlerDefault
;
702 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
)
704 wxInputHandler
*handler
;
705 int n
= m_handlerNames
.Index(control
);
706 if ( n
== wxNOT_FOUND
)
708 // create a new handler
709 if ( control
== wxINP_HANDLER_SCROLLBAR
)
710 handler
= new wxGTKScrollBarInputHandler(m_renderer
,
711 GetDefaultInputHandler());
713 else if ( control
== wxINP_HANDLER_BUTTON
)
714 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
715 #endif // wxUSE_CHECKBOX
717 else if ( control
== wxINP_HANDLER_CHECKBOX
)
718 handler
= new wxGTKCheckboxInputHandler(GetDefaultInputHandler());
719 #endif // wxUSE_CHECKBOX
721 else if ( control
== wxINP_HANDLER_COMBOBOX
)
722 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
723 #endif // wxUSE_COMBOBOX
725 else if ( control
== wxINP_HANDLER_LISTBOX
)
726 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
727 #endif // wxUSE_LISTBOX
728 #if wxUSE_CHECKLISTBOX
729 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
730 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
731 #endif // wxUSE_CHECKLISTBOX
733 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
734 handler
= new wxGTKTextCtrlInputHandler(GetDefaultInputHandler());
735 #endif // wxUSE_TEXTCTRL
737 else if ( control
== wxINP_HANDLER_SLIDER
)
738 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
739 #endif // wxUSE_SLIDER
741 else if ( control
== wxINP_HANDLER_SPINBTN
)
742 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
743 #endif // wxUSE_SPINBTN
745 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
746 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
747 #endif // wxUSE_NOTEBOOK
749 else if ( control
== wxINP_HANDLER_TOOLBAR
)
750 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
751 #endif // wxUSE_TOOLBAR
752 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
753 handler
= new wxStdFrameInputHandler(GetDefaultInputHandler());
755 handler
= GetDefaultInputHandler();
757 n
= m_handlerNames
.Add(control
);
758 m_handlers
.Insert(handler
, n
);
760 else // we already have it
762 handler
= m_handlers
[n
];
768 // ============================================================================
770 // ============================================================================
772 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
775 if ( win
->UseBgCol() )
777 // use the user specified colour
778 col
= win
->GetBackgroundColour();
781 if ( !win
->ShouldInheritColours() )
783 // doesn't depend on the state
791 int flags
= win
->GetStateFlags();
793 // the colour set by the user should be used for the normal state
794 // and for the states for which we don't have any specific colours
795 if ( !col
.Ok() || (flags
!= 0) )
797 if ( wxDynamicCast(win
, wxScrollBar
) )
798 col
= Get(SCROLLBAR
);
799 else if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
800 col
= Get(CONTROL_CURRENT
);
801 else if ( flags
& wxCONTROL_PRESSED
)
802 col
= Get(CONTROL_PRESSED
);
811 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
815 case WINDOW
: return *wxWHITE
;
817 case SHADOW_DARK
: return *wxBLACK
;
818 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
819 case SHADOW_IN
: return wxColour(0xd6d6d6);
820 case SHADOW_OUT
: return wxColour(0x969696);
822 case CONTROL
: return wxColour(0xd6d6d6);
823 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
824 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
826 case CONTROL_TEXT
: return *wxBLACK
;
827 case CONTROL_TEXT_DISABLED
:
828 return wxColour(0x757575);
829 case CONTROL_TEXT_DISABLED_SHADOW
:
833 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
835 case HIGHLIGHT
: return wxColour(0x9c0000);
836 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
838 case GAUGE
: return Get(CONTROL_CURRENT
);
842 wxFAIL_MSG(_T("invalid standard colour"));
847 // ============================================================================
849 // ============================================================================
851 // ----------------------------------------------------------------------------
853 // ----------------------------------------------------------------------------
855 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
859 m_sizeScrollbarArrow
= wxSize(15, 14);
862 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
863 m_penDarkGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_OUT
), 0, wxSOLID
);
864 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
), 0, wxSOLID
);
865 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
866 m_penHighlight
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
), 0, wxSOLID
);
869 // ----------------------------------------------------------------------------
871 // ----------------------------------------------------------------------------
873 void wxGTKRenderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
877 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
878 dc
.DrawRectangle(*rect
);
884 void wxGTKRenderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
886 // draw the bottom and right sides
888 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
889 rect
->GetRight() + 1, rect
->GetBottom());
890 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
891 rect
->GetRight(), rect
->GetBottom());
898 void wxGTKRenderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
899 const wxPen
& pen1
, const wxPen
& pen2
)
901 // draw the rectangle
903 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
904 rect
->GetLeft(), rect
->GetBottom());
905 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
906 rect
->GetRight(), rect
->GetTop());
908 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
909 rect
->GetRight(), rect
->GetBottom());
910 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
911 rect
->GetRight() + 1, rect
->GetBottom());
917 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
923 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
928 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
929 rect
.GetLeft(), rect
.GetBottom() + 1);
933 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
934 rect
.GetRight() + 1, rect
.GetTop());
938 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
939 rect
.GetRight(), rect
.GetBottom() + 1);
943 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
944 rect
.GetRight() + 1, rect
.GetBottom());
948 wxFAIL_MSG(_T("unknown rectangle side"));
952 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
953 const wxPen
& pen1
, const wxPen
& pen2
)
955 // draw the rectangle
957 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
958 rect
->GetLeft(), rect
->GetBottom() + 1);
959 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
960 rect
->GetRight() + 1, rect
->GetTop());
962 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
963 rect
->GetRight(), rect
->GetBottom());
964 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
965 rect
->GetRight() + 1, rect
->GetBottom());
971 void wxGTKRenderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
973 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
974 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
977 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
979 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
980 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
983 void wxGTKRenderer::DrawBorder(wxDC
& dc
,
985 const wxRect
& rectTotal
,
991 wxRect rect
= rectTotal
;
995 case wxBORDER_SUNKEN
:
996 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
998 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
999 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1003 case wxBORDER_STATIC
:
1004 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1006 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1010 case wxBORDER_RAISED
:
1011 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1013 DrawRaisedBorder(dc
, &rect
);
1017 case wxBORDER_DOUBLE
:
1018 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1020 DrawShadedRect(dc
, &rect
, m_penLightGrey
, m_penBlack
);
1021 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penDarkGrey
);
1022 DrawRect(dc
, &rect
, m_penLightGrey
);
1026 case wxBORDER_SIMPLE
:
1027 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
1029 DrawRect(dc
, &rect
, m_penBlack
);
1034 wxFAIL_MSG(_T("unknown border type"));
1037 case wxBORDER_DEFAULT
:
1046 wxRect
wxGTKRenderer::GetBorderDimensions(wxBorder border
) const
1051 case wxBORDER_RAISED
:
1052 case wxBORDER_SUNKEN
:
1053 width
= 2*BORDER_THICKNESS
;
1056 case wxBORDER_SIMPLE
:
1057 case wxBORDER_STATIC
:
1058 width
= BORDER_THICKNESS
;
1061 case wxBORDER_DOUBLE
:
1062 width
= 3*BORDER_THICKNESS
;
1066 wxFAIL_MSG(_T("unknown border type"));
1069 case wxBORDER_DEFAULT
:
1079 rect
.height
= width
;
1084 bool wxGTKRenderer::AreScrollbarsInsideBorder() const
1086 // no, the scrollbars are outside the border in GTK+
1090 // ----------------------------------------------------------------------------
1092 // ----------------------------------------------------------------------------
1094 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
1096 const wxRect
& rectOrig
,
1100 wxRect rect
= rectOrig
;
1102 if ( border
!= wxBORDER_NONE
)
1104 if ( flags
& wxCONTROL_FOCUSED
)
1106 DrawRect(dc
, &rect
, m_penBlack
);
1107 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1111 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1112 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penHighlight
);
1120 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
1121 const wxRect
& rectTotal
,
1125 wxRect rect
= rectTotal
;
1127 if ( flags
& wxCONTROL_PRESSED
)
1129 // button pressed: draw a black border around it and an inward shade
1130 DrawRect(dc
, &rect
, m_penBlack
);
1132 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1134 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1135 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penDarkGrey
);
1140 // button not pressed
1142 if ( flags
& wxCONTROL_ISDEFAULT
)
1147 if ( flags
& wxCONTROL_FOCUSED
)
1149 // button is currently default: add an extra border around it
1150 DrawRect(dc
, &rect
, m_penBlack
);
1153 // now draw a normal button
1154 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1156 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1157 DrawAntiShadedRect(dc
, &rect
,
1158 wxPen(GetBackgroundColour(flags
), 0, wxSOLID
),
1169 // ----------------------------------------------------------------------------
1171 // ----------------------------------------------------------------------------
1173 void wxGTKRenderer::DrawHorizontalLine(wxDC
& dc
,
1174 wxCoord y
, wxCoord x1
, wxCoord x2
)
1176 dc
.SetPen(m_penDarkGrey
);
1177 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1178 dc
.SetPen(m_penHighlight
);
1180 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1183 void wxGTKRenderer::DrawVerticalLine(wxDC
& dc
,
1184 wxCoord x
, wxCoord y1
, wxCoord y2
)
1186 dc
.SetPen(m_penDarkGrey
);
1187 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1188 dc
.SetPen(m_penHighlight
);
1190 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1193 void wxGTKRenderer::DrawFrame(wxDC
& dc
,
1194 const wxString
& label
,
1200 wxCoord height
= 0; // of the label
1201 wxRect rectFrame
= rect
;
1202 if ( !label
.empty() )
1204 // the text should touch the top border of the rect, so the frame
1205 // itself should be lower
1206 dc
.GetTextExtent(label
, NULL
, &height
);
1207 rectFrame
.y
+= height
/ 2;
1208 rectFrame
.height
-= height
/ 2;
1210 // TODO: the +4 should be customizable
1213 rectText
.x
= rectFrame
.x
+ 4;
1214 rectText
.y
= rect
.y
;
1215 rectText
.width
= rectFrame
.width
- 8;
1216 rectText
.height
= height
;
1219 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1221 rectLabel
.width
+= 2;
1223 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1225 // GTK+ does it like this
1226 dc
.SetPen(m_penHighlight
);
1227 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
1228 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
1232 // just draw the complete frame
1233 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1234 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1238 // ----------------------------------------------------------------------------
1240 // ----------------------------------------------------------------------------
1242 void wxGTKRenderer::DrawLabel(wxDC
& dc
,
1243 const wxString
& label
,
1250 DrawButtonLabel(dc
, label
, wxNullBitmap
, rect
, flags
,
1251 alignment
, indexAccel
, rectBounds
);
1254 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
1255 const wxString
& label
,
1256 const wxBitmap
& image
,
1263 if ( flags
& wxCONTROL_DISABLED
)
1265 // make the text grey and draw a shade for it
1266 dc
.SetTextForeground(*wxWHITE
); // FIXME hardcoded colour
1267 wxRect rectShadow
= rect
;
1270 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1271 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT_DISABLED
));
1275 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT
));
1278 dc
.DrawLabel(label
, image
, rect
, alignment
, indexAccel
, rectBounds
);
1281 void wxGTKRenderer::DrawItem(wxDC
& dc
,
1282 const wxString
& label
,
1286 wxLogTrace(_T("listbox"), _T("drawing item '%s' at (%d, %d)-(%d, %d)"),
1289 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1292 if ( flags
& wxCONTROL_SELECTED
)
1294 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
), wxSOLID
));
1295 dc
.SetPen(*wxTRANSPARENT_PEN
);
1296 dc
.DrawRectangle(rect
);
1298 colFg
= dc
.GetTextForeground();
1299 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
1302 if ( flags
& wxCONTROL_FOCUSED
)
1304 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1305 wxRect rectFocus
= rect
;
1306 DrawRect(dc
, &rectFocus
, m_penBlack
);
1309 wxRect rectText
= rect
;
1312 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
1314 if ( flags
& wxCONTROL_SELECTED
)
1316 dc
.SetBackgroundMode(wxTRANSPARENT
);
1319 // restore the text colour
1322 dc
.SetTextForeground(colFg
);
1326 void wxGTKRenderer::DrawCheckItem(wxDC
& dc
,
1327 const wxString
& label
,
1328 const wxBitmap
& bitmap
,
1332 wxRect rectBitmap
= rect
;
1334 rectBitmap
.width
= GetCheckBitmapSize().x
;
1336 // never draw the focus rect around the check indicators here
1337 DrawCheckButton(dc
, wxEmptyString
, bitmap
, rectBitmap
, flags
& ~wxCONTROL_FOCUSED
);
1339 wxRect rectLabel
= rect
;
1340 wxCoord shift
= rectBitmap
.width
+ 2*GetCheckItemMargin();
1341 rectLabel
.x
+= shift
;
1342 rectLabel
.width
-= shift
;
1343 DrawItem(dc
, label
, rectLabel
, flags
);
1346 // ----------------------------------------------------------------------------
1347 // check/radion buttons
1348 // ----------------------------------------------------------------------------
1350 void wxGTKRenderer::DrawUndeterminedBitmap(wxDC
& dc
,
1351 const wxRect
& rectTotal
,
1354 // FIXME: For sure it is not GTK look but it is better than nothing.
1355 // Show me correct look and I will immediatelly make it better (ABX)
1356 wxRect rect
= rectTotal
;
1358 wxColour col1
, col2
;
1362 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1363 col2
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1367 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1368 col2
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1371 dc
.SetPen(*wxTRANSPARENT_PEN
);
1372 dc
.SetBrush(wxBrush(col1
, wxSOLID
));
1373 dc
.DrawRectangle(rect
);
1375 dc
.SetBrush(wxBrush(col2
, wxSOLID
));
1376 dc
.DrawRectangle(rect
);
1379 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1380 const wxRect
& rectTotal
,
1383 wxRect rect
= rectTotal
;
1384 DrawAntiRaisedBorder(dc
, &rect
);
1386 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1387 dc
.SetPen(wxPen(col
, 0, wxSOLID
));
1388 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1391 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1392 //else: it is SHADOW_IN, leave as is
1394 dc
.SetPen(*wxTRANSPARENT_PEN
);
1395 dc
.SetBrush(wxBrush(col
, wxSOLID
));
1396 dc
.DrawRectangle(rect
);
1399 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1401 wxRect rect
= rectTotal
;
1402 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1403 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1405 dc
.SetPen(*wxTRANSPARENT_PEN
);
1406 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), wxSOLID
));
1407 dc
.DrawRectangle(rect
);
1410 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1416 xRight
= rect
.GetRight(),
1417 yBottom
= rect
.GetBottom();
1419 wxCoord yMid
= (y
+ yBottom
) / 2;
1421 // this looks ugly when the background colour of the control is not the
1422 // same ours - radiobox is not transparent as it should be
1424 // first fill the middle: as FloodFill() is not implemented on all
1425 // platforms, this is the only thing to do
1426 wxColour colBg
= flags
& wxCONTROL_CURRENT
1427 ? wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
)
1428 : wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1429 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
1430 dc
.SetPen(*wxTRANSPARENT_PEN
);
1431 dc
.DrawRectangle(rect
);
1434 // then draw the upper half
1435 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1436 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1437 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1440 if ( flags
& wxCONTROL_CHECKED
)
1441 dc
.SetPen(m_penBlack
);
1442 else if ( flags
& wxCONTROL_PRESSED
)
1443 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1444 else // unchecked and unpressed
1448 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1450 // and then the lower one
1451 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1452 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1453 if ( !(flags
& wxCONTROL_CHECKED
) )
1454 dc
.SetPen(m_penDarkGrey
);
1455 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1457 if ( !(flags
& wxCONTROL_CHECKED
) )
1458 drawIt
= true; // with the same pen
1459 else if ( flags
& wxCONTROL_PRESSED
)
1461 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1464 else // checked and unpressed
1468 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1471 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1477 wxCoord xMid
= (x1
+ x2
) / 2;
1478 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1479 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1482 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1488 wxCoord xMid
= (x1
+ x2
) / 2;
1489 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1490 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1493 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1495 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1497 // init the bitmaps once only
1499 wxSize size
= GetCheckBitmapSize();
1500 rect
.width
= size
.x
;
1501 rect
.height
= size
.y
;
1502 for ( int i
= 0; i
< 2; i
++ )
1504 for ( int j
= 0; j
< 3; j
++ )
1505 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1511 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1512 DrawCheckBitmap(dc
, rect
);
1515 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1516 DrawUncheckBitmap(dc
, rect
, false);
1518 // normal undeterminated
1519 dc
.SelectObject(m_bitmapsCheckbox
[0][2]);
1520 DrawUndeterminedBitmap(dc
, rect
, false);
1523 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1525 // pressed unchecked
1526 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1527 DrawUncheckBitmap(dc
, rect
, true);
1529 // pressed undeterminated
1530 dc
.SelectObject(m_bitmapsCheckbox
[1][2]);
1531 DrawUndeterminedBitmap(dc
, rect
, true);
1534 int row
= flags
& wxCONTROL_PRESSED
1537 int col
= flags
& wxCONTROL_CHECKED
1539 : ( flags
& wxCONTROL_UNDETERMINED
1543 return m_bitmapsCheckbox
[row
][col
];
1546 wxBitmap
wxGTKRenderer::GetLineWrapBitmap() const
1548 if ( !m_bmpLineWrap
.Ok() )
1550 // the line wrap bitmap as used by GTK+
1551 #define line_wrap_width 6
1552 #define line_wrap_height 9
1553 static const char line_wrap_bits
[] =
1555 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1558 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1559 if ( !bmpLineWrap
.Ok() )
1561 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1565 wxConstCast(this, wxGTKRenderer
)->m_bmpLineWrap
= bmpLineWrap
;
1569 return m_bmpLineWrap
;
1572 void wxGTKRenderer::DrawCheckButton(wxDC
& dc
,
1573 const wxString
& label
,
1574 const wxBitmap
& bitmapOrig
,
1575 const wxRect
& rectTotal
,
1581 if ( bitmapOrig
.Ok() )
1583 bitmap
= bitmapOrig
;
1587 bitmap
= GetCheckBitmap(flags
);
1590 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1591 flags
, align
, indexAccel
);
1594 void wxGTKRenderer::DoDrawCheckOrRadioBitmap(wxDC
& dc
,
1595 const wxString
& label
,
1596 const wxBitmap
& bitmap
,
1597 const wxRect
& rectTotal
,
1602 wxRect rect
= rectTotal
;
1604 if ( flags
& wxCONTROL_FOCUSED
)
1606 // draw the focus border around everything
1607 DrawRect(dc
, &rect
, m_penBlack
);
1611 // the border does not offset the string under GTK
1615 // calculate the position of the bitmap and of the label
1617 yBmp
= rect
.y
+ (rect
.height
- bitmap
.GetHeight()) / 2;
1620 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
1621 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
1623 if ( align
== wxALIGN_RIGHT
)
1625 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
1626 rectLabel
.x
= rect
.x
+ 2;
1627 rectLabel
.SetRight(xBmp
);
1629 else // normal (checkbox to the left of the text) case
1632 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 4;
1633 rectLabel
.SetRight(rect
.GetRight());
1636 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
1638 DrawLabel(dc
, label
, rectLabel
, flags
,
1639 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1642 void wxGTKRenderer::DrawRadioButton(wxDC
& dc
,
1643 const wxString
& label
,
1644 const wxBitmap
& bitmapOrig
,
1645 const wxRect
& rectTotal
,
1651 if ( bitmapOrig
.Ok() )
1653 bitmap
= bitmapOrig
;
1658 wxSize size
= GetRadioBitmapSize();
1659 rect
.width
= size
.x
;
1660 rect
.height
= size
.y
;
1661 bitmap
.Create(rect
.width
, rect
.height
);
1663 dc
.SelectObject(bitmap
);
1664 dc
.SetBackground(*wxLIGHT_GREY_BRUSH
);
1666 DrawRadioBitmap(dc
, rect
, flags
);
1668 // must unselect the bitmap before setting a mask for it because of the
1670 dc
.SelectObject(wxNullBitmap
);
1671 bitmap
.SetMask(new wxMask(bitmap
, *wxLIGHT_GREY
));
1674 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1675 flags
, align
, indexAccel
);
1678 void wxGTKRenderer::DrawToolBarButton(wxDC
& dc
,
1679 const wxString
& label
,
1680 const wxBitmap
& bitmap
,
1681 const wxRect
& rectOrig
,
1683 long WXUNUSED(style
))
1685 // we don't draw the separators at all
1686 if ( !label
.empty() || bitmap
.Ok() )
1688 wxRect rect
= rectOrig
;
1689 rect
.Deflate(BORDER_THICKNESS
);
1691 if ( flags
& wxCONTROL_PRESSED
)
1693 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
, &rect
);
1695 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), rect
);
1697 else if ( flags
& wxCONTROL_CURRENT
)
1699 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rect
);
1701 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rect
);
1704 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1708 // ----------------------------------------------------------------------------
1710 // ----------------------------------------------------------------------------
1712 wxRect
wxGTKRenderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
1713 const wxRect
& rect
) const
1715 wxRect rectTotal
= rect
;
1716 rectTotal
.Inflate(2*BORDER_THICKNESS
);
1720 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1722 wxCoord
*extraSpaceBeyond
) const
1724 wxRect rectText
= rect
;
1725 rectText
.Deflate(2*BORDER_THICKNESS
);
1727 if ( text
->WrapLines() )
1729 // leave enough for the line wrap bitmap indicator
1730 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1732 rectText
.width
-= widthMark
;
1734 if ( extraSpaceBeyond
)
1735 *extraSpaceBeyond
= widthMark
;
1741 void wxGTKRenderer::DrawTextLine(wxDC
& dc
,
1742 const wxString
& text
,
1748 // TODO: GTK+ draws selection even for unfocused controls, just with
1749 // different colours
1750 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
1753 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1755 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1757 // for a mono bitmap he colours it appears in depends on the current text
1758 // colours, so set them correctly
1760 if ( bmpLineWrap
.GetDepth() == 1 )
1762 colFgOld
= dc
.GetTextForeground();
1764 // FIXME: I wonder what should we do if the background is black too?
1765 dc
.SetTextForeground(*wxBLACK
);
1768 dc
.DrawBitmap(bmpLineWrap
,
1769 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1771 if ( colFgOld
.Ok() )
1773 // restore old colour
1774 dc
.SetTextForeground(colFgOld
);
1778 // ----------------------------------------------------------------------------
1780 // ----------------------------------------------------------------------------
1782 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1783 const wxRect
& rectOrig
,
1785 const wxString
& label
,
1786 const wxBitmap
& bitmap
,
1790 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1791 #define REVERSE_FOR_VERTICAL(X,Y) \
1792 SELECT_FOR_VERTICAL(X,Y) \
1794 SELECT_FOR_VERTICAL(Y,X)
1796 wxRect rect
= rectOrig
;
1798 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1800 // the current tab is drawn indented (to the top for default case) and
1801 // bigger than the other ones
1802 const wxSize indent
= GetTabIndent();
1803 if ( flags
& wxCONTROL_SELECTED
)
1805 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1806 SELECT_FOR_VERTICAL( 0, indent
.y
));
1810 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1817 rect
.height
+= indent
.y
;
1824 rect
.width
+= indent
.x
;
1829 // selected tab has different colour
1830 wxColour col
= flags
& wxCONTROL_SELECTED
1831 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1832 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1833 DoDrawBackground(dc
, col
, rect
);
1835 if ( flags
& wxCONTROL_FOCUSED
)
1837 // draw the focus rect
1838 wxRect rectBorder
= rect
;
1839 rectBorder
.Deflate(4, 3);
1840 if ( dir
== wxBOTTOM
)
1841 rectBorder
.Offset(0, -1);
1842 if ( dir
== wxRIGHT
)
1843 rectBorder
.Offset(-1, 0);
1845 DrawRect(dc
, &rectBorder
, m_penBlack
);
1848 // draw the text, image and the focus around them (if necessary)
1849 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1850 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1852 rectLabel
.Deflate(1, 1);
1855 // draw it horizontally into memory and rotate for screen
1857 wxBitmap bitmapRotated
,
1858 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1859 rectLabel
.y
+ rectLabel
.height
);
1860 dcMem
.SelectObject(bitmapMem
);
1861 dcMem
.SetBackground(dc
.GetBackground());
1862 dcMem
.SetFont(dc
.GetFont());
1863 dcMem
.SetTextForeground(dc
.GetTextForeground());
1865 bitmapRotated
= wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) );
1866 dcMem
.DrawLabel(label
, bitmapRotated
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1867 dcMem
.SelectObject(wxNullBitmap
);
1868 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1869 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
1870 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1874 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1877 // now draw the tab itself
1878 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1879 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1880 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1881 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1887 // left orientation looks like top but IsVertical makes x and y reversed
1889 // top is not vertical so use coordinates in written order
1890 dc
.SetPen(m_penHighlight
);
1891 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1892 REVERSE_FOR_VERTICAL(x
, y
));
1893 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
),
1894 REVERSE_FOR_VERTICAL(x2
, y
));
1896 dc
.SetPen(m_penBlack
);
1897 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1898 REVERSE_FOR_VERTICAL(x2
, y
));
1900 dc
.SetPen(m_penDarkGrey
);
1901 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1902 REVERSE_FOR_VERTICAL(x2
- 1, y
+ 1));
1904 if ( flags
& wxCONTROL_SELECTED
)
1906 dc
.SetPen(m_penLightGrey
);
1908 // overwrite the part of the border below this tab
1909 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1910 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1912 // and the shadow of the tab to the left of us
1913 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ 2),
1914 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1919 // right orientation looks like bottom but IsVertical makes x and y reversed
1921 // bottom is not vertical so use coordinates in written order
1922 dc
.SetPen(m_penHighlight
);
1924 // we need to continue one pixel further to overwrite the corner of
1925 // the border for the selected tab
1926 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
1927 REVERSE_FOR_VERTICAL(x
, y2
));
1929 // it doesn't work like this (TODO: implement it properly)
1931 // erase the corner of the tab to the right
1932 dc
.SetPen(m_penLightGrey
);
1933 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1934 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 2));
1935 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 1));
1938 dc
.SetPen(m_penBlack
);
1939 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
),
1940 REVERSE_FOR_VERTICAL(x2
, y2
));
1941 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
1942 REVERSE_FOR_VERTICAL(x2
, y2
));
1944 dc
.SetPen(m_penDarkGrey
);
1945 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 2, y2
- 1),
1946 REVERSE_FOR_VERTICAL(x2
- 1, y2
- 1));
1947 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
1948 REVERSE_FOR_VERTICAL(x2
- 1, y2
));
1950 if ( flags
& wxCONTROL_SELECTED
)
1952 dc
.SetPen(m_penLightGrey
);
1954 // overwrite the part of the (double!) border above this tab
1955 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
1956 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
1957 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
1958 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1960 // and the shadow of the tab to the left of us
1961 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- 1),
1962 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
1968 // ----------------------------------------------------------------------------
1970 // ----------------------------------------------------------------------------
1972 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1974 wxOrientation orient
) const
1976 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1980 wxRect rectShaft
= GetSliderShaftRect(rect
, lenThumb
, orient
);
1981 if ( orient
== wxHORIZONTAL
)
1983 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1984 size
.y
= rectShaft
.height
;
1988 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1989 size
.x
= rectShaft
.width
;
1995 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1996 int WXUNUSED(lenThumb
),
1997 wxOrientation
WXUNUSED(orient
),
1998 long WXUNUSED(style
)) const
2000 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
2003 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
2004 const wxRect
& rectOrig
,
2005 int WXUNUSED(lenThumb
),
2006 wxOrientation
WXUNUSED(orient
),
2008 long WXUNUSED(style
),
2011 wxRect rect
= rectOrig
;
2013 // draw the border first
2014 if ( flags
& wxCONTROL_FOCUSED
)
2016 DrawRect(dc
, &rect
, m_penBlack
);
2017 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
2019 else // not focused, normal
2021 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
2022 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
2025 // and the background
2026 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
2032 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
2033 const wxRect
& rectOrig
,
2034 wxOrientation orient
,
2035 int WXUNUSED(flags
),
2036 long WXUNUSED(style
))
2038 // draw the thumb border
2039 wxRect rect
= rectOrig
;
2040 DrawAntiRaisedBorder(dc
, &rect
);
2042 // draw the handle in the middle
2043 if ( orient
== wxVERTICAL
)
2045 rect
.height
= 2*BORDER_THICKNESS
;
2046 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2050 rect
.width
= 2*BORDER_THICKNESS
;
2051 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2054 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
2057 // ----------------------------------------------------------------------------
2059 // ----------------------------------------------------------------------------
2061 // wxGTKMenuGeometryInfo: the wxMenuGeometryInfo used by wxGTKRenderer
2062 class WXDLLEXPORT wxGTKMenuGeometryInfo
: public wxMenuGeometryInfo
2065 virtual wxSize
GetSize() const { return m_size
; }
2067 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2068 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2070 wxCoord
GetItemHeight() const { return m_heightItem
; }
2073 // the total size of the menu
2076 // the offset of the start of the menu item label
2079 // the offset of the start of the accel label
2082 // the height of a normal (not separator) item
2083 wxCoord m_heightItem
;
2085 friend wxMenuGeometryInfo
*
2086 wxGTKRenderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2089 // FIXME: all constants are hardcoded but shouldn't be
2090 static const wxCoord MENU_LEFT_MARGIN
= 9;
2091 static const wxCoord MENU_RIGHT_MARGIN
= 6;
2093 static const wxCoord MENU_HORZ_MARGIN
= 6;
2094 static const wxCoord MENU_VERT_MARGIN
= 3;
2096 // the margin around bitmap/check marks (on each side)
2097 static const wxCoord MENU_BMP_MARGIN
= 2;
2099 // the margin between the labels and accel strings
2100 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2102 // the separator height in pixels: in fact, strangely enough, the real height
2103 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2105 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2107 // the size of the standard checkmark bitmap
2108 static const wxCoord MENU_CHECK_SIZE
= 9;
2110 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
2112 const wxString
& label
,
2116 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
);
2119 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
2121 const wxMenuGeometryInfo
& gi
,
2122 const wxString
& label
,
2123 const wxString
& accel
,
2124 const wxBitmap
& bitmap
,
2128 const wxGTKMenuGeometryInfo
& geomInfo
= (const wxGTKMenuGeometryInfo
&)gi
;
2133 rect
.width
= geomInfo
.GetSize().x
;
2134 rect
.height
= geomInfo
.GetItemHeight();
2136 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
, accel
, bitmap
, &geomInfo
);
2139 void wxGTKRenderer::DoDrawMenuItem(wxDC
& dc
,
2140 const wxRect
& rectOrig
,
2141 const wxString
& label
,
2144 const wxString
& accel
,
2145 const wxBitmap
& bitmap
,
2146 const wxGTKMenuGeometryInfo
*geometryInfo
)
2148 wxRect rect
= rectOrig
;
2150 // draw the selected item specially
2151 if ( flags
& wxCONTROL_SELECTED
)
2154 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
2156 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rectIn
);
2159 rect
.Deflate(MENU_HORZ_MARGIN
, MENU_VERT_MARGIN
);
2161 // draw the bitmap: use the bitmap provided or the standard checkmark for
2162 // the checkable items
2165 wxBitmap bmp
= bitmap
;
2166 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKABLE
) )
2168 bmp
= GetCheckBitmap(flags
);
2173 rect
.SetRight(geometryInfo
->GetLabelOffset());
2174 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2177 //else: menubar items don't have bitmaps
2182 rect
.x
= geometryInfo
->GetLabelOffset();
2183 rect
.SetRight(geometryInfo
->GetAccelOffset());
2186 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2188 // draw the accel string
2189 if ( !accel
.empty() )
2191 // menubar items shouldn't have them
2192 wxCHECK_RET( geometryInfo
, _T("accel strings only valid for menus") );
2194 rect
.x
= geometryInfo
->GetAccelOffset();
2195 rect
.SetRight(geometryInfo
->GetSize().x
);
2197 // NB: no accel index here
2198 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2201 // draw the submenu indicator
2202 if ( flags
& wxCONTROL_ISSUBMENU
)
2204 wxCHECK_RET( geometryInfo
, _T("wxCONTROL_ISSUBMENU only valid for menus") );
2206 rect
.x
= geometryInfo
->GetSize().x
- MENU_RIGHT_MARGIN
;
2207 rect
.width
= MENU_RIGHT_MARGIN
;
2209 DrawArrow(dc
, wxRIGHT
, rect
, flags
);
2213 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
2215 const wxMenuGeometryInfo
& geomInfo
)
2217 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2220 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2222 wxSize size
= sizeText
;
2224 // TODO: make this configurable
2225 size
.x
+= 2*MENU_HORZ_MARGIN
;
2226 size
.y
+= 2*MENU_VERT_MARGIN
;
2231 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
2232 const wxMenu
& menu
) const
2234 // prepare the dc: for now we draw all the items with the system font
2236 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2238 // the height of a normal item
2239 wxCoord heightText
= dc
.GetCharHeight();
2244 // the max length of label and accel strings: the menu width is the sum of
2245 // them, even if they're for different items (as the accels should be
2248 // the max length of the bitmap is never 0 as Windows always leaves enough
2249 // space for a check mark indicator
2250 wxCoord widthLabelMax
= 0,
2252 widthBmpMax
= MENU_LEFT_MARGIN
;
2254 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
2256 node
= node
->GetNext() )
2258 // height of this item
2261 wxMenuItem
*item
= node
->GetData();
2262 if ( item
->IsSeparator() )
2264 h
= MENU_SEPARATOR_HEIGHT
;
2266 else // not separator
2271 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2272 if ( widthLabel
> widthLabelMax
)
2274 widthLabelMax
= widthLabel
;
2278 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2279 if ( widthAccel
> widthAccelMax
)
2281 widthAccelMax
= widthAccel
;
2284 const wxBitmap
& bmp
= item
->GetBitmap();
2287 wxCoord widthBmp
= bmp
.GetWidth();
2288 if ( widthBmp
> widthBmpMax
)
2289 widthBmpMax
= widthBmp
;
2291 //else if ( item->IsCheckable() ): no need to check for this as
2292 // MENU_LEFT_MARGIN is big enough to show the check mark
2295 h
+= 2*MENU_VERT_MARGIN
;
2297 // remember the item position and height
2298 item
->SetGeometry(height
, h
);
2303 // bundle the metrics into a struct and return it
2304 wxGTKMenuGeometryInfo
*gi
= new wxGTKMenuGeometryInfo
;
2306 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2307 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2308 if ( widthAccelMax
> 0 )
2310 // if we actually have any accesl, add a margin
2311 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2314 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2316 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2317 gi
->m_size
.y
= height
;
2322 // ----------------------------------------------------------------------------
2324 // ----------------------------------------------------------------------------
2327 wxGTKRenderer::GetStatusBarBorders(wxCoord
* WXUNUSED(borderBetweenFields
)) const
2332 void wxGTKRenderer::DrawStatusField(wxDC
& WXUNUSED(dc
),
2333 const wxRect
& WXUNUSED(rect
),
2334 const wxString
& WXUNUSED(label
),
2335 int WXUNUSED(flags
), int WXUNUSED(style
))
2339 // ----------------------------------------------------------------------------
2341 // ----------------------------------------------------------------------------
2343 void wxGTKRenderer::InitComboBitmaps()
2345 wxSize sizeArrow
= m_sizeScrollbarArrow
;
2351 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
2353 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
2356 static const int comboButtonFlags
[ComboState_Max
] =
2364 wxRect
rect(sizeArrow
);
2367 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
2369 int flags
= comboButtonFlags
[n
];
2371 dc
.SelectObject(m_bitmapsCombo
[n
]);
2372 DoDrawBackground(dc
, GetBackgroundColour(flags
), rect
);
2373 DrawArrow(dc
, wxDOWN
, rect
, flags
);
2377 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
2379 wxBitmap
*bmpPressed
,
2380 wxBitmap
*bmpDisabled
)
2382 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
2388 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
2390 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
2392 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
2394 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
2397 // ----------------------------------------------------------------------------
2399 // ----------------------------------------------------------------------------
2401 void wxGTKRenderer::DoDrawBackground(wxDC
& dc
,
2402 const wxColour
& col
,
2404 wxWindow
* WXUNUSED(window
))
2406 wxBrush
brush(col
, wxSOLID
);
2408 dc
.SetPen(*wxTRANSPARENT_PEN
);
2409 dc
.DrawRectangle(rect
);
2412 void wxGTKRenderer::DrawBackground(wxDC
& dc
,
2413 const wxColour
& col
,
2418 wxColour colBg
= col
.Ok() ? col
: GetBackgroundColour(flags
);
2419 DoDrawBackground(dc
, colBg
, rect
, window
);
2422 // ----------------------------------------------------------------------------
2424 // ----------------------------------------------------------------------------
2426 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
2430 static const wxDirection sides
[] =
2432 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
2435 wxRect rect1
, rect2
, rectInner
;
2441 rectInner
.Inflate(-2);
2443 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
2445 // find the side not to draw and also adjust the rectangles to compensate
2447 wxDirection sideToOmit
;
2451 sideToOmit
= wxDOWN
;
2453 rectInner
.height
+= 1;
2461 rectInner
.height
+= 1;
2465 sideToOmit
= wxRIGHT
;
2467 rectInner
.width
+= 1;
2471 sideToOmit
= wxLEFT
;
2475 rectInner
.width
+= 1;
2479 wxFAIL_MSG(_T("unknown arrow direction"));
2483 // the outer rect first
2485 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2487 wxDirection side
= sides
[n
];
2488 if ( side
== sideToOmit
)
2491 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
2494 // and then the inner one
2495 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2497 wxDirection side
= sides
[n
];
2498 if ( side
== sideToOmit
)
2501 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
2507 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
2509 const wxRect
& rectArrow
,
2512 // first of all, draw the border around it - but we don't want the border
2513 // on the side opposite to the arrow point
2514 wxRect rect
= rectArrow
;
2515 DrawArrowBorder(dc
, &rect
, dir
);
2517 // then the arrow itself
2518 DrawArrow(dc
, dir
, rect
, flags
);
2521 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
2522 // these people are just crazy :-(
2523 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2536 wxPoint ptArrow
[Point_Max
];
2538 wxColour colInside
= GetBackgroundColour(flags
);
2540 if ( flags
& wxCONTROL_DISABLED
)
2542 penShadow
[0] = m_penDarkGrey
;
2543 penShadow
[1] = m_penDarkGrey
;
2544 penShadow
[2] = wxNullPen
;
2545 penShadow
[3] = wxNullPen
;
2547 else if ( flags
& wxCONTROL_PRESSED
)
2549 penShadow
[0] = m_penDarkGrey
;
2550 penShadow
[1] = m_penHighlight
;
2551 penShadow
[2] = wxNullPen
;
2552 penShadow
[3] = m_penBlack
;
2554 else // normal arrow
2556 penShadow
[0] = m_penHighlight
;
2557 penShadow
[1] = m_penBlack
;
2558 penShadow
[2] = m_penDarkGrey
;
2559 penShadow
[3] = wxNullPen
;
2563 if ( dir
== wxUP
|| dir
== wxDOWN
)
2566 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2570 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2573 // draw the arrow interior
2574 dc
.SetPen(*wxTRANSPARENT_PEN
);
2575 dc
.SetBrush(wxBrush(colInside
, wxSOLID
));
2580 ptArrow
[Point_First
].x
= rect
.GetLeft();
2581 ptArrow
[Point_First
].y
= rect
.GetBottom();
2582 ptArrow
[Point_Second
].x
= middle
;
2583 ptArrow
[Point_Second
].y
= rect
.GetTop();
2584 ptArrow
[Point_Third
].x
= rect
.GetRight();
2585 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2589 ptArrow
[Point_First
] = rect
.GetPosition();
2590 ptArrow
[Point_Second
].x
= middle
;
2591 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2592 ptArrow
[Point_Third
].x
= rect
.GetRight();
2593 ptArrow
[Point_Third
].y
= rect
.GetTop();
2597 ptArrow
[Point_First
].x
= rect
.GetRight();
2598 ptArrow
[Point_First
].y
= rect
.GetTop();
2599 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2600 ptArrow
[Point_Second
].y
= middle
;
2601 ptArrow
[Point_Third
].x
= rect
.GetRight();
2602 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2606 ptArrow
[Point_First
] = rect
.GetPosition();
2607 ptArrow
[Point_Second
].x
= rect
.GetRight();
2608 ptArrow
[Point_Second
].y
= middle
;
2609 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2610 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2614 wxFAIL_MSG(_T("unknown arrow direction"));
2617 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2619 // draw the arrow border
2620 dc
.SetPen(penShadow
[0]);
2624 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2625 dc
.DrawPoint(ptArrow
[Point_First
]);
2626 if ( penShadow
[3].Ok() )
2628 dc
.SetPen(penShadow
[3]);
2629 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2630 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2632 dc
.SetPen(penShadow
[1]);
2633 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2634 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2635 dc
.DrawPoint(ptArrow
[Point_Third
]);
2636 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2637 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2638 if ( penShadow
[2].Ok() )
2640 dc
.SetPen(penShadow
[2]);
2641 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2642 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2643 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2644 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2649 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2650 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2651 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2652 if ( penShadow
[2].Ok() )
2654 dc
.SetPen(penShadow
[2]);
2655 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2656 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2658 dc
.SetPen(penShadow
[1]);
2659 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2660 dc
.DrawPoint(ptArrow
[Point_Third
]);
2664 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2665 dc
.DrawPoint(ptArrow
[Point_First
]);
2666 if ( penShadow
[2].Ok() )
2668 dc
.SetPen(penShadow
[2]);
2669 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2670 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2671 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2672 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2674 dc
.SetPen(penShadow
[1]);
2675 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2676 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2677 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2678 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2682 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2683 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2684 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2685 dc
.SetPen(penShadow
[1]);
2686 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2687 dc
.DrawPoint(ptArrow
[Point_Third
]);
2691 wxFAIL_MSG(_T("unknown arrow direction"));
2696 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2698 wxOrientation orient
)
2700 if ( orient
== wxVERTICAL
)
2702 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2704 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2706 rect
->Inflate(-1, 0);
2708 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2710 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2712 rect
->Inflate(-1, 0);
2716 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2718 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2720 rect
->Inflate(0, -1);
2722 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2724 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2726 rect
->Inflate(0, -1);
2730 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2731 wxOrientation orient
,
2735 // the thumb is never pressed never has focus border under GTK and the
2736 // scrollbar background never changes at all
2737 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2739 // we don't want the border in the direction of the scrollbar movement
2740 wxRect rectThumb
= rect
;
2741 DrawThumbBorder(dc
, &rectThumb
, orient
);
2743 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2744 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2747 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2748 wxOrientation orient
,
2750 int WXUNUSED(flags
))
2752 wxRect rectBar
= rect
;
2753 DrawThumbBorder(dc
, &rectBar
, orient
);
2754 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2757 void wxGTKRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2759 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2762 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2763 wxScrollBar::Element elem
,
2766 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2767 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2769 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2771 elem
= wxScrollBar::Element_Bar_2
;
2774 return StandardGetScrollbarRect(scrollbar
, elem
,
2776 GetScrollbarArrowSize(scrollbar
));
2779 wxCoord
wxGTKRenderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
2781 return StandardScrollBarSize(scrollbar
, GetScrollbarArrowSize(scrollbar
));
2784 wxHitTest
wxGTKRenderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
2785 const wxPoint
& pt
) const
2787 return StandardHitTestScrollbar(scrollbar
, pt
,
2788 GetScrollbarArrowSize(scrollbar
));
2791 wxCoord
wxGTKRenderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
2794 return StandardScrollbarToPixel(scrollbar
, thumbPos
,
2795 GetScrollbarArrowSize(scrollbar
));
2798 int wxGTKRenderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
2801 return StandardPixelToScrollbar(scrollbar
, coord
,
2802 GetScrollbarArrowSize(scrollbar
));
2805 // ----------------------------------------------------------------------------
2807 // ----------------------------------------------------------------------------
2809 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2812 if ( wxDynamicCast(window
, wxBitmapButton
) )
2817 #endif // wxUSE_BMPBUTTON
2819 if ( wxDynamicCast(window
, wxButton
) )
2821 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2823 // TODO: this is ad hoc...
2824 size
->x
+= 3*window
->GetCharWidth();
2825 wxCoord minBtnHeight
= 18;
2826 if ( size
->y
< minBtnHeight
)
2827 size
->y
= minBtnHeight
;
2829 // button border width
2833 #endif //wxUSE_BUTTON
2834 if ( wxDynamicCast(window
, wxScrollBar
) )
2836 // we only set the width of vert scrollbars and height of the
2838 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2839 size
->y
= m_sizeScrollbarArrow
.x
;
2841 size
->x
= m_sizeScrollbarArrow
.x
;
2845 // take into account the border width
2846 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
2847 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
2848 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
2852 // ----------------------------------------------------------------------------
2853 // top level windows
2854 // ----------------------------------------------------------------------------
2856 void wxGTKRenderer::DrawFrameTitleBar(wxDC
& WXUNUSED(dc
),
2857 const wxRect
& WXUNUSED(rect
),
2858 const wxString
& WXUNUSED(title
),
2859 const wxIcon
& WXUNUSED(icon
),
2860 int WXUNUSED(flags
),
2861 int WXUNUSED(specialButton
),
2862 int WXUNUSED(specialButtonFlag
))
2866 void wxGTKRenderer::DrawFrameBorder(wxDC
& WXUNUSED(dc
),
2867 const wxRect
& WXUNUSED(rect
),
2868 int WXUNUSED(flags
))
2872 void wxGTKRenderer::DrawFrameBackground(wxDC
& WXUNUSED(dc
),
2873 const wxRect
& WXUNUSED(rect
),
2874 int WXUNUSED(flags
))
2878 void wxGTKRenderer::DrawFrameTitle(wxDC
& WXUNUSED(dc
),
2879 const wxRect
& WXUNUSED(rect
),
2880 const wxString
& WXUNUSED(title
),
2881 int WXUNUSED(flags
))
2885 void wxGTKRenderer::DrawFrameIcon(wxDC
& WXUNUSED(dc
),
2886 const wxRect
& WXUNUSED(rect
),
2887 const wxIcon
& WXUNUSED(icon
),
2888 int WXUNUSED(flags
))
2892 void wxGTKRenderer::DrawFrameButton(wxDC
& WXUNUSED(dc
),
2893 wxCoord
WXUNUSED(x
),
2894 wxCoord
WXUNUSED(y
),
2895 int WXUNUSED(button
),
2896 int WXUNUSED(flags
))
2901 wxGTKRenderer::GetFrameClientArea(const wxRect
& rect
,
2902 int WXUNUSED(flags
)) const
2908 wxGTKRenderer::GetFrameTotalSize(const wxSize
& clientSize
,
2909 int WXUNUSED(flags
)) const
2914 wxSize
wxGTKRenderer::GetFrameMinSize(int WXUNUSED(flags
)) const
2919 wxSize
wxGTKRenderer::GetFrameIconSize() const
2921 return wxSize(wxDefaultCoord
, wxDefaultCoord
);
2925 wxGTKRenderer::HitTestFrame(const wxRect
& WXUNUSED(rect
),
2926 const wxPoint
& WXUNUSED(pt
),
2927 int WXUNUSED(flags
)) const
2929 return wxHT_TOPLEVEL_CLIENT_AREA
;
2933 // ----------------------------------------------------------------------------
2935 // ----------------------------------------------------------------------------
2937 /* Copyright (c) Julian Smart */
2938 static const char *error_xpm
[] = {
2939 /* columns rows colors chars-per-pixel */
2953 " ................. ",
2954 " ................... ",
2955 " ....................... ",
2956 " ......................... ",
2957 " ........................... ",
2958 " ...........................X ",
2959 " .............................X ",
2960 " ............................... ",
2961 " ...............................X ",
2962 " .................................X ",
2963 " .................................X ",
2964 " .................................XX ",
2965 " ...ooooooooooooooooooooooooooo...XX ",
2966 " ....ooooooooooooooooooooooooooo....X ",
2967 " ....ooooooooooooooooooooooooooo....X ",
2968 " ....ooooooooooooooooooooooooooo....XX ",
2969 " ....ooooooooooooooooooooooooooo....XX ",
2970 " ....ooooooooooooooooooooooooooo....XX ",
2971 " ...ooooooooooooooooooooooooooo...XXX ",
2972 " ...ooooooooooooooooooooooooooo...XXX ",
2973 " .................................XX ",
2974 " .................................XX ",
2975 " ...............................XXX ",
2976 " ...............................XXX ",
2977 " .............................XXX ",
2978 " ...........................XXXX ",
2979 " ...........................XXX ",
2980 " .........................XXX ",
2981 " .......................XXXX ",
2982 " X...................XXXXX ",
2983 " X.................XXXXX ",
2984 " X.............XXXXX ",
2985 " XXXX.....XXXXXXXX ",
2996 /* Copyright (c) Julian Smart */
2997 static const char *info_xpm
[] = {
2998 /* columns rows colors chars-per-pixel */
3022 " .XXXOXXXXXXXoo. ",
3023 " .XOOXXX+XXXXXo. ",
3024 " .XOOOXX+++XXXXoo. ",
3025 " .XOOXXX+++XXXXXo. ",
3026 " .XOOOXXX+++XXXXXXo. ",
3027 " .XOOXXXX+++XXXXXXo. ",
3028 " .XXXXXXX+++XXXXXXX. ",
3029 " .XXXXXXX+++XXXXXXo. ",
3030 " .XXXXXXX+++XXXXXoo. ",
3031 " .XXXXXX+++XXXXXo. ",
3032 " .XXXXXXX+XXXXXXo. ",
3033 " .XXXXXXXXXXXXo. ",
3034 " .XXXXX+++XXXoo. ",
3060 /* Copyright (c) Julian Smart */
3061 static const char *warning_xpm
[] = {
3062 /* columns rows colors chars-per-pixel */
3092 " ..XXXXO@#XXX... ",
3093 " ...XXXXO@#XXXX.. ",
3094 " ..XXXXXO@#XXXX... ",
3095 " ...XXXXXo@OXXXXX.. ",
3096 " ...XXXXXXo@OXXXXXX.. ",
3097 " ..XXXXXXX$@OXXXXXX... ",
3098 " ...XXXXXXXX@XXXXXXXX.. ",
3099 " ...XXXXXXXXXXXXXXXXXX... ",
3100 " ..XXXXXXXXXXOXXXXXXXXX.. ",
3101 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
3102 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
3103 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
3104 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
3105 " .............................. ",
3106 " .............................. ",
3124 /* Copyright (c) Julian Smart */
3125 static const char *question_xpm
[] = {
3126 /* columns rows colors chars-per-pixel */
3156 " ..XXXXoooooXXXO+ ",
3157 " ..XXooooooooooooX@.. ",
3158 " ..XoooooooooooooooXX#. ",
3159 " $%XoooooooooooooooooXX#. ",
3160 " &.XoooooooXXXXXXooooooXX.. ",
3161 " .XooooooXX.$...$XXoooooX*. ",
3162 " $.XoooooX%.$ .*oooooo=.. ",
3163 " .XooooooX.. -.XoooooX.. ",
3164 " .XoooooX..+ .XoooooX;. ",
3165 " ...XXXX..: .XoooooX;. ",
3166 " ........ >.XoooooX;. ",
3200 wxBitmap
wxGTKArtProvider::CreateBitmap(const wxArtID
& id
,
3201 const wxArtClient
& WXUNUSED(client
),
3202 const wxSize
& WXUNUSED(size
))
3204 if ( id
== wxART_INFORMATION
)
3205 return wxBitmap(info_xpm
);
3206 if ( id
== wxART_ERROR
)
3207 return wxBitmap(error_xpm
);
3208 if ( id
== wxART_WARNING
)
3209 return wxBitmap(warning_xpm
);
3210 if ( id
== wxART_QUESTION
)
3211 return wxBitmap(question_xpm
);
3212 return wxNullBitmap
;
3216 // ============================================================================
3218 // ============================================================================
3220 // ----------------------------------------------------------------------------
3221 // wxGTKInputHandler
3222 // ----------------------------------------------------------------------------
3224 wxGTKInputHandler::wxGTKInputHandler(wxGTKRenderer
*renderer
)
3226 m_renderer
= renderer
;
3229 bool wxGTKInputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
3230 const wxKeyEvent
& WXUNUSED(event
),
3231 bool WXUNUSED(pressed
))
3236 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
3237 const wxMouseEvent
& event
)
3239 // clicking on the control gives it focus
3240 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
3242 control
->GetInputWindow()->SetFocus();
3250 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3251 const wxMouseEvent
& event
)
3253 if ( event
.Entering() )
3255 control
->GetInputWindow()->SetCurrent(true);
3257 else if ( event
.Leaving() )
3259 control
->GetInputWindow()->SetCurrent(false);
3269 // ----------------------------------------------------------------------------
3270 // wxGTKCheckboxInputHandler
3271 // ----------------------------------------------------------------------------
3273 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3274 const wxKeyEvent
& event
,
3279 int keycode
= event
.GetKeyCode();
3280 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
3282 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
3291 // ----------------------------------------------------------------------------
3292 // wxGTKTextCtrlInputHandler
3293 // ----------------------------------------------------------------------------
3295 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
3296 const wxKeyEvent
& event
,
3299 // handle only GTK-specific text bindings here, the others are handled in
3303 wxControlAction action
;
3304 int keycode
= event
.GetKeyCode();
3305 if ( event
.ControlDown() )
3310 action
= wxACTION_TEXT_HOME
;
3314 action
= wxACTION_TEXT_LEFT
;
3318 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
3322 action
= wxACTION_TEXT_END
;
3326 action
= wxACTION_TEXT_RIGHT
;
3330 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
3334 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
3338 action
= wxACTION_TEXT_DOWN
;
3342 action
= wxACTION_TEXT_UP
;
3346 //delete the entire line
3347 control
->PerformAction(wxACTION_TEXT_HOME
);
3348 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
3352 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
3356 else if ( event
.AltDown() )
3361 action
= wxACTION_TEXT_WORD_LEFT
;
3365 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
3369 action
= wxACTION_TEXT_WORD_RIGHT
;
3374 if ( action
!= wxACTION_NONE
)
3376 control
->PerformAction(action
);
3382 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);