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"
27 #include "wx/univ/theme.h"
34 #include "wx/dcmemory.h"
35 #include "wx/window.h"
39 #include "wx/bmpbuttn.h"
40 #include "wx/button.h"
41 #include "wx/checkbox.h"
42 #include "wx/listbox.h"
43 #include "wx/checklst.h"
44 #include "wx/combobox.h"
45 #include "wx/scrolbar.h"
46 #include "wx/slider.h"
47 #include "wx/textctrl.h"
48 #include "wx/toolbar.h"
49 #include "wx/statusbr.h"
51 #include "wx/settings.h"
52 #include "wx/toplevel.h"
56 #include "wx/notebook.h"
57 #include "wx/spinbutt.h"
58 #include "wx/artprov.h"
59 #ifdef wxUSE_TOGGLEBTN
60 #include "wx/tglbtn.h"
61 #endif // wxUSE_TOGGLEBTN
63 #include "wx/univ/stdrend.h"
64 #include "wx/univ/inpcons.h"
65 #include "wx/univ/inphand.h"
66 #include "wx/univ/colschem.h"
68 class WXDLLEXPORT wxGTKMenuGeometryInfo
;
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
74 // standard border size
75 static const int BORDER_THICKNESS
= 2;
77 // ----------------------------------------------------------------------------
78 // wxGTKRenderer: draw the GUI elements in GTK style
79 // ----------------------------------------------------------------------------
81 class wxGTKRenderer
: public wxStdRenderer
84 wxGTKRenderer(const wxColourScheme
*scheme
);
87 virtual void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
, int flags
= 0);
88 virtual void DrawTextBorder(wxDC
& dc
,
92 wxRect
*rectIn
= NULL
);
93 virtual void DrawButtonLabel(wxDC
& dc
,
94 const wxString
& label
,
95 const wxBitmap
& image
,
101 virtual void DrawButtonBorder(wxDC
& dc
,
104 wxRect
*rectIn
= NULL
);
105 virtual void DrawArrow(wxDC
& dc
,
109 virtual void DrawScrollbarArrow(wxDC
& dc
,
113 virtual void DrawScrollbarThumb(wxDC
& dc
,
114 wxOrientation orient
,
117 virtual void DrawScrollbarShaft(wxDC
& dc
,
118 wxOrientation orient
,
123 virtual void DrawToolBarButton(wxDC
& dc
,
124 const wxString
& label
,
125 const wxBitmap
& bitmap
,
130 #endif // wxUSE_TOOLBAR
133 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
134 #endif // wxUSE_TEXTCTRL
137 virtual void DrawTab(wxDC
& dc
,
140 const wxString
& label
,
141 const wxBitmap
& bitmap
= wxNullBitmap
,
143 int indexAccel
= -1);
144 #endif // wxUSE_NOTEBOOK
147 virtual void DrawSliderShaft(wxDC
& dc
,
150 wxOrientation orient
,
153 wxRect
*rectShaft
= NULL
);
154 virtual void DrawSliderThumb(wxDC
& dc
,
156 wxOrientation orient
,
159 virtual void DrawSliderTicks(wxDC
& WXUNUSED(dc
),
160 const wxRect
& WXUNUSED(rect
),
161 int WXUNUSED(lenThumb
),
162 wxOrientation
WXUNUSED(orient
),
165 int WXUNUSED(step
) = 1,
166 int WXUNUSED(flags
) = 0,
167 long WXUNUSED(style
) = 0)
169 // we don't have the ticks in GTK version
171 #endif // wxUSE_SLIDER
174 virtual void DrawMenuBarItem(wxDC
& dc
,
176 const wxString
& label
,
178 int indexAccel
= -1);
179 virtual void DrawMenuItem(wxDC
& dc
,
181 const wxMenuGeometryInfo
& geometryInfo
,
182 const wxString
& label
,
183 const wxString
& accel
,
184 const wxBitmap
& bitmap
= wxNullBitmap
,
186 int indexAccel
= -1);
187 virtual void DrawMenuSeparator(wxDC
& dc
,
189 const wxMenuGeometryInfo
& geomInfo
);
190 #endif // wxUSE_MENUS
192 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
194 wxBitmap
*bmpPressed
,
195 wxBitmap
*bmpDisabled
);
197 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
199 // geometry and hit testing
201 virtual wxSize
GetScrollbarArrowSize() const
202 { return m_sizeScrollbarArrow
; }
203 #endif // wxUSE_SCROLLBAR
205 virtual wxSize
GetCheckBitmapSize() const
206 { return wxSize(10, 10); }
207 virtual wxSize
GetRadioBitmapSize() const
208 { return wxSize(11, 11); }
209 virtual wxCoord
GetCheckItemMargin() const
213 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
214 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
215 virtual wxSize
GetToolBarMargin() const
216 { return wxSize(6, 6); }
217 #endif // wxUSE_TOOLBAR
220 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
222 wxCoord
*extraSpaceBeyond
) const;
223 #endif // wxUSE_TEXTCTRL
226 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
227 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
228 #endif // wxUSE_NOTEBOOK
231 virtual wxCoord
GetSliderDim() const { return 15; }
232 virtual wxCoord
GetSliderTickLen() const { return 0; }
233 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
235 wxOrientation orient
,
236 long style
= 0) const;
237 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
239 wxOrientation orient
) const;
240 #endif // wxUSE_SLIDER
242 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
245 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
246 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
247 const wxMenu
& menu
) const;
248 #endif // wxUSE_MENUS
250 // helpers for "wxBitmap wxColourScheme::Get()"
251 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
252 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
253 void DrawUndeterminedBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
256 // overridden wxStdRenderer methods
257 virtual void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
259 virtual void DrawFrameWithLabel(wxDC
& dc
,
260 const wxString
& label
,
261 const wxRect
& rectFrame
,
262 const wxRect
& rectText
,
267 virtual void DrawCheckItemBitmap(wxDC
& dc
,
268 const wxBitmap
& bitmap
,
272 // get the colour to use for background
273 wxColour
GetBackgroundColour(int flags
) const
275 if ( flags
& wxCONTROL_PRESSED
)
276 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
277 else if ( flags
& wxCONTROL_CURRENT
)
278 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
280 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
283 // as DrawShadedRect() but the pixels in the bottom left and upper right
284 // border are drawn with the pen1, not pen2
285 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
286 const wxPen
& pen1
, const wxPen
& pen2
);
288 // used for drawing opened rectangles - draws only one side of it at once
289 // (and doesn't adjust the rect)
290 void DrawAntiShadedRectSide(wxDC
& dc
,
296 // draw an opened rect for the arrow in given direction
297 void DrawArrowBorder(wxDC
& dc
,
301 // draw two sides of the rectangle
302 void DrawThumbBorder(wxDC
& dc
,
304 wxOrientation orient
);
306 // just as DrawRaisedBorder() except that the bottom left and up right
307 // pixels of the interior rect are drawn in another colour (i.e. the inner
308 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
309 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
311 // draw inner GTK shadow
312 void DrawInnerShadedRect(wxDC
& dc
, wxRect
*rect
);
314 // get the line wrap indicator bitmap
315 wxBitmap
GetLineWrapBitmap() const;
317 virtual wxBitmap
GetCheckBitmap(int flags
);
318 virtual wxBitmap
GetRadioBitmap(int flags
);
320 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
322 void DrawUpZag(wxDC
& dc
,
323 wxCoord x1
, wxCoord x2
,
324 wxCoord y1
, wxCoord y2
);
325 void DrawDownZag(wxDC
& dc
,
326 wxCoord x1
, wxCoord x2
,
327 wxCoord y1
, wxCoord y2
);
329 // draw the radio button bitmap for the given state
330 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
332 // common part of DrawMenuItem() and DrawMenuBarItem()
333 void DoDrawMenuItem(wxDC
& dc
,
335 const wxString
& label
,
338 const wxString
& accel
= wxEmptyString
,
339 const wxBitmap
& bitmap
= wxNullBitmap
,
340 const wxGTKMenuGeometryInfo
*geometryInfo
= NULL
);
342 // initialize the combo bitmaps
343 void InitComboBitmaps();
345 virtual wxBitmap
GetFrameButtonBitmap(FrameButtonType
WXUNUSED(type
))
352 wxSize m_sizeScrollbarArrow
;
357 // the checkbox and radio button bitmaps: first row is for the normal,
358 // second for the pressed state and the columns are for checked, unchecked
359 // and undeterminated respectively
360 wxBitmap m_bitmapsCheckbox
[IndicatorState_MaxCtrl
][IndicatorStatus_Max
],
361 m_bitmapsRadiobtn
[IndicatorState_MaxCtrl
][IndicatorStatus_Max
];
363 // the line wrap bitmap (drawn at the end of wrapped lines)
364 wxBitmap m_bmpLineWrap
;
366 // the combobox bitmaps
376 wxBitmap m_bitmapsCombo
[ComboState_Max
];
379 // ----------------------------------------------------------------------------
380 // wxGTKInputHandler and derived classes: process the keyboard and mouse
381 // messages according to GTK standards
382 // ----------------------------------------------------------------------------
384 class wxGTKInputHandler
: public wxInputHandler
387 wxGTKInputHandler() { }
389 virtual bool HandleKey(wxInputConsumer
*control
,
390 const wxKeyEvent
& event
,
392 virtual bool HandleMouse(wxInputConsumer
*control
,
393 const wxMouseEvent
& event
);
394 virtual bool HandleMouseMove(wxInputConsumer
*control
,
395 const wxMouseEvent
& event
);
400 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
403 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
404 : wxStdScrollBarInputHandler(renderer
, handler
) { }
407 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
409 // only arrows and the thumb can be highlighted
410 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
413 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
416 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
418 // only arrows can be pressed
422 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
425 // any button can be used to drag the scrollbar under GTK+
426 virtual bool IsAllowedButton(int WXUNUSED(button
)) const { return true; }
430 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
431 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
435 #endif // wxUSE_SCROLLBAR
439 class wxGTKCheckboxInputHandler
: public wxStdInputHandler
442 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
443 : wxStdInputHandler(handler
) { }
445 virtual bool HandleKey(wxInputConsumer
*control
,
446 const wxKeyEvent
& event
,
450 #endif // wxUSE_CHECKBOX
454 class wxGTKTextCtrlInputHandler
: public wxStdInputHandler
457 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
458 : wxStdInputHandler(handler
) { }
460 virtual bool HandleKey(wxInputConsumer
*control
,
461 const wxKeyEvent
& event
,
465 #endif // wxUSE_TEXTCTRL
467 // ----------------------------------------------------------------------------
468 // wxGTKColourScheme: uses the standard GTK colours
469 // ----------------------------------------------------------------------------
471 class wxGTKColourScheme
: public wxColourScheme
474 virtual wxColour
Get(StdColour col
) const;
475 virtual wxColour
GetBackground(wxWindow
*win
) const;
478 // ----------------------------------------------------------------------------
480 // ----------------------------------------------------------------------------
482 class wxGTKArtProvider
: public wxArtProvider
485 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
486 const wxArtClient
& client
,
490 // ----------------------------------------------------------------------------
492 // ----------------------------------------------------------------------------
494 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
496 class wxGTKTheme
: public wxTheme
500 virtual ~wxGTKTheme();
502 virtual wxRenderer
*GetRenderer();
503 virtual wxArtProvider
*GetArtProvider();
504 virtual wxInputHandler
*GetInputHandler(const wxString
& control
,
505 wxInputConsumer
*consumer
);
506 virtual wxColourScheme
*GetColourScheme();
509 wxGTKRenderer
*m_renderer
;
511 wxGTKArtProvider
*m_artProvider
;
513 // the names of the already created handlers and the handlers themselves
514 // (these arrays are synchronized)
515 wxSortedArrayString m_handlerNames
;
516 wxArrayHandlers m_handlers
;
518 wxGTKColourScheme
*m_scheme
;
520 WX_DECLARE_THEME(gtk
)
523 // ============================================================================
525 // ============================================================================
527 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
529 // ----------------------------------------------------------------------------
531 // ----------------------------------------------------------------------------
533 wxGTKTheme::wxGTKTheme()
537 m_artProvider
= NULL
;
540 wxGTKTheme::~wxGTKTheme()
544 delete m_artProvider
;
547 wxRenderer
*wxGTKTheme::GetRenderer()
551 m_renderer
= new wxGTKRenderer(GetColourScheme());
557 wxArtProvider
*wxGTKTheme::GetArtProvider()
559 if ( !m_artProvider
)
561 m_artProvider
= new wxGTKArtProvider
;
564 return m_artProvider
;
567 wxColourScheme
*wxGTKTheme::GetColourScheme()
571 m_scheme
= new wxGTKColourScheme
;
576 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
,
577 wxInputConsumer
*consumer
)
579 wxInputHandler
*handler
= NULL
;
580 int n
= m_handlerNames
.Index(control
);
581 if ( n
== wxNOT_FOUND
)
583 static wxGTKInputHandler s_handlerDef
;
585 wxInputHandler
* const
586 handlerStd
= consumer
->DoGetStdInputHandler(&s_handlerDef
);
588 // create a new handler
590 if ( control
== wxINP_HANDLER_CHECKBOX
)
592 static wxGTKCheckboxInputHandler
s_handler(handlerStd
);
594 handler
= &s_handler
;
597 #endif // wxUSE_CHECKBOX
599 if ( control
== wxINP_HANDLER_SCROLLBAR
)
601 static wxGTKScrollBarInputHandler
s_handler(m_renderer
, handlerStd
);
603 handler
= &s_handler
;
606 #endif // wxUSE_SCROLLBAR
608 if ( control
== wxINP_HANDLER_TEXTCTRL
)
610 static wxGTKTextCtrlInputHandler
s_handler(handlerStd
);
612 handler
= &s_handler
;
615 #endif // wxUSE_TEXTCTRL
617 // no special handler for this control
618 handler
= handlerStd
;
621 n
= m_handlerNames
.Add(control
);
622 m_handlers
.Insert(handler
, n
);
624 else // we already have it
626 handler
= m_handlers
[n
];
632 // ============================================================================
634 // ============================================================================
636 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
639 if ( win
->UseBgCol() )
641 // use the user specified colour
642 col
= win
->GetBackgroundColour();
645 if ( !win
->ShouldInheritColours() )
647 // doesn't depend on the state
655 int flags
= win
->GetStateFlags();
657 // the colour set by the user should be used for the normal state
658 // and for the states for which we don't have any specific colours
659 if ( !col
.Ok() || (flags
!= 0) )
662 if ( wxDynamicCast(win
, wxScrollBar
) )
663 col
= Get(SCROLLBAR
);
665 #endif //wxUSE_SCROLLBAR
666 if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
667 col
= Get(CONTROL_CURRENT
);
668 else if ( flags
& wxCONTROL_PRESSED
)
669 col
= Get(CONTROL_PRESSED
);
678 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
683 case WINDOW
: return *wxWHITE
;
685 case SHADOW_DARK
: return *wxBLACK
;
686 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
687 case SHADOW_IN
: return wxColour(0xd6d6d6);
688 case SHADOW_OUT
: return wxColour(0x969696);
690 case CONTROL
: return wxColour(0xd6d6d6);
691 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
692 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
694 case CONTROL_TEXT
: return *wxBLACK
;
695 case CONTROL_TEXT_DISABLED
:
696 return wxColour(0x757575);
697 case CONTROL_TEXT_DISABLED_SHADOW
:
701 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
703 case HIGHLIGHT
: return wxColour(0x9c0000);
704 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
706 case GAUGE
: return Get(CONTROL_CURRENT
);
708 case TITLEBAR
: return wxColour(0xaeaaae);
709 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
710 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
711 case TITLEBAR_ACTIVE_TEXT
:
714 case DESKTOP
: return *wxBLACK
;
718 wxFAIL_MSG(_T("invalid standard colour"));
723 // ============================================================================
725 // ============================================================================
727 // ----------------------------------------------------------------------------
729 // ----------------------------------------------------------------------------
731 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
732 : wxStdRenderer(scheme
)
734 m_sizeScrollbarArrow
= wxSize(15, 14);
736 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
));
739 // ----------------------------------------------------------------------------
741 // ----------------------------------------------------------------------------
743 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
749 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
754 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
755 rect
.GetLeft(), rect
.GetBottom() + 1);
759 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
760 rect
.GetRight() + 1, rect
.GetTop());
764 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
765 rect
.GetRight(), rect
.GetBottom() + 1);
769 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
770 rect
.GetRight() + 1, rect
.GetBottom());
774 wxFAIL_MSG(_T("unknown rectangle side"));
778 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
779 const wxPen
& pen1
, const wxPen
& pen2
)
781 // draw the rectangle
783 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
784 rect
->GetLeft(), rect
->GetBottom() + 1);
785 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
786 rect
->GetRight() + 1, rect
->GetTop());
788 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
789 rect
->GetRight(), rect
->GetBottom());
790 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
791 rect
->GetRight() + 1, rect
->GetBottom());
797 void wxGTKRenderer::DrawInnerShadedRect(wxDC
& dc
, wxRect
*rect
)
799 DrawAntiShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
800 DrawAntiShadedRect(dc
, rect
, m_penBlack
, m_penHighlight
);
803 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
805 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
806 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
809 void wxGTKRenderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
811 DrawAntiShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
812 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
816 wxGTKRenderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
, int WXUNUSED(flags
))
818 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
819 wxRect rectFocus
= rect
;
820 DrawRect(dc
, &rectFocus
, m_penBlack
);
823 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
825 const wxRect
& rectOrig
,
829 wxRect rect
= rectOrig
;
831 if ( border
!= wxBORDER_NONE
)
833 if ( flags
& wxCONTROL_FOCUSED
)
835 DrawRect(dc
, &rect
, m_penBlack
);
836 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
840 DrawInnerShadedRect(dc
, &rect
);
848 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
849 const wxString
& label
,
850 const wxBitmap
& image
,
857 // no focus rect around buttons label in GTK+
858 wxStdRenderer::DrawButtonLabel(dc
, label
, image
, rect
, flags
,
859 alignment
, indexAccel
, rectBounds
);
862 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
863 const wxRect
& rectTotal
,
867 wxRect rect
= rectTotal
;
869 if ( flags
& wxCONTROL_PRESSED
)
871 // button pressed: draw a black border around it and an inward shade
872 DrawRect(dc
, &rect
, m_penBlack
);
874 DrawInnerShadedRect(dc
, &rect
);
876 else // button not pressed
878 if ( flags
& wxCONTROL_ISDEFAULT
)
883 if ( flags
& wxCONTROL_FOCUSED
)
885 // button is currently default: add an extra border around it
886 DrawRect(dc
, &rect
, m_penBlack
);
889 // now draw a normal button
890 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
891 DrawAntiShadedRect(dc
, &rect
, GetBackgroundColour(flags
), m_penDarkGrey
);
898 // ----------------------------------------------------------------------------
900 // ----------------------------------------------------------------------------
902 void wxGTKRenderer::DrawFrameWithLabel(wxDC
& dc
,
903 const wxString
& label
,
904 const wxRect
& rectFrame
,
905 const wxRect
& rectTextOrig
,
910 wxRect
rectText(rectTextOrig
);
911 rectText
.Inflate(1, 0);
914 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
916 rectLabel
.width
+= 2;
918 DrawFrameWithoutLabel(dc
, rectFrame
, rectLabel
);
920 // GTK+ does it like this
921 dc
.SetPen(m_penHighlight
);
922 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
923 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
926 // ----------------------------------------------------------------------------
927 // check/radion buttons
928 // ----------------------------------------------------------------------------
930 void wxGTKRenderer::DrawCheckItemBitmap(wxDC
& dc
,
931 const wxBitmap
& bitmap
,
935 // never draw the focus rect around the check indicators here
936 DrawCheckButton(dc
, wxEmptyString
, bitmap
, rect
, flags
& ~wxCONTROL_FOCUSED
);
939 void wxGTKRenderer::DrawUndeterminedBitmap(wxDC
& dc
,
940 const wxRect
& rectTotal
,
943 // FIXME: For sure it is not GTK look but it is better than nothing.
944 // Show me correct look and I will immediatelly make it better (ABX)
945 wxRect rect
= rectTotal
;
951 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
952 col2
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
956 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
957 col2
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
960 dc
.SetPen(*wxTRANSPARENT_PEN
);
962 dc
.DrawRectangle(rect
);
965 dc
.DrawRectangle(rect
);
968 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
969 const wxRect
& rectTotal
,
972 wxRect rect
= rectTotal
;
973 DrawAntiRaisedBorder(dc
, &rect
);
975 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
976 dc
.SetPen(wxPen(col
));
977 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
980 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
981 //else: it is SHADOW_IN, leave as is
983 dc
.SetPen(*wxTRANSPARENT_PEN
);
985 dc
.DrawRectangle(rect
);
988 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
990 wxRect rect
= rectTotal
;
991 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
992 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
994 dc
.SetPen(*wxTRANSPARENT_PEN
);
995 dc
.SetBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
));
996 dc
.DrawRectangle(rect
);
999 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1005 xRight
= rect
.GetRight(),
1006 yBottom
= rect
.GetBottom();
1008 wxCoord yMid
= (y
+ yBottom
) / 2;
1010 // then draw the upper half
1011 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1012 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1013 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1016 if ( flags
& wxCONTROL_CHECKED
)
1017 dc
.SetPen(m_penBlack
);
1018 else if ( flags
& wxCONTROL_PRESSED
)
1019 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
)));
1020 else // unchecked and unpressed
1024 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1026 // and then the lower one
1027 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1028 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1029 if ( !(flags
& wxCONTROL_CHECKED
) )
1030 dc
.SetPen(m_penDarkGrey
);
1031 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1033 if ( !(flags
& wxCONTROL_CHECKED
) )
1034 drawIt
= true; // with the same pen
1035 else if ( flags
& wxCONTROL_PRESSED
)
1037 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
)));
1040 else // checked and unpressed
1044 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1047 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1053 wxCoord xMid
= (x1
+ x2
) / 2;
1054 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1055 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1058 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1064 wxCoord xMid
= (x1
+ x2
) / 2;
1065 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1066 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1069 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1071 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1073 // init the bitmaps once only
1075 wxSize size
= GetCheckBitmapSize();
1076 rect
.width
= size
.x
;
1077 rect
.height
= size
.y
;
1078 for ( int i
= 0; i
< 2; i
++ )
1080 for ( int j
= 0; j
< 3; j
++ )
1081 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1087 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1088 DrawCheckBitmap(dc
, rect
);
1091 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1092 DrawUncheckBitmap(dc
, rect
, false);
1094 // normal undeterminated
1095 dc
.SelectObject(m_bitmapsCheckbox
[0][2]);
1096 DrawUndeterminedBitmap(dc
, rect
, false);
1099 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1101 // pressed unchecked
1102 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1103 DrawUncheckBitmap(dc
, rect
, true);
1105 // pressed undeterminated
1106 dc
.SelectObject(m_bitmapsCheckbox
[1][2]);
1107 DrawUndeterminedBitmap(dc
, rect
, true);
1110 IndicatorState state
;
1111 IndicatorStatus status
;
1112 GetIndicatorsFromFlags(flags
, state
, status
);
1114 // disabled looks the same as normal
1115 if ( state
== IndicatorState_Disabled
)
1116 state
= IndicatorState_Normal
;
1118 return m_bitmapsCheckbox
[state
][status
];
1121 wxBitmap
wxGTKRenderer::GetRadioBitmap(int flags
)
1123 IndicatorState state
;
1124 IndicatorStatus status
;
1125 GetIndicatorsFromFlags(flags
, state
, status
);
1127 wxBitmap
& bmp
= m_bitmapsRadiobtn
[state
][status
];
1130 const wxSize size
= GetRadioBitmapSize();
1133 bmp
.Create(size
.x
, size
.y
);
1134 dc
.SelectObject(bmp
);
1136 DrawRadioBitmap(dc
, size
, flags
);
1142 wxBitmap
wxGTKRenderer::GetLineWrapBitmap() const
1144 if ( !m_bmpLineWrap
.Ok() )
1146 // the line wrap bitmap as used by GTK+
1147 #define line_wrap_width 6
1148 #define line_wrap_height 9
1149 static const char line_wrap_bits
[] =
1151 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1154 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1155 if ( !bmpLineWrap
.Ok() )
1157 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1161 wxConstCast(this, wxGTKRenderer
)->m_bmpLineWrap
= bmpLineWrap
;
1165 return m_bmpLineWrap
;
1169 void wxGTKRenderer::DrawToolBarButton(wxDC
& dc
,
1170 const wxString
& label
,
1171 const wxBitmap
& bitmap
,
1172 const wxRect
& rectOrig
,
1174 long WXUNUSED(style
),
1177 // we don't draw the separators at all
1178 if ( !label
.empty() || bitmap
.Ok() )
1180 wxRect rect
= rectOrig
;
1181 rect
.Deflate(BORDER_THICKNESS
);
1183 if ( flags
& wxCONTROL_PRESSED
)
1185 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
, &rect
);
1187 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), rect
);
1189 else if ( flags
& wxCONTROL_CURRENT
)
1191 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rect
);
1193 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rect
);
1196 if(tbarStyle
& wxTB_TEXT
)
1198 if(tbarStyle
& wxTB_HORIZONTAL
)
1200 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1204 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
1209 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
1210 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
1211 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
1215 #endif // wxUSE_TOOLBAR
1217 // ----------------------------------------------------------------------------
1219 // ----------------------------------------------------------------------------
1223 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1225 wxCoord
*extraSpaceBeyond
) const
1228 rectText
= wxStdRenderer::GetTextClientArea(text
, rect
, extraSpaceBeyond
);
1230 if ( text
->WrapLines() )
1232 // leave enough for the line wrap bitmap indicator
1233 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1235 rectText
.width
-= widthMark
;
1237 if ( extraSpaceBeyond
)
1238 *extraSpaceBeyond
= widthMark
;
1244 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1246 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1248 // for a mono bitmap he colours it appears in depends on the current text
1249 // colours, so set them correctly
1251 if ( bmpLineWrap
.GetDepth() == 1 )
1253 colFgOld
= dc
.GetTextForeground();
1255 // FIXME: I wonder what should we do if the background is black too?
1256 dc
.SetTextForeground(*wxBLACK
);
1259 dc
.DrawBitmap(bmpLineWrap
,
1260 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1262 if ( colFgOld
.Ok() )
1264 // restore old colour
1265 dc
.SetTextForeground(colFgOld
);
1269 #endif // wxUSE_TEXTCTRL
1271 // ----------------------------------------------------------------------------
1273 // ----------------------------------------------------------------------------
1277 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1278 const wxRect
& rectOrig
,
1280 const wxString
& label
,
1281 const wxBitmap
& bitmap
,
1285 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1286 #define REVERSE_FOR_VERTICAL(X,Y) \
1287 SELECT_FOR_VERTICAL(X,Y) \
1289 SELECT_FOR_VERTICAL(Y,X)
1291 wxRect rect
= rectOrig
;
1293 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1295 // the current tab is drawn indented (to the top for default case) and
1296 // bigger than the other ones
1297 const wxSize indent
= GetTabIndent();
1298 if ( flags
& wxCONTROL_SELECTED
)
1300 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1301 SELECT_FOR_VERTICAL( 0, indent
.y
));
1305 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1312 rect
.height
+= indent
.y
;
1319 rect
.width
+= indent
.x
;
1324 // selected tab has different colour
1325 wxColour col
= flags
& wxCONTROL_SELECTED
1326 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1327 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1328 DrawSolidRect(dc
, col
, rect
);
1330 if ( flags
& wxCONTROL_FOCUSED
)
1332 // draw the focus rect
1333 wxRect rectBorder
= rect
;
1334 rectBorder
.Deflate(4, 3);
1335 if ( dir
== wxBOTTOM
)
1336 rectBorder
.Offset(0, -1);
1337 if ( dir
== wxRIGHT
)
1338 rectBorder
.Offset(-1, 0);
1340 DrawRect(dc
, &rectBorder
, m_penBlack
);
1343 // draw the text, image and the focus around them (if necessary)
1344 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1345 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1347 rectLabel
.Deflate(1, 1);
1350 // draw it horizontally into memory and rotate for screen
1352 wxBitmap bitmapRotated
,
1353 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1354 rectLabel
.y
+ rectLabel
.height
);
1355 dcMem
.SelectObject(bitmapMem
);
1356 dcMem
.SetBackground(dc
.GetBackground());
1357 dcMem
.SetFont(dc
.GetFont());
1358 dcMem
.SetTextForeground(dc
.GetTextForeground());
1362 wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) )
1365 #endif // wxUSE_IMAGE
1367 dcMem
.DrawLabel(label
, bitmapRotated
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1368 dcMem
.SelectObject(wxNullBitmap
);
1369 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1371 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
))
1375 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1379 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1382 // now draw the tab itself
1383 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1384 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1385 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1386 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1392 // left orientation looks like top but IsVertical makes x and y reversed
1394 // top is not vertical so use coordinates in written order
1395 dc
.SetPen(m_penHighlight
);
1396 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1397 REVERSE_FOR_VERTICAL(x
, y
));
1398 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
),
1399 REVERSE_FOR_VERTICAL(x2
, y
));
1401 dc
.SetPen(m_penBlack
);
1402 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1403 REVERSE_FOR_VERTICAL(x2
, y
));
1405 dc
.SetPen(m_penDarkGrey
);
1406 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1407 REVERSE_FOR_VERTICAL(x2
- 1, y
+ 1));
1409 if ( flags
& wxCONTROL_SELECTED
)
1411 dc
.SetPen(m_penLightGrey
);
1413 // overwrite the part of the border below this tab
1414 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1415 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1417 // and the shadow of the tab to the left of us
1418 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ 2),
1419 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1424 // right orientation looks like bottom but IsVertical makes x and y reversed
1426 // bottom is not vertical so use coordinates in written order
1427 dc
.SetPen(m_penHighlight
);
1429 // we need to continue one pixel further to overwrite the corner of
1430 // the border for the selected tab
1431 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
1432 REVERSE_FOR_VERTICAL(x
, y2
));
1434 // it doesn't work like this (TODO: implement it properly)
1436 // erase the corner of the tab to the right
1437 dc
.SetPen(m_penLightGrey
);
1438 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1439 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 2));
1440 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 1));
1443 dc
.SetPen(m_penBlack
);
1444 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
),
1445 REVERSE_FOR_VERTICAL(x2
, y2
));
1446 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
1447 REVERSE_FOR_VERTICAL(x2
, y2
));
1449 dc
.SetPen(m_penDarkGrey
);
1450 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 2, y2
- 1),
1451 REVERSE_FOR_VERTICAL(x2
- 1, y2
- 1));
1452 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
1453 REVERSE_FOR_VERTICAL(x2
- 1, y2
));
1455 if ( flags
& wxCONTROL_SELECTED
)
1457 dc
.SetPen(m_penLightGrey
);
1459 // overwrite the part of the (double!) border above this tab
1460 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
1461 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
1462 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
1463 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1465 // and the shadow of the tab to the left of us
1466 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- 1),
1467 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
1473 #endif // wxUSE_NOTEBOOK
1475 // ----------------------------------------------------------------------------
1477 // ----------------------------------------------------------------------------
1481 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1483 wxOrientation orient
) const
1485 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1489 wxRect rectShaft
= GetSliderShaftRect(rect
, lenThumb
, orient
);
1490 if ( orient
== wxHORIZONTAL
)
1492 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1493 size
.y
= rectShaft
.height
;
1497 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1498 size
.x
= rectShaft
.width
;
1504 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1505 int WXUNUSED(lenThumb
),
1506 wxOrientation
WXUNUSED(orient
),
1507 long WXUNUSED(style
)) const
1509 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
1512 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
1513 const wxRect
& rectOrig
,
1514 int WXUNUSED(lenThumb
),
1515 wxOrientation
WXUNUSED(orient
),
1517 long WXUNUSED(style
),
1520 wxRect rect
= rectOrig
;
1522 // draw the border first
1523 if ( flags
& wxCONTROL_FOCUSED
)
1525 DrawRect(dc
, &rect
, m_penBlack
);
1527 else // not focused, normal
1529 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1532 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1534 // and the background
1535 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
1541 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
1542 const wxRect
& rectOrig
,
1543 wxOrientation orient
,
1544 int WXUNUSED(flags
),
1545 long WXUNUSED(style
))
1547 // draw the thumb border
1548 wxRect rect
= rectOrig
;
1549 DrawAntiRaisedBorder(dc
, &rect
);
1551 // draw the handle in the middle
1552 if ( orient
== wxVERTICAL
)
1554 rect
.height
= 2*BORDER_THICKNESS
;
1555 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
1559 rect
.width
= 2*BORDER_THICKNESS
;
1560 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
1563 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1566 #endif // wxUSE_SLIDER
1570 // ----------------------------------------------------------------------------
1572 // ----------------------------------------------------------------------------
1574 // wxGTKMenuGeometryInfo: the wxMenuGeometryInfo used by wxGTKRenderer
1575 class WXDLLEXPORT wxGTKMenuGeometryInfo
: public wxMenuGeometryInfo
1578 virtual wxSize
GetSize() const { return m_size
; }
1580 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
1581 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
1583 wxCoord
GetItemHeight() const { return m_heightItem
; }
1586 // the total size of the menu
1589 // the offset of the start of the menu item label
1592 // the offset of the start of the accel label
1595 // the height of a normal (not separator) item
1596 wxCoord m_heightItem
;
1598 friend wxMenuGeometryInfo
*
1599 wxGTKRenderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
1602 // FIXME: all constants are hardcoded but shouldn't be
1603 static const wxCoord MENU_LEFT_MARGIN
= 9;
1604 static const wxCoord MENU_RIGHT_MARGIN
= 6;
1606 static const wxCoord MENU_HORZ_MARGIN
= 6;
1607 static const wxCoord MENU_VERT_MARGIN
= 3;
1609 // the margin around bitmap/check marks (on each side)
1610 static const wxCoord MENU_BMP_MARGIN
= 2;
1612 // the margin between the labels and accel strings
1613 static const wxCoord MENU_ACCEL_MARGIN
= 8;
1615 // the separator height in pixels: in fact, strangely enough, the real height
1616 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
1618 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
1620 // the size of the standard checkmark bitmap
1621 static const wxCoord MENU_CHECK_SIZE
= 9;
1623 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
1625 const wxString
& label
,
1629 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
);
1632 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
1634 const wxMenuGeometryInfo
& gi
,
1635 const wxString
& label
,
1636 const wxString
& accel
,
1637 const wxBitmap
& bitmap
,
1641 const wxGTKMenuGeometryInfo
& geomInfo
= (const wxGTKMenuGeometryInfo
&)gi
;
1646 rect
.width
= geomInfo
.GetSize().x
;
1647 rect
.height
= geomInfo
.GetItemHeight();
1649 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
, accel
, bitmap
, &geomInfo
);
1652 void wxGTKRenderer::DoDrawMenuItem(wxDC
& dc
,
1653 const wxRect
& rectOrig
,
1654 const wxString
& label
,
1657 const wxString
& accel
,
1658 const wxBitmap
& bitmap
,
1659 const wxGTKMenuGeometryInfo
*geometryInfo
)
1661 wxRect rect
= rectOrig
;
1663 // draw the selected item specially
1664 if ( flags
& wxCONTROL_SELECTED
)
1667 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
1669 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rectIn
);
1672 rect
.Deflate(MENU_HORZ_MARGIN
, MENU_VERT_MARGIN
);
1674 // draw the bitmap: use the bitmap provided or the standard checkmark for
1675 // the checkable items
1678 wxBitmap bmp
= bitmap
;
1679 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKABLE
) )
1681 bmp
= GetCheckBitmap(flags
);
1686 rect
.SetRight(geometryInfo
->GetLabelOffset());
1687 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
1690 //else: menubar items don't have bitmaps
1695 rect
.x
= geometryInfo
->GetLabelOffset();
1696 rect
.SetRight(geometryInfo
->GetAccelOffset());
1699 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1701 // draw the accel string
1702 if ( !accel
.empty() )
1704 // menubar items shouldn't have them
1705 wxCHECK_RET( geometryInfo
, _T("accel strings only valid for menus") );
1707 rect
.x
= geometryInfo
->GetAccelOffset();
1708 rect
.SetRight(geometryInfo
->GetSize().x
);
1710 // NB: no accel index here
1711 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
1714 // draw the submenu indicator
1715 if ( flags
& wxCONTROL_ISSUBMENU
)
1717 wxCHECK_RET( geometryInfo
, _T("wxCONTROL_ISSUBMENU only valid for menus") );
1719 rect
.x
= geometryInfo
->GetSize().x
- MENU_RIGHT_MARGIN
;
1720 rect
.width
= MENU_RIGHT_MARGIN
;
1722 DrawArrow(dc
, wxRIGHT
, rect
, flags
);
1726 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
1728 const wxMenuGeometryInfo
& geomInfo
)
1730 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
1733 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
1735 wxSize size
= sizeText
;
1737 // TODO: make this configurable
1738 size
.x
+= 2*MENU_HORZ_MARGIN
;
1739 size
.y
+= 2*MENU_VERT_MARGIN
;
1744 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
1745 const wxMenu
& menu
) const
1747 // prepare the dc: for now we draw all the items with the system font
1749 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
1751 // the height of a normal item
1752 wxCoord heightText
= dc
.GetCharHeight();
1757 // the max length of label and accel strings: the menu width is the sum of
1758 // them, even if they're for different items (as the accels should be
1761 // the max length of the bitmap is never 0 as Windows always leaves enough
1762 // space for a check mark indicator
1763 wxCoord widthLabelMax
= 0,
1765 widthBmpMax
= MENU_LEFT_MARGIN
;
1767 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
1769 node
= node
->GetNext() )
1771 // height of this item
1774 wxMenuItem
*item
= node
->GetData();
1775 if ( item
->IsSeparator() )
1777 h
= MENU_SEPARATOR_HEIGHT
;
1779 else // not separator
1784 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
1785 if ( widthLabel
> widthLabelMax
)
1787 widthLabelMax
= widthLabel
;
1791 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
1792 if ( widthAccel
> widthAccelMax
)
1794 widthAccelMax
= widthAccel
;
1797 const wxBitmap
& bmp
= item
->GetBitmap();
1800 wxCoord widthBmp
= bmp
.GetWidth();
1801 if ( widthBmp
> widthBmpMax
)
1802 widthBmpMax
= widthBmp
;
1804 //else if ( item->IsCheckable() ): no need to check for this as
1805 // MENU_LEFT_MARGIN is big enough to show the check mark
1808 h
+= 2*MENU_VERT_MARGIN
;
1810 // remember the item position and height
1811 item
->SetGeometry(height
, h
);
1816 // bundle the metrics into a struct and return it
1817 wxGTKMenuGeometryInfo
*gi
= new wxGTKMenuGeometryInfo
;
1819 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
1820 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
1821 if ( widthAccelMax
> 0 )
1823 // if we actually have any accesl, add a margin
1824 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
1827 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
1829 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
1830 gi
->m_size
.y
= height
;
1835 #endif // wxUSE_MENUS
1837 // ----------------------------------------------------------------------------
1839 // ----------------------------------------------------------------------------
1841 void wxGTKRenderer::InitComboBitmaps()
1843 wxSize sizeArrow
= m_sizeScrollbarArrow
;
1849 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1851 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
1854 static const int comboButtonFlags
[ComboState_Max
] =
1862 wxRect
rect(sizeArrow
);
1865 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1867 int flags
= comboButtonFlags
[n
];
1869 dc
.SelectObject(m_bitmapsCombo
[n
]);
1870 DrawSolidRect(dc
, GetBackgroundColour(flags
), rect
);
1871 DrawArrow(dc
, wxDOWN
, rect
, flags
);
1875 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
1877 wxBitmap
*bmpPressed
,
1878 wxBitmap
*bmpDisabled
)
1880 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
1886 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
1888 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
1890 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
1892 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
1895 // ----------------------------------------------------------------------------
1897 // ----------------------------------------------------------------------------
1899 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
1903 static const wxDirection sides
[] =
1905 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
1908 wxRect rect1
, rect2
, rectInner
;
1914 rectInner
.Inflate(-2);
1916 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
1918 // find the side not to draw and also adjust the rectangles to compensate
1920 wxDirection sideToOmit
;
1924 sideToOmit
= wxDOWN
;
1926 rectInner
.height
+= 1;
1934 rectInner
.height
+= 1;
1938 sideToOmit
= wxRIGHT
;
1940 rectInner
.width
+= 1;
1944 sideToOmit
= wxLEFT
;
1948 rectInner
.width
+= 1;
1952 wxFAIL_MSG(_T("unknown arrow direction"));
1956 // the outer rect first
1958 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
1960 wxDirection side
= sides
[n
];
1961 if ( side
== sideToOmit
)
1964 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
1967 // and then the inner one
1968 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
1970 wxDirection side
= sides
[n
];
1971 if ( side
== sideToOmit
)
1974 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
1980 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
1982 const wxRect
& rectArrow
,
1985 // first of all, draw the border around it - but we don't want the border
1986 // on the side opposite to the arrow point
1987 wxRect rect
= rectArrow
;
1988 DrawArrowBorder(dc
, &rect
, dir
);
1990 // then the arrow itself
1991 DrawArrow(dc
, dir
, rect
, flags
);
1994 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
1995 // these people are just crazy :-(
1996 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2009 wxPoint ptArrow
[Point_Max
];
2011 wxColour colInside
= GetBackgroundColour(flags
);
2013 if ( flags
& wxCONTROL_DISABLED
)
2015 penShadow
[0] = m_penDarkGrey
;
2016 penShadow
[1] = m_penDarkGrey
;
2017 penShadow
[2] = wxNullPen
;
2018 penShadow
[3] = wxNullPen
;
2020 else if ( flags
& wxCONTROL_PRESSED
)
2022 penShadow
[0] = m_penDarkGrey
;
2023 penShadow
[1] = m_penHighlight
;
2024 penShadow
[2] = wxNullPen
;
2025 penShadow
[3] = m_penBlack
;
2027 else // normal arrow
2029 penShadow
[0] = m_penHighlight
;
2030 penShadow
[1] = m_penBlack
;
2031 penShadow
[2] = m_penDarkGrey
;
2032 penShadow
[3] = wxNullPen
;
2036 if ( dir
== wxUP
|| dir
== wxDOWN
)
2039 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2043 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2046 // draw the arrow interior
2047 dc
.SetPen(*wxTRANSPARENT_PEN
);
2048 dc
.SetBrush(colInside
);
2053 ptArrow
[Point_First
].x
= rect
.GetLeft();
2054 ptArrow
[Point_First
].y
= rect
.GetBottom();
2055 ptArrow
[Point_Second
].x
= middle
;
2056 ptArrow
[Point_Second
].y
= rect
.GetTop();
2057 ptArrow
[Point_Third
].x
= rect
.GetRight();
2058 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2062 ptArrow
[Point_First
] = rect
.GetPosition();
2063 ptArrow
[Point_Second
].x
= middle
;
2064 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2065 ptArrow
[Point_Third
].x
= rect
.GetRight();
2066 ptArrow
[Point_Third
].y
= rect
.GetTop();
2070 ptArrow
[Point_First
].x
= rect
.GetRight();
2071 ptArrow
[Point_First
].y
= rect
.GetTop();
2072 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2073 ptArrow
[Point_Second
].y
= middle
;
2074 ptArrow
[Point_Third
].x
= rect
.GetRight();
2075 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2079 ptArrow
[Point_First
] = rect
.GetPosition();
2080 ptArrow
[Point_Second
].x
= rect
.GetRight();
2081 ptArrow
[Point_Second
].y
= middle
;
2082 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2083 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2087 wxFAIL_MSG(_T("unknown arrow direction"));
2090 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2092 // draw the arrow border
2093 dc
.SetPen(penShadow
[0]);
2097 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2098 dc
.DrawPoint(ptArrow
[Point_First
]);
2099 if ( penShadow
[3].Ok() )
2101 dc
.SetPen(penShadow
[3]);
2102 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2103 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2105 dc
.SetPen(penShadow
[1]);
2106 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2107 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2108 dc
.DrawPoint(ptArrow
[Point_Third
]);
2109 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2110 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2111 if ( penShadow
[2].Ok() )
2113 dc
.SetPen(penShadow
[2]);
2114 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2115 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2116 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2117 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2122 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2123 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2124 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2125 if ( penShadow
[2].Ok() )
2127 dc
.SetPen(penShadow
[2]);
2128 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2129 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2131 dc
.SetPen(penShadow
[1]);
2132 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2133 dc
.DrawPoint(ptArrow
[Point_Third
]);
2137 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2138 dc
.DrawPoint(ptArrow
[Point_First
]);
2139 if ( penShadow
[2].Ok() )
2141 dc
.SetPen(penShadow
[2]);
2142 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2143 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2144 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2145 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2147 dc
.SetPen(penShadow
[1]);
2148 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2149 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2150 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2151 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2155 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2156 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2157 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2158 dc
.SetPen(penShadow
[1]);
2159 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2160 dc
.DrawPoint(ptArrow
[Point_Third
]);
2164 wxFAIL_MSG(_T("unknown arrow direction"));
2169 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2171 wxOrientation orient
)
2173 if ( orient
== wxVERTICAL
)
2175 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2177 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2179 rect
->Inflate(-1, 0);
2181 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2183 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2185 rect
->Inflate(-1, 0);
2189 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2191 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2193 rect
->Inflate(0, -1);
2195 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2197 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2199 rect
->Inflate(0, -1);
2203 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2204 wxOrientation orient
,
2208 // the thumb is never pressed never has focus border under GTK and the
2209 // scrollbar background never changes at all
2210 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2212 // we don't want the border in the direction of the scrollbar movement
2213 wxRect rectThumb
= rect
;
2214 DrawThumbBorder(dc
, &rectThumb
, orient
);
2216 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2217 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2220 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2221 wxOrientation orient
,
2223 int WXUNUSED(flags
))
2225 wxRect rectBar
= rect
;
2226 DrawThumbBorder(dc
, &rectBar
, orient
);
2227 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2230 // ----------------------------------------------------------------------------
2232 // ----------------------------------------------------------------------------
2234 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2237 if ( wxDynamicCast(window
, wxBitmapButton
) )
2242 #endif // wxUSE_BMPBUTTON
2243 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
2246 || wxDynamicCast(window
, wxButton
)
2247 # endif // wxUSE_BUTTON
2248 # if wxUSE_TOGGLEBTN
2249 || wxDynamicCast(window
, wxToggleButton
)
2250 # endif // wxUSE_TOGGLEBTN
2253 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2255 // TODO: this is ad hoc...
2256 size
->x
+= 3*window
->GetCharWidth();
2257 wxCoord minBtnHeight
= 18;
2258 if ( size
->y
< minBtnHeight
)
2259 size
->y
= minBtnHeight
;
2261 // button border width
2265 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
2267 if ( wxDynamicCast(window
, wxScrollBar
) )
2269 // we only set the width of vert scrollbars and height of the
2271 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2272 size
->y
= m_sizeScrollbarArrow
.x
;
2274 size
->x
= m_sizeScrollbarArrow
.x
;
2277 #endif // wxUSE_SCROLLBAR
2279 // take into account the border width
2280 wxStdRenderer::AdjustSize(size
, window
);
2284 // ----------------------------------------------------------------------------
2286 // ----------------------------------------------------------------------------
2288 /* Copyright (c) Julian Smart */
2289 static const char *error_xpm
[] = {
2290 /* columns rows colors chars-per-pixel */
2304 " ................. ",
2305 " ................... ",
2306 " ....................... ",
2307 " ......................... ",
2308 " ........................... ",
2309 " ...........................X ",
2310 " .............................X ",
2311 " ............................... ",
2312 " ...............................X ",
2313 " .................................X ",
2314 " .................................X ",
2315 " .................................XX ",
2316 " ...ooooooooooooooooooooooooooo...XX ",
2317 " ....ooooooooooooooooooooooooooo....X ",
2318 " ....ooooooooooooooooooooooooooo....X ",
2319 " ....ooooooooooooooooooooooooooo....XX ",
2320 " ....ooooooooooooooooooooooooooo....XX ",
2321 " ....ooooooooooooooooooooooooooo....XX ",
2322 " ...ooooooooooooooooooooooooooo...XXX ",
2323 " ...ooooooooooooooooooooooooooo...XXX ",
2324 " .................................XX ",
2325 " .................................XX ",
2326 " ...............................XXX ",
2327 " ...............................XXX ",
2328 " .............................XXX ",
2329 " ...........................XXXX ",
2330 " ...........................XXX ",
2331 " .........................XXX ",
2332 " .......................XXXX ",
2333 " X...................XXXXX ",
2334 " X.................XXXXX ",
2335 " X.............XXXXX ",
2336 " XXXX.....XXXXXXXX ",
2347 /* Copyright (c) Julian Smart */
2348 static const char *info_xpm
[] = {
2349 /* columns rows colors chars-per-pixel */
2373 " .XXXOXXXXXXXoo. ",
2374 " .XOOXXX+XXXXXo. ",
2375 " .XOOOXX+++XXXXoo. ",
2376 " .XOOXXX+++XXXXXo. ",
2377 " .XOOOXXX+++XXXXXXo. ",
2378 " .XOOXXXX+++XXXXXXo. ",
2379 " .XXXXXXX+++XXXXXXX. ",
2380 " .XXXXXXX+++XXXXXXo. ",
2381 " .XXXXXXX+++XXXXXoo. ",
2382 " .XXXXXX+++XXXXXo. ",
2383 " .XXXXXXX+XXXXXXo. ",
2384 " .XXXXXXXXXXXXo. ",
2385 " .XXXXX+++XXXoo. ",
2411 /* Copyright (c) Julian Smart */
2412 static const char *warning_xpm
[] = {
2413 /* columns rows colors chars-per-pixel */
2443 " ..XXXXO@#XXX... ",
2444 " ...XXXXO@#XXXX.. ",
2445 " ..XXXXXO@#XXXX... ",
2446 " ...XXXXXo@OXXXXX.. ",
2447 " ...XXXXXXo@OXXXXXX.. ",
2448 " ..XXXXXXX$@OXXXXXX... ",
2449 " ...XXXXXXXX@XXXXXXXX.. ",
2450 " ...XXXXXXXXXXXXXXXXXX... ",
2451 " ..XXXXXXXXXXOXXXXXXXXX.. ",
2452 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
2453 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
2454 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
2455 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
2456 " .............................. ",
2457 " .............................. ",
2475 /* Copyright (c) Julian Smart */
2476 static const char *question_xpm
[] = {
2477 /* columns rows colors chars-per-pixel */
2507 " ..XXXXoooooXXXO+ ",
2508 " ..XXooooooooooooX@.. ",
2509 " ..XoooooooooooooooXX#. ",
2510 " $%XoooooooooooooooooXX#. ",
2511 " &.XoooooooXXXXXXooooooXX.. ",
2512 " .XooooooXX.$...$XXoooooX*. ",
2513 " $.XoooooX%.$ .*oooooo=.. ",
2514 " .XooooooX.. -.XoooooX.. ",
2515 " .XoooooX..+ .XoooooX;. ",
2516 " ...XXXX..: .XoooooX;. ",
2517 " ........ >.XoooooX;. ",
2551 wxBitmap
wxGTKArtProvider::CreateBitmap(const wxArtID
& id
,
2552 const wxArtClient
& WXUNUSED(client
),
2553 const wxSize
& WXUNUSED(size
))
2555 if ( id
== wxART_INFORMATION
)
2556 return wxBitmap(info_xpm
);
2557 if ( id
== wxART_ERROR
)
2558 return wxBitmap(error_xpm
);
2559 if ( id
== wxART_WARNING
)
2560 return wxBitmap(warning_xpm
);
2561 if ( id
== wxART_QUESTION
)
2562 return wxBitmap(question_xpm
);
2563 return wxNullBitmap
;
2567 // ============================================================================
2569 // ============================================================================
2571 // ----------------------------------------------------------------------------
2572 // wxGTKInputHandler
2573 // ----------------------------------------------------------------------------
2575 bool wxGTKInputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
2576 const wxKeyEvent
& WXUNUSED(event
),
2577 bool WXUNUSED(pressed
))
2582 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
2583 const wxMouseEvent
& event
)
2585 // clicking on the control gives it focus
2586 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
2588 control
->GetInputWindow()->SetFocus();
2596 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
2597 const wxMouseEvent
& event
)
2599 if ( event
.Entering() )
2601 control
->GetInputWindow()->SetCurrent(true);
2603 else if ( event
.Leaving() )
2605 control
->GetInputWindow()->SetCurrent(false);
2617 // ----------------------------------------------------------------------------
2618 // wxGTKCheckboxInputHandler
2619 // ----------------------------------------------------------------------------
2621 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
2622 const wxKeyEvent
& event
,
2627 int keycode
= event
.GetKeyCode();
2628 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
2630 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
2639 #endif // wxUSE_CHECKBOX
2643 // ----------------------------------------------------------------------------
2644 // wxGTKTextCtrlInputHandler
2645 // ----------------------------------------------------------------------------
2647 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
2648 const wxKeyEvent
& event
,
2651 // handle only GTK-specific text bindings here, the others are handled in
2655 wxControlAction action
;
2656 int keycode
= event
.GetKeyCode();
2657 if ( event
.ControlDown() )
2662 action
= wxACTION_TEXT_HOME
;
2666 action
= wxACTION_TEXT_LEFT
;
2670 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
2674 action
= wxACTION_TEXT_END
;
2678 action
= wxACTION_TEXT_RIGHT
;
2682 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
2686 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2690 action
= wxACTION_TEXT_DOWN
;
2694 action
= wxACTION_TEXT_UP
;
2698 //delete the entire line
2699 control
->PerformAction(wxACTION_TEXT_HOME
);
2700 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2704 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
2708 else if ( event
.AltDown() )
2713 action
= wxACTION_TEXT_WORD_LEFT
;
2717 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
2721 action
= wxACTION_TEXT_WORD_RIGHT
;
2726 if ( action
!= wxACTION_NONE
)
2728 control
->PerformAction(action
);
2734 return wxStdInputHandler::HandleKey(control
, event
, pressed
);
2737 #endif // wxUSE_TEXTCTRL
2739 #endif // wxUSE_THEME_GTK