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/dcclient.h"
36 #include "wx/window.h"
40 #include "wx/bmpbuttn.h"
41 #include "wx/button.h"
42 #include "wx/checkbox.h"
43 #include "wx/listbox.h"
44 #include "wx/checklst.h"
45 #include "wx/combobox.h"
46 #include "wx/scrolbar.h"
47 #include "wx/slider.h"
48 #include "wx/textctrl.h"
49 #include "wx/toolbar.h"
50 #include "wx/statusbr.h"
52 #include "wx/settings.h"
53 #include "wx/toplevel.h"
57 #include "wx/notebook.h"
58 #include "wx/spinbutt.h"
59 #include "wx/artprov.h"
60 #ifdef wxUSE_TOGGLEBTN
61 #include "wx/tglbtn.h"
62 #endif // wxUSE_TOGGLEBTN
64 #include "wx/univ/stdrend.h"
65 #include "wx/univ/inpcons.h"
66 #include "wx/univ/inphand.h"
67 #include "wx/univ/colschem.h"
69 class wxGTKMenuGeometryInfo
;
71 // ----------------------------------------------------------------------------
73 // ----------------------------------------------------------------------------
75 // standard border size
76 static const int BORDER_THICKNESS
= 2;
78 // ----------------------------------------------------------------------------
79 // wxGTKRenderer: draw the GUI elements in GTK style
80 // ----------------------------------------------------------------------------
82 class wxGTKRenderer
: public wxStdRenderer
85 wxGTKRenderer(const wxColourScheme
*scheme
);
88 virtual void DrawFocusRect(wxWindow
* win
, wxDC
& dc
, const wxRect
& rect
, int flags
= 0);
89 virtual void DrawTextBorder(wxDC
& dc
,
93 wxRect
*rectIn
= NULL
);
94 virtual void DrawButtonLabel(wxDC
& dc
,
95 const wxString
& label
,
96 const wxBitmap
& image
,
102 virtual void DrawButtonBorder(wxDC
& dc
,
105 wxRect
*rectIn
= NULL
);
106 virtual void DrawArrow(wxDC
& dc
,
110 virtual void DrawScrollbarArrow(wxDC
& dc
,
114 virtual void DrawScrollbarThumb(wxDC
& dc
,
115 wxOrientation orient
,
118 virtual void DrawScrollbarShaft(wxDC
& dc
,
119 wxOrientation orient
,
124 virtual void DrawToolBarButton(wxDC
& dc
,
125 const wxString
& label
,
126 const wxBitmap
& bitmap
,
131 #endif // wxUSE_TOOLBAR
134 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
135 #endif // wxUSE_TEXTCTRL
138 virtual void DrawTab(wxDC
& dc
,
141 const wxString
& label
,
142 const wxBitmap
& bitmap
= wxNullBitmap
,
144 int indexAccel
= -1);
145 #endif // wxUSE_NOTEBOOK
148 virtual void DrawSliderShaft(wxDC
& dc
,
151 wxOrientation orient
,
154 wxRect
*rectShaft
= NULL
);
155 virtual void DrawSliderThumb(wxDC
& dc
,
157 wxOrientation orient
,
160 virtual void DrawSliderTicks(wxDC
& WXUNUSED(dc
),
161 const wxRect
& WXUNUSED(rect
),
162 int WXUNUSED(lenThumb
),
163 wxOrientation
WXUNUSED(orient
),
166 int WXUNUSED(step
) = 1,
167 int WXUNUSED(flags
) = 0,
168 long WXUNUSED(style
) = 0)
170 // we don't have the ticks in GTK version
172 #endif // wxUSE_SLIDER
175 virtual void DrawMenuBarItem(wxDC
& dc
,
177 const wxString
& label
,
179 int indexAccel
= -1);
180 virtual void DrawMenuItem(wxDC
& dc
,
182 const wxMenuGeometryInfo
& geometryInfo
,
183 const wxString
& label
,
184 const wxString
& accel
,
185 const wxBitmap
& bitmap
= wxNullBitmap
,
187 int indexAccel
= -1);
188 virtual void DrawMenuSeparator(wxDC
& dc
,
190 const wxMenuGeometryInfo
& geomInfo
);
191 #endif // wxUSE_MENUS
193 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
195 wxBitmap
*bmpPressed
,
196 wxBitmap
*bmpDisabled
);
198 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
200 // geometry and hit testing
202 virtual wxSize
GetScrollbarArrowSize() const
203 { return m_sizeScrollbarArrow
; }
204 #endif // wxUSE_SCROLLBAR
206 virtual wxSize
GetCheckBitmapSize() const
207 { return wxSize(10, 10); }
208 virtual wxSize
GetRadioBitmapSize() const
209 { return wxSize(11, 11); }
210 virtual wxCoord
GetCheckItemMargin() const
214 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
215 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
216 virtual wxSize
GetToolBarMargin() const
217 { return wxSize(6, 6); }
218 #endif // wxUSE_TOOLBAR
221 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
223 wxCoord
*extraSpaceBeyond
) const;
224 #endif // wxUSE_TEXTCTRL
227 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
228 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
229 #endif // wxUSE_NOTEBOOK
232 virtual wxCoord
GetSliderDim() const { return 15; }
233 virtual wxCoord
GetSliderTickLen() const { return 0; }
234 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
236 wxOrientation orient
,
237 long style
= 0) const;
238 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
240 wxOrientation orient
) const;
241 #endif // wxUSE_SLIDER
243 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
246 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
247 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
248 const wxMenu
& menu
) const;
249 #endif // wxUSE_MENUS
251 // helpers for "wxBitmap wxColourScheme::Get()"
252 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
253 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
254 void DrawUndeterminedBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
257 // overridden wxStdRenderer methods
258 virtual void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
260 virtual void DrawFrameWithLabel(wxDC
& dc
,
261 const wxString
& label
,
262 const wxRect
& rectFrame
,
263 const wxRect
& rectText
,
268 virtual void DrawCheckItemBitmap(wxDC
& dc
,
269 const wxBitmap
& bitmap
,
273 // get the colour to use for background
274 wxColour
GetBackgroundColour(int flags
) const
276 if ( flags
& wxCONTROL_PRESSED
)
277 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
278 else if ( flags
& wxCONTROL_CURRENT
)
279 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
281 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
284 // as DrawShadedRect() but the pixels in the bottom left and upper right
285 // border are drawn with the pen1, not pen2
286 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
287 const wxPen
& pen1
, const wxPen
& pen2
);
289 // used for drawing opened rectangles - draws only one side of it at once
290 // (and doesn't adjust the rect)
291 void DrawAntiShadedRectSide(wxDC
& dc
,
297 // draw an opened rect for the arrow in given direction
298 void DrawArrowBorder(wxDC
& dc
,
302 // draw two sides of the rectangle
303 void DrawThumbBorder(wxDC
& dc
,
305 wxOrientation orient
);
307 // just as DrawRaisedBorder() except that the bottom left and up right
308 // pixels of the interior rect are drawn in another colour (i.e. the inner
309 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
310 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
312 // draw inner GTK shadow
313 void DrawInnerShadedRect(wxDC
& dc
, wxRect
*rect
);
315 // get the line wrap indicator bitmap
316 wxBitmap
GetLineWrapBitmap() const;
318 virtual wxBitmap
GetCheckBitmap(int flags
);
319 virtual wxBitmap
GetRadioBitmap(int flags
);
321 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
323 void DrawUpZag(wxDC
& dc
,
324 wxCoord x1
, wxCoord x2
,
325 wxCoord y1
, wxCoord y2
);
326 void DrawDownZag(wxDC
& dc
,
327 wxCoord x1
, wxCoord x2
,
328 wxCoord y1
, wxCoord y2
);
330 // draw the radio button bitmap for the given state
331 void DrawRadioButtonBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
333 // common part of DrawMenuItem() and DrawMenuBarItem()
334 void DoDrawMenuItem(wxDC
& dc
,
336 const wxString
& label
,
339 const wxString
& accel
= wxEmptyString
,
340 const wxBitmap
& bitmap
= wxNullBitmap
,
341 const wxGTKMenuGeometryInfo
*geometryInfo
= NULL
);
343 // initialize the combo bitmaps
344 void InitComboBitmaps();
346 virtual wxBitmap
GetFrameButtonBitmap(FrameButtonType
WXUNUSED(type
))
353 wxSize m_sizeScrollbarArrow
;
358 // the checkbox and radio button bitmaps: first row is for the normal,
359 // second for the pressed state and the columns are for checked, unchecked
360 // and undeterminated respectively
361 wxBitmap m_bitmapsCheckbox
[IndicatorState_MaxCtrl
][IndicatorStatus_Max
],
362 m_bitmapsRadiobtn
[IndicatorState_MaxCtrl
][IndicatorStatus_Max
];
364 // the line wrap bitmap (drawn at the end of wrapped lines)
365 wxBitmap m_bmpLineWrap
;
367 // the combobox bitmaps
377 wxBitmap m_bitmapsCombo
[ComboState_Max
];
380 // ----------------------------------------------------------------------------
381 // wxGTKInputHandler and derived classes: process the keyboard and mouse
382 // messages according to GTK standards
383 // ----------------------------------------------------------------------------
385 class wxGTKInputHandler
: public wxInputHandler
388 wxGTKInputHandler() { }
390 virtual bool HandleKey(wxInputConsumer
*control
,
391 const wxKeyEvent
& event
,
393 virtual bool HandleMouse(wxInputConsumer
*control
,
394 const wxMouseEvent
& event
);
395 virtual bool HandleMouseMove(wxInputConsumer
*control
,
396 const wxMouseEvent
& event
);
401 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
404 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
405 : wxStdScrollBarInputHandler(renderer
, handler
) { }
408 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
410 // only arrows and the thumb can be highlighted
411 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
414 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
417 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
419 // only arrows can be pressed
423 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
426 // any button can be used to drag the scrollbar under GTK+
427 virtual bool IsAllowedButton(int WXUNUSED(button
)) const { return true; }
431 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
432 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
436 #endif // wxUSE_SCROLLBAR
440 class wxGTKCheckboxInputHandler
: public wxStdInputHandler
443 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
444 : wxStdInputHandler(handler
) { }
446 virtual bool HandleKey(wxInputConsumer
*control
,
447 const wxKeyEvent
& event
,
451 #endif // wxUSE_CHECKBOX
455 class wxGTKTextCtrlInputHandler
: public wxStdInputHandler
458 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
459 : wxStdInputHandler(handler
) { }
461 virtual bool HandleKey(wxInputConsumer
*control
,
462 const wxKeyEvent
& event
,
466 #endif // wxUSE_TEXTCTRL
468 // ----------------------------------------------------------------------------
469 // wxGTKColourScheme: uses the standard GTK colours
470 // ----------------------------------------------------------------------------
472 class wxGTKColourScheme
: public wxColourScheme
475 virtual wxColour
Get(StdColour col
) const;
476 virtual wxColour
GetBackground(wxWindow
*win
) const;
479 // ----------------------------------------------------------------------------
481 // ----------------------------------------------------------------------------
483 class wxGTKArtProvider
: public wxArtProvider
486 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
487 const wxArtClient
& client
,
491 // ----------------------------------------------------------------------------
493 // ----------------------------------------------------------------------------
495 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
497 class wxGTKTheme
: public wxTheme
501 virtual ~wxGTKTheme();
503 virtual wxRenderer
*GetRenderer();
504 virtual wxArtProvider
*GetArtProvider();
505 virtual wxInputHandler
*GetInputHandler(const wxString
& control
,
506 wxInputConsumer
*consumer
);
507 virtual wxColourScheme
*GetColourScheme();
510 wxGTKRenderer
*m_renderer
;
512 wxGTKArtProvider
*m_artProvider
;
514 // the names of the already created handlers and the handlers themselves
515 // (these arrays are synchronized)
516 wxSortedArrayString m_handlerNames
;
517 wxArrayHandlers m_handlers
;
519 wxGTKColourScheme
*m_scheme
;
521 WX_DECLARE_THEME(gtk
)
524 // ============================================================================
526 // ============================================================================
528 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
530 // ----------------------------------------------------------------------------
532 // ----------------------------------------------------------------------------
534 wxGTKTheme::wxGTKTheme()
538 m_artProvider
= NULL
;
541 wxGTKTheme::~wxGTKTheme()
545 delete m_artProvider
;
548 wxRenderer
*wxGTKTheme::GetRenderer()
552 m_renderer
= new wxGTKRenderer(GetColourScheme());
558 wxArtProvider
*wxGTKTheme::GetArtProvider()
560 if ( !m_artProvider
)
562 m_artProvider
= new wxGTKArtProvider
;
565 return m_artProvider
;
568 wxColourScheme
*wxGTKTheme::GetColourScheme()
572 m_scheme
= new wxGTKColourScheme
;
577 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
,
578 wxInputConsumer
*consumer
)
580 wxInputHandler
*handler
= NULL
;
581 int n
= m_handlerNames
.Index(control
);
582 if ( n
== wxNOT_FOUND
)
584 static wxGTKInputHandler s_handlerDef
;
586 wxInputHandler
* const
587 handlerStd
= consumer
->DoGetStdInputHandler(&s_handlerDef
);
589 // create a new handler
591 if ( control
== wxINP_HANDLER_CHECKBOX
)
593 static wxGTKCheckboxInputHandler
s_handler(handlerStd
);
595 handler
= &s_handler
;
598 #endif // wxUSE_CHECKBOX
600 if ( control
== wxINP_HANDLER_SCROLLBAR
)
602 static wxGTKScrollBarInputHandler
s_handler(m_renderer
, handlerStd
);
604 handler
= &s_handler
;
607 #endif // wxUSE_SCROLLBAR
609 if ( control
== wxINP_HANDLER_TEXTCTRL
)
611 static wxGTKTextCtrlInputHandler
s_handler(handlerStd
);
613 handler
= &s_handler
;
616 #endif // wxUSE_TEXTCTRL
618 // no special handler for this control
619 handler
= handlerStd
;
622 n
= m_handlerNames
.Add(control
);
623 m_handlers
.Insert(handler
, n
);
625 else // we already have it
627 handler
= m_handlers
[n
];
633 // ============================================================================
635 // ============================================================================
637 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
640 if ( win
->UseBgCol() )
642 // use the user specified colour
643 col
= win
->GetBackgroundColour();
646 if ( !win
->ShouldInheritColours() )
648 // doesn't depend on the state
656 int flags
= win
->GetStateFlags();
658 // the colour set by the user should be used for the normal state
659 // and for the states for which we don't have any specific colours
660 if ( !col
.IsOk() || (flags
!= 0) )
663 if ( wxDynamicCast(win
, wxScrollBar
) )
664 col
= Get(SCROLLBAR
);
666 #endif //wxUSE_SCROLLBAR
667 if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
668 col
= Get(CONTROL_CURRENT
);
669 else if ( flags
& wxCONTROL_PRESSED
)
670 col
= Get(CONTROL_PRESSED
);
679 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
684 case WINDOW
: return *wxWHITE
;
686 case SHADOW_DARK
: return *wxBLACK
;
687 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
688 case SHADOW_IN
: return wxColour(0xd6d6d6);
689 case SHADOW_OUT
: return wxColour(0x969696);
691 case CONTROL
: return wxColour(0xd6d6d6);
692 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
693 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
695 case CONTROL_TEXT
: return *wxBLACK
;
696 case CONTROL_TEXT_DISABLED
:
697 return wxColour(0x757575);
698 case CONTROL_TEXT_DISABLED_SHADOW
:
702 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
704 case HIGHLIGHT
: return wxColour(0x9c0000);
705 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
707 case GAUGE
: return Get(CONTROL_CURRENT
);
709 case TITLEBAR
: return wxColour(0xaeaaae);
710 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
711 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
712 case TITLEBAR_ACTIVE_TEXT
:
715 case DESKTOP
: return *wxBLACK
;
719 wxFAIL_MSG(wxT("invalid standard colour"));
724 // ============================================================================
726 // ============================================================================
728 // ----------------------------------------------------------------------------
730 // ----------------------------------------------------------------------------
732 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
733 : wxStdRenderer(scheme
)
735 m_sizeScrollbarArrow
= wxSize(15, 14);
737 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
));
740 // ----------------------------------------------------------------------------
742 // ----------------------------------------------------------------------------
744 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
750 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
755 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
756 rect
.GetLeft(), rect
.GetBottom() + 1);
760 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
761 rect
.GetRight() + 1, rect
.GetTop());
765 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
766 rect
.GetRight(), rect
.GetBottom() + 1);
770 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
771 rect
.GetRight() + 1, rect
.GetBottom());
775 wxFAIL_MSG(wxT("unknown rectangle side"));
779 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
780 const wxPen
& pen1
, const wxPen
& pen2
)
782 // draw the rectangle
784 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
785 rect
->GetLeft(), rect
->GetBottom() + 1);
786 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
787 rect
->GetRight() + 1, rect
->GetTop());
789 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
790 rect
->GetRight(), rect
->GetBottom());
791 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
792 rect
->GetRight() + 1, rect
->GetBottom());
798 void wxGTKRenderer::DrawInnerShadedRect(wxDC
& dc
, wxRect
*rect
)
800 DrawAntiShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
801 DrawAntiShadedRect(dc
, rect
, m_penBlack
, m_penHighlight
);
804 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
806 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
807 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
810 void wxGTKRenderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
812 DrawAntiShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
813 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
817 wxGTKRenderer::DrawFocusRect(wxWindow
* WXUNUSED(win
), wxDC
& dc
, const wxRect
& rect
, int WXUNUSED(flags
))
819 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
820 wxRect rectFocus
= rect
;
821 DrawRect(dc
, &rectFocus
, m_penBlack
);
824 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
826 const wxRect
& rectOrig
,
830 wxRect rect
= rectOrig
;
832 if ( border
!= wxBORDER_NONE
)
834 if ( flags
& wxCONTROL_FOCUSED
)
836 DrawRect(dc
, &rect
, m_penBlack
);
837 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
841 DrawInnerShadedRect(dc
, &rect
);
849 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
850 const wxString
& label
,
851 const wxBitmap
& image
,
858 // no focus rect around buttons label in GTK+
859 wxStdRenderer::DrawButtonLabel(dc
, label
, image
, rect
, flags
,
860 alignment
, indexAccel
, rectBounds
);
863 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
864 const wxRect
& rectTotal
,
868 wxRect rect
= rectTotal
;
870 if ( flags
& wxCONTROL_PRESSED
)
872 // button pressed: draw a black border around it and an inward shade
873 DrawRect(dc
, &rect
, m_penBlack
);
875 DrawInnerShadedRect(dc
, &rect
);
877 else // button not pressed
879 if ( flags
& wxCONTROL_ISDEFAULT
)
884 if ( flags
& wxCONTROL_FOCUSED
)
886 // button is currently default: add an extra border around it
887 DrawRect(dc
, &rect
, m_penBlack
);
890 // now draw a normal button
891 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
892 DrawAntiShadedRect(dc
, &rect
, GetBackgroundColour(flags
), m_penDarkGrey
);
899 // ----------------------------------------------------------------------------
901 // ----------------------------------------------------------------------------
903 void wxGTKRenderer::DrawFrameWithLabel(wxDC
& dc
,
904 const wxString
& label
,
905 const wxRect
& rectFrame
,
906 const wxRect
& rectTextOrig
,
911 wxRect
rectText(rectTextOrig
);
912 rectText
.Inflate(1, 0);
915 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
917 rectLabel
.width
+= 2;
919 DrawFrameWithoutLabel(dc
, rectFrame
, rectLabel
);
921 // GTK+ does it like this
922 dc
.SetPen(m_penHighlight
);
923 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
924 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
927 // ----------------------------------------------------------------------------
928 // check/radio buttons
929 // ----------------------------------------------------------------------------
931 void wxGTKRenderer::DrawCheckItemBitmap(wxDC
& dc
,
932 const wxBitmap
& bitmap
,
936 // never draw the focus rect around the check indicators here
937 DrawCheckButton(dc
, wxEmptyString
, bitmap
, rect
, flags
& ~wxCONTROL_FOCUSED
);
940 void wxGTKRenderer::DrawUndeterminedBitmap(wxDC
& dc
,
941 const wxRect
& rectTotal
,
944 // FIXME: For sure it is not GTK look but it is better than nothing.
945 // Show me correct look and I will immediatelly make it better (ABX)
946 wxRect rect
= rectTotal
;
952 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
953 col2
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
957 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
958 col2
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
961 dc
.SetPen(*wxTRANSPARENT_PEN
);
963 dc
.DrawRectangle(rect
);
966 dc
.DrawRectangle(rect
);
969 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
970 const wxRect
& rectTotal
,
973 wxRect rect
= rectTotal
;
974 DrawAntiRaisedBorder(dc
, &rect
);
976 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
977 dc
.SetPen(wxPen(col
));
978 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
981 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
982 //else: it is SHADOW_IN, leave as is
984 dc
.SetPen(*wxTRANSPARENT_PEN
);
986 dc
.DrawRectangle(rect
);
989 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
991 wxRect rect
= rectTotal
;
992 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
993 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
995 dc
.SetPen(*wxTRANSPARENT_PEN
);
996 dc
.SetBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
));
997 dc
.DrawRectangle(rect
);
1000 void wxGTKRenderer::DrawRadioButtonBitmap(wxDC
& dc
,
1006 xRight
= rect
.GetRight(),
1007 yBottom
= rect
.GetBottom();
1009 wxCoord yMid
= (y
+ yBottom
) / 2;
1011 // then draw the upper half
1012 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1013 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1014 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1017 if ( flags
& wxCONTROL_CHECKED
)
1018 dc
.SetPen(m_penBlack
);
1019 else if ( flags
& wxCONTROL_PRESSED
)
1020 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
)));
1021 else // unchecked and unpressed
1025 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1027 // and then the lower one
1028 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1029 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1030 if ( !(flags
& wxCONTROL_CHECKED
) )
1031 dc
.SetPen(m_penDarkGrey
);
1032 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1034 if ( !(flags
& wxCONTROL_CHECKED
) )
1035 drawIt
= true; // with the same pen
1036 else if ( flags
& wxCONTROL_PRESSED
)
1038 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
)));
1041 else // checked and unpressed
1045 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1048 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1054 wxCoord xMid
= (x1
+ x2
) / 2;
1055 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1056 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1059 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1065 wxCoord xMid
= (x1
+ x2
) / 2;
1066 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1067 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1070 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1072 if ( !m_bitmapsCheckbox
[0][0].IsOk() )
1074 // init the bitmaps once only
1076 wxSize size
= GetCheckBitmapSize();
1077 rect
.width
= size
.x
;
1078 rect
.height
= size
.y
;
1079 for ( int i
= 0; i
< 2; i
++ )
1081 for ( int j
= 0; j
< 3; j
++ )
1082 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1088 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1089 DrawCheckBitmap(dc
, rect
);
1092 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1093 DrawUncheckBitmap(dc
, rect
, false);
1095 // normal undeterminated
1096 dc
.SelectObject(m_bitmapsCheckbox
[0][2]);
1097 DrawUndeterminedBitmap(dc
, rect
, false);
1100 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1102 // pressed unchecked
1103 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1104 DrawUncheckBitmap(dc
, rect
, true);
1106 // pressed undeterminated
1107 dc
.SelectObject(m_bitmapsCheckbox
[1][2]);
1108 DrawUndeterminedBitmap(dc
, rect
, true);
1111 IndicatorState state
;
1112 IndicatorStatus status
;
1113 GetIndicatorsFromFlags(flags
, state
, status
);
1115 // disabled looks the same as normal
1116 if ( state
== IndicatorState_Disabled
)
1117 state
= IndicatorState_Normal
;
1119 return m_bitmapsCheckbox
[state
][status
];
1122 wxBitmap
wxGTKRenderer::GetRadioBitmap(int flags
)
1124 IndicatorState state
;
1125 IndicatorStatus status
;
1126 GetIndicatorsFromFlags(flags
, state
, status
);
1128 wxBitmap
& bmp
= m_bitmapsRadiobtn
[state
][status
];
1131 const wxSize size
= GetRadioBitmapSize();
1134 bmp
.Create(size
.x
, size
.y
);
1135 dc
.SelectObject(bmp
);
1137 DrawRadioButtonBitmap(dc
, size
, flags
);
1143 wxBitmap
wxGTKRenderer::GetLineWrapBitmap() const
1145 if ( !m_bmpLineWrap
.IsOk() )
1147 // the line wrap bitmap as used by GTK+
1148 #define line_wrap_width 6
1149 #define line_wrap_height 9
1150 static const char line_wrap_bits
[] =
1152 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1155 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1156 if ( !bmpLineWrap
.IsOk() )
1158 wxFAIL_MSG( wxT("Failed to create line wrap XBM") );
1162 wxConstCast(this, wxGTKRenderer
)->m_bmpLineWrap
= bmpLineWrap
;
1166 return m_bmpLineWrap
;
1170 void wxGTKRenderer::DrawToolBarButton(wxDC
& dc
,
1171 const wxString
& label
,
1172 const wxBitmap
& bitmap
,
1173 const wxRect
& rectOrig
,
1175 long WXUNUSED(style
),
1178 // we don't draw the separators at all
1179 if ( !label
.empty() || bitmap
.IsOk() )
1181 wxRect rect
= rectOrig
;
1182 rect
.Deflate(BORDER_THICKNESS
);
1184 if ( flags
& wxCONTROL_PRESSED
)
1186 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
, &rect
);
1188 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), rect
);
1190 else if ( flags
& wxCONTROL_CURRENT
)
1192 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rect
);
1194 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rect
);
1197 if(tbarStyle
& wxTB_TEXT
)
1199 if(tbarStyle
& wxTB_HORIZONTAL
)
1201 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1205 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
1210 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
1211 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
1212 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
1216 #endif // wxUSE_TOOLBAR
1218 // ----------------------------------------------------------------------------
1220 // ----------------------------------------------------------------------------
1224 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1226 wxCoord
*extraSpaceBeyond
) const
1229 rectText
= wxStdRenderer::GetTextClientArea(text
, rect
, extraSpaceBeyond
);
1231 if ( text
->WrapLines() )
1233 // leave enough for the line wrap bitmap indicator
1234 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1236 rectText
.width
-= widthMark
;
1238 if ( extraSpaceBeyond
)
1239 *extraSpaceBeyond
= widthMark
;
1245 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1247 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1249 // for a mono bitmap he colours it appears in depends on the current text
1250 // colours, so set them correctly
1252 if ( bmpLineWrap
.GetDepth() == 1 )
1254 colFgOld
= dc
.GetTextForeground();
1256 // FIXME: I wonder what should we do if the background is black too?
1257 dc
.SetTextForeground(*wxBLACK
);
1260 dc
.DrawBitmap(bmpLineWrap
,
1261 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1263 if ( colFgOld
.IsOk() )
1265 // restore old colour
1266 dc
.SetTextForeground(colFgOld
);
1270 #endif // wxUSE_TEXTCTRL
1272 // ----------------------------------------------------------------------------
1274 // ----------------------------------------------------------------------------
1278 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1279 const wxRect
& rectOrig
,
1281 const wxString
& label
,
1282 const wxBitmap
& bitmap
,
1286 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1287 #define REVERSE_FOR_VERTICAL(X,Y) \
1288 SELECT_FOR_VERTICAL(X,Y) \
1290 SELECT_FOR_VERTICAL(Y,X)
1292 wxRect rect
= rectOrig
;
1294 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1296 // the current tab is drawn indented (to the top for default case) and
1297 // bigger than the other ones
1298 const wxSize indent
= GetTabIndent();
1299 if ( flags
& wxCONTROL_SELECTED
)
1301 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1302 SELECT_FOR_VERTICAL( 0, indent
.y
));
1306 wxFAIL_MSG(wxT("invaild notebook tab orientation"));
1313 rect
.height
+= indent
.y
;
1320 rect
.width
+= indent
.x
;
1325 // selected tab has different colour
1326 wxColour col
= flags
& wxCONTROL_SELECTED
1327 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1328 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1329 DrawSolidRect(dc
, col
, rect
);
1331 if ( flags
& wxCONTROL_FOCUSED
)
1333 // draw the focus rect
1334 wxRect rectBorder
= rect
;
1335 rectBorder
.Deflate(4, 3);
1336 if ( dir
== wxBOTTOM
)
1337 rectBorder
.Offset(0, -1);
1338 if ( dir
== wxRIGHT
)
1339 rectBorder
.Offset(-1, 0);
1341 DrawRect(dc
, &rectBorder
, m_penBlack
);
1344 // draw the text, image and the focus around them (if necessary)
1345 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1346 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1348 rectLabel
.Deflate(1, 1);
1351 // draw it horizontally into memory and rotate for screen
1353 wxBitmap bitmapRotated
,
1354 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1355 rectLabel
.y
+ rectLabel
.height
);
1356 dcMem
.SelectObject(bitmapMem
);
1357 dcMem
.SetBackground(dc
.GetBackground());
1358 dcMem
.SetFont(dc
.GetFont());
1359 dcMem
.SetTextForeground(dc
.GetTextForeground());
1363 wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) )
1366 #endif // wxUSE_IMAGE
1368 dcMem
.DrawLabel(label
, bitmapRotated
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1369 dcMem
.SelectObject(wxNullBitmap
);
1370 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1372 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
))
1376 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1380 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1383 // now draw the tab itself
1384 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1385 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1386 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1387 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1393 // left orientation looks like top but IsVertical makes x and y reversed
1395 // top is not vertical so use coordinates in written order
1396 dc
.SetPen(m_penHighlight
);
1397 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1398 REVERSE_FOR_VERTICAL(x
, y
));
1399 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
),
1400 REVERSE_FOR_VERTICAL(x2
, y
));
1402 dc
.SetPen(m_penBlack
);
1403 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1404 REVERSE_FOR_VERTICAL(x2
, y
));
1406 dc
.SetPen(m_penDarkGrey
);
1407 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1408 REVERSE_FOR_VERTICAL(x2
- 1, y
+ 1));
1410 if ( flags
& wxCONTROL_SELECTED
)
1412 dc
.SetPen(m_penLightGrey
);
1414 // overwrite the part of the border below this tab
1415 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1416 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1418 // and the shadow of the tab to the left of us
1419 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ 2),
1420 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1425 // right orientation looks like bottom but IsVertical makes x and y reversed
1427 // bottom is not vertical so use coordinates in written order
1428 dc
.SetPen(m_penHighlight
);
1430 // we need to continue one pixel further to overwrite the corner of
1431 // the border for the selected tab
1432 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
1433 REVERSE_FOR_VERTICAL(x
, y2
));
1435 // it doesn't work like this (TODO: implement it properly)
1437 // erase the corner of the tab to the right
1438 dc
.SetPen(m_penLightGrey
);
1439 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1440 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 2));
1441 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 1));
1444 dc
.SetPen(m_penBlack
);
1445 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
),
1446 REVERSE_FOR_VERTICAL(x2
, y2
));
1447 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
1448 REVERSE_FOR_VERTICAL(x2
, y2
));
1450 dc
.SetPen(m_penDarkGrey
);
1451 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 2, y2
- 1),
1452 REVERSE_FOR_VERTICAL(x2
- 1, y2
- 1));
1453 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
1454 REVERSE_FOR_VERTICAL(x2
- 1, y2
));
1456 if ( flags
& wxCONTROL_SELECTED
)
1458 dc
.SetPen(m_penLightGrey
);
1460 // overwrite the part of the (double!) border above this tab
1461 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
1462 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
1463 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
1464 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1466 // and the shadow of the tab to the left of us
1467 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- 1),
1468 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
1474 #endif // wxUSE_NOTEBOOK
1476 // ----------------------------------------------------------------------------
1478 // ----------------------------------------------------------------------------
1482 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1484 wxOrientation orient
) const
1486 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1490 wxRect rectShaft
= GetSliderShaftRect(rect
, lenThumb
, orient
);
1491 if ( orient
== wxHORIZONTAL
)
1493 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1494 size
.y
= rectShaft
.height
;
1498 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1499 size
.x
= rectShaft
.width
;
1505 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1506 int WXUNUSED(lenThumb
),
1507 wxOrientation
WXUNUSED(orient
),
1508 long WXUNUSED(style
)) const
1510 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
1513 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
1514 const wxRect
& rectOrig
,
1515 int WXUNUSED(lenThumb
),
1516 wxOrientation
WXUNUSED(orient
),
1518 long WXUNUSED(style
),
1521 wxRect rect
= rectOrig
;
1523 // draw the border first
1524 if ( flags
& wxCONTROL_FOCUSED
)
1526 DrawRect(dc
, &rect
, m_penBlack
);
1528 else // not focused, normal
1530 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1533 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1535 // and the background
1536 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
1542 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
1543 const wxRect
& rectOrig
,
1544 wxOrientation orient
,
1545 int WXUNUSED(flags
),
1546 long WXUNUSED(style
))
1548 // draw the thumb border
1549 wxRect rect
= rectOrig
;
1550 DrawAntiRaisedBorder(dc
, &rect
);
1552 // draw the handle in the middle
1553 if ( orient
== wxVERTICAL
)
1555 rect
.height
= 2*BORDER_THICKNESS
;
1556 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
1560 rect
.width
= 2*BORDER_THICKNESS
;
1561 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
1564 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1567 #endif // wxUSE_SLIDER
1571 // ----------------------------------------------------------------------------
1573 // ----------------------------------------------------------------------------
1575 // wxGTKMenuGeometryInfo: the wxMenuGeometryInfo used by wxGTKRenderer
1576 class wxGTKMenuGeometryInfo
: public wxMenuGeometryInfo
1579 virtual wxSize
GetSize() const { return m_size
; }
1581 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
1582 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
1584 wxCoord
GetItemHeight() const { return m_heightItem
; }
1587 // the total size of the menu
1590 // the offset of the start of the menu item label
1593 // the offset of the start of the accel label
1596 // the height of a normal (not separator) item
1597 wxCoord m_heightItem
;
1599 friend wxMenuGeometryInfo
*
1600 wxGTKRenderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
1603 // FIXME: all constants are hardcoded but shouldn't be
1604 static const wxCoord MENU_LEFT_MARGIN
= 9;
1605 static const wxCoord MENU_RIGHT_MARGIN
= 6;
1607 static const wxCoord MENU_HORZ_MARGIN
= 6;
1608 static const wxCoord MENU_VERT_MARGIN
= 3;
1610 // the margin around bitmap/check marks (on each side)
1611 static const wxCoord MENU_BMP_MARGIN
= 2;
1613 // the margin between the labels and accel strings
1614 static const wxCoord MENU_ACCEL_MARGIN
= 8;
1616 // the separator height in pixels: in fact, strangely enough, the real height
1617 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
1619 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
1621 // the size of the standard checkmark bitmap
1622 static const wxCoord MENU_CHECK_SIZE
= 9;
1624 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
1626 const wxString
& label
,
1630 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
);
1633 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
1635 const wxMenuGeometryInfo
& gi
,
1636 const wxString
& label
,
1637 const wxString
& accel
,
1638 const wxBitmap
& bitmap
,
1642 const wxGTKMenuGeometryInfo
& geomInfo
= (const wxGTKMenuGeometryInfo
&)gi
;
1647 rect
.width
= geomInfo
.GetSize().x
;
1648 rect
.height
= geomInfo
.GetItemHeight();
1650 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
, accel
, bitmap
, &geomInfo
);
1653 void wxGTKRenderer::DoDrawMenuItem(wxDC
& dc
,
1654 const wxRect
& rectOrig
,
1655 const wxString
& label
,
1658 const wxString
& accel
,
1659 const wxBitmap
& bitmap
,
1660 const wxGTKMenuGeometryInfo
*geometryInfo
)
1662 wxRect rect
= rectOrig
;
1664 // draw the selected item specially
1665 if ( flags
& wxCONTROL_SELECTED
)
1668 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
1670 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rectIn
);
1673 rect
.Deflate(MENU_HORZ_MARGIN
, MENU_VERT_MARGIN
);
1675 // draw the bitmap: use the bitmap provided or the standard checkmark for
1676 // the checkable items
1679 wxBitmap bmp
= bitmap
;
1680 if ( !bmp
.IsOk() && (flags
& wxCONTROL_CHECKABLE
) )
1682 bmp
= GetCheckBitmap(flags
);
1687 rect
.SetRight(geometryInfo
->GetLabelOffset());
1688 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
1691 //else: menubar items don't have bitmaps
1696 rect
.x
= geometryInfo
->GetLabelOffset();
1697 rect
.SetRight(geometryInfo
->GetAccelOffset());
1700 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1702 // draw the accel string
1703 if ( !accel
.empty() )
1705 // menubar items shouldn't have them
1706 wxCHECK_RET( geometryInfo
, wxT("accel strings only valid for menus") );
1708 rect
.x
= geometryInfo
->GetAccelOffset();
1709 rect
.SetRight(geometryInfo
->GetSize().x
);
1711 // NB: no accel index here
1712 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
1715 // draw the submenu indicator
1716 if ( flags
& wxCONTROL_ISSUBMENU
)
1718 wxCHECK_RET( geometryInfo
, wxT("wxCONTROL_ISSUBMENU only valid for menus") );
1720 rect
.x
= geometryInfo
->GetSize().x
- MENU_RIGHT_MARGIN
;
1721 rect
.width
= MENU_RIGHT_MARGIN
;
1723 DrawArrow(dc
, wxRIGHT
, rect
, flags
);
1727 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
1729 const wxMenuGeometryInfo
& geomInfo
)
1731 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
1734 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
1736 wxSize size
= sizeText
;
1738 // TODO: make this configurable
1739 size
.x
+= 2*MENU_HORZ_MARGIN
;
1740 size
.y
+= 2*MENU_VERT_MARGIN
;
1745 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
1746 const wxMenu
& menu
) const
1748 // prepare the dc: for now we draw all the items with the system font
1750 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
1752 // the height of a normal item
1753 wxCoord heightText
= dc
.GetCharHeight();
1758 // the max length of label and accel strings: the menu width is the sum of
1759 // them, even if they're for different items (as the accels should be
1762 // the max length of the bitmap is never 0 as Windows always leaves enough
1763 // space for a check mark indicator
1764 wxCoord widthLabelMax
= 0,
1766 widthBmpMax
= MENU_LEFT_MARGIN
;
1768 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
1770 node
= node
->GetNext() )
1772 // height of this item
1775 wxMenuItem
*item
= node
->GetData();
1776 if ( item
->IsSeparator() )
1778 h
= MENU_SEPARATOR_HEIGHT
;
1780 else // not separator
1785 dc
.GetTextExtent(item
->GetItemLabelText(), &widthLabel
, NULL
);
1786 if ( widthLabel
> widthLabelMax
)
1788 widthLabelMax
= widthLabel
;
1792 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
1793 if ( widthAccel
> widthAccelMax
)
1795 widthAccelMax
= widthAccel
;
1798 const wxBitmap
& bmp
= item
->GetBitmap();
1801 wxCoord widthBmp
= bmp
.GetWidth();
1802 if ( widthBmp
> widthBmpMax
)
1803 widthBmpMax
= widthBmp
;
1805 //else if ( item->IsCheckable() ): no need to check for this as
1806 // MENU_LEFT_MARGIN is big enough to show the check mark
1809 h
+= 2*MENU_VERT_MARGIN
;
1811 // remember the item position and height
1812 item
->SetGeometry(height
, h
);
1817 // bundle the metrics into a struct and return it
1818 wxGTKMenuGeometryInfo
*gi
= new wxGTKMenuGeometryInfo
;
1820 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
1821 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
1822 if ( widthAccelMax
> 0 )
1824 // if we actually have any accesl, add a margin
1825 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
1828 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
1830 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
1831 gi
->m_size
.y
= height
;
1836 #endif // wxUSE_MENUS
1838 // ----------------------------------------------------------------------------
1840 // ----------------------------------------------------------------------------
1842 void wxGTKRenderer::InitComboBitmaps()
1844 wxSize sizeArrow
= m_sizeScrollbarArrow
;
1850 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1852 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
1855 static const int comboButtonFlags
[ComboState_Max
] =
1863 wxRect
rect(sizeArrow
);
1866 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1868 int flags
= comboButtonFlags
[n
];
1870 dc
.SelectObject(m_bitmapsCombo
[n
]);
1871 DrawSolidRect(dc
, GetBackgroundColour(flags
), rect
);
1872 DrawArrow(dc
, wxDOWN
, rect
, flags
);
1876 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
1878 wxBitmap
*bmpPressed
,
1879 wxBitmap
*bmpDisabled
)
1881 if ( !m_bitmapsCombo
[ComboState_Normal
].IsOk() )
1887 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
1889 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
1891 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
1893 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
1896 // ----------------------------------------------------------------------------
1898 // ----------------------------------------------------------------------------
1900 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
1904 static const wxDirection sides
[] =
1906 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
1909 wxRect rect1
, rect2
, rectInner
;
1915 rectInner
.Inflate(-2);
1917 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
1919 // find the side not to draw and also adjust the rectangles to compensate
1921 wxDirection sideToOmit
;
1925 sideToOmit
= wxDOWN
;
1927 rectInner
.height
+= 1;
1935 rectInner
.height
+= 1;
1939 sideToOmit
= wxRIGHT
;
1941 rectInner
.width
+= 1;
1945 sideToOmit
= wxLEFT
;
1949 rectInner
.width
+= 1;
1953 wxFAIL_MSG(wxT("unknown arrow direction"));
1957 // the outer rect first
1959 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
1961 wxDirection side
= sides
[n
];
1962 if ( side
== sideToOmit
)
1965 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
1968 // and then the inner one
1969 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
1971 wxDirection side
= sides
[n
];
1972 if ( side
== sideToOmit
)
1975 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
1981 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
1983 const wxRect
& rectArrow
,
1986 // first of all, draw the border around it - but we don't want the border
1987 // on the side opposite to the arrow point
1988 wxRect rect
= rectArrow
;
1989 DrawArrowBorder(dc
, &rect
, dir
);
1991 // then the arrow itself
1992 DrawArrow(dc
, dir
, rect
, flags
);
1995 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
1996 // these people are just crazy :-(
1997 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2010 wxPoint ptArrow
[Point_Max
];
2012 wxColour colInside
= GetBackgroundColour(flags
);
2014 if ( flags
& wxCONTROL_DISABLED
)
2016 penShadow
[0] = m_penDarkGrey
;
2017 penShadow
[1] = m_penDarkGrey
;
2018 penShadow
[2] = wxNullPen
;
2019 penShadow
[3] = wxNullPen
;
2021 else if ( flags
& wxCONTROL_PRESSED
)
2023 penShadow
[0] = m_penDarkGrey
;
2024 penShadow
[1] = m_penHighlight
;
2025 penShadow
[2] = wxNullPen
;
2026 penShadow
[3] = m_penBlack
;
2028 else // normal arrow
2030 penShadow
[0] = m_penHighlight
;
2031 penShadow
[1] = m_penBlack
;
2032 penShadow
[2] = m_penDarkGrey
;
2033 penShadow
[3] = wxNullPen
;
2037 if ( dir
== wxUP
|| dir
== wxDOWN
)
2040 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2044 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2047 // draw the arrow interior
2048 dc
.SetPen(*wxTRANSPARENT_PEN
);
2049 dc
.SetBrush(colInside
);
2054 ptArrow
[Point_First
].x
= rect
.GetLeft();
2055 ptArrow
[Point_First
].y
= rect
.GetBottom();
2056 ptArrow
[Point_Second
].x
= middle
;
2057 ptArrow
[Point_Second
].y
= rect
.GetTop();
2058 ptArrow
[Point_Third
].x
= rect
.GetRight();
2059 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2063 ptArrow
[Point_First
] = rect
.GetPosition();
2064 ptArrow
[Point_Second
].x
= middle
;
2065 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2066 ptArrow
[Point_Third
].x
= rect
.GetRight();
2067 ptArrow
[Point_Third
].y
= rect
.GetTop();
2071 ptArrow
[Point_First
].x
= rect
.GetRight();
2072 ptArrow
[Point_First
].y
= rect
.GetTop();
2073 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2074 ptArrow
[Point_Second
].y
= middle
;
2075 ptArrow
[Point_Third
].x
= rect
.GetRight();
2076 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2080 ptArrow
[Point_First
] = rect
.GetPosition();
2081 ptArrow
[Point_Second
].x
= rect
.GetRight();
2082 ptArrow
[Point_Second
].y
= middle
;
2083 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2084 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2088 wxFAIL_MSG(wxT("unknown arrow direction"));
2091 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2093 // draw the arrow border
2094 dc
.SetPen(penShadow
[0]);
2098 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2099 dc
.DrawPoint(ptArrow
[Point_First
]);
2100 if ( penShadow
[3].IsOk() )
2102 dc
.SetPen(penShadow
[3]);
2103 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2104 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2106 dc
.SetPen(penShadow
[1]);
2107 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2108 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2109 dc
.DrawPoint(ptArrow
[Point_Third
]);
2110 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2111 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2112 if ( penShadow
[2].IsOk() )
2114 dc
.SetPen(penShadow
[2]);
2115 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2116 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2117 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2118 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2123 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2124 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2125 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2126 if ( penShadow
[2].IsOk() )
2128 dc
.SetPen(penShadow
[2]);
2129 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2130 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2132 dc
.SetPen(penShadow
[1]);
2133 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2134 dc
.DrawPoint(ptArrow
[Point_Third
]);
2138 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2139 dc
.DrawPoint(ptArrow
[Point_First
]);
2140 if ( penShadow
[2].IsOk() )
2142 dc
.SetPen(penShadow
[2]);
2143 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2144 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2145 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2146 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2148 dc
.SetPen(penShadow
[1]);
2149 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2150 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2151 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2152 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2156 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2157 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2158 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2159 dc
.SetPen(penShadow
[1]);
2160 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2161 dc
.DrawPoint(ptArrow
[Point_Third
]);
2165 wxFAIL_MSG(wxT("unknown arrow direction"));
2170 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2172 wxOrientation orient
)
2174 if ( orient
== wxVERTICAL
)
2176 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2178 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2180 rect
->Inflate(-1, 0);
2182 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2184 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2186 rect
->Inflate(-1, 0);
2190 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2192 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2194 rect
->Inflate(0, -1);
2196 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2198 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2200 rect
->Inflate(0, -1);
2204 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2205 wxOrientation orient
,
2209 // the thumb is never pressed never has focus border under GTK and the
2210 // scrollbar background never changes at all
2211 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2213 // we don't want the border in the direction of the scrollbar movement
2214 wxRect rectThumb
= rect
;
2215 DrawThumbBorder(dc
, &rectThumb
, orient
);
2217 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2218 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2221 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2222 wxOrientation orient
,
2224 int WXUNUSED(flags
))
2226 wxRect rectBar
= rect
;
2227 DrawThumbBorder(dc
, &rectBar
, orient
);
2228 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2231 // ----------------------------------------------------------------------------
2233 // ----------------------------------------------------------------------------
2235 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2238 if ( wxDynamicCast(window
, wxBitmapButton
) )
2243 #endif // wxUSE_BMPBUTTON
2244 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
2247 || wxDynamicCast(window
, wxButton
)
2248 # endif // wxUSE_BUTTON
2249 # if wxUSE_TOGGLEBTN
2250 || wxDynamicCast(window
, wxToggleButton
)
2251 # endif // wxUSE_TOGGLEBTN
2254 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2256 // TODO: this is ad hoc...
2257 size
->x
+= 3*window
->GetCharWidth();
2258 wxCoord minBtnHeight
= 18;
2259 if ( size
->y
< minBtnHeight
)
2260 size
->y
= minBtnHeight
;
2262 // button border width
2266 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
2268 if ( wxDynamicCast(window
, wxScrollBar
) )
2271 Don't adjust the size for a scrollbar as its DoGetBestClientSize
2272 already has the correct size set. Any size changes here would get
2273 added to the best size, making the scrollbar larger.
2274 Also skip border width adjustments, they don't make sense for us.
2279 #endif // wxUSE_SCROLLBAR
2281 // take into account the border width
2282 wxStdRenderer::AdjustSize(size
, window
);
2286 // ----------------------------------------------------------------------------
2288 // ----------------------------------------------------------------------------
2290 /* Copyright (c) Julian Smart */
2291 static const char *error_xpm
[] = {
2292 /* columns rows colors chars-per-pixel */
2306 " ................. ",
2307 " ................... ",
2308 " ....................... ",
2309 " ......................... ",
2310 " ........................... ",
2311 " ...........................X ",
2312 " .............................X ",
2313 " ............................... ",
2314 " ...............................X ",
2315 " .................................X ",
2316 " .................................X ",
2317 " .................................XX ",
2318 " ...ooooooooooooooooooooooooooo...XX ",
2319 " ....ooooooooooooooooooooooooooo....X ",
2320 " ....ooooooooooooooooooooooooooo....X ",
2321 " ....ooooooooooooooooooooooooooo....XX ",
2322 " ....ooooooooooooooooooooooooooo....XX ",
2323 " ....ooooooooooooooooooooooooooo....XX ",
2324 " ...ooooooooooooooooooooooooooo...XXX ",
2325 " ...ooooooooooooooooooooooooooo...XXX ",
2326 " .................................XX ",
2327 " .................................XX ",
2328 " ...............................XXX ",
2329 " ...............................XXX ",
2330 " .............................XXX ",
2331 " ...........................XXXX ",
2332 " ...........................XXX ",
2333 " .........................XXX ",
2334 " .......................XXXX ",
2335 " X...................XXXXX ",
2336 " X.................XXXXX ",
2337 " X.............XXXXX ",
2338 " XXXX.....XXXXXXXX ",
2349 /* Copyright (c) Julian Smart */
2350 static const char *info_xpm
[] = {
2351 /* columns rows colors chars-per-pixel */
2375 " .XXXOXXXXXXXoo. ",
2376 " .XOOXXX+XXXXXo. ",
2377 " .XOOOXX+++XXXXoo. ",
2378 " .XOOXXX+++XXXXXo. ",
2379 " .XOOOXXX+++XXXXXXo. ",
2380 " .XOOXXXX+++XXXXXXo. ",
2381 " .XXXXXXX+++XXXXXXX. ",
2382 " .XXXXXXX+++XXXXXXo. ",
2383 " .XXXXXXX+++XXXXXoo. ",
2384 " .XXXXXX+++XXXXXo. ",
2385 " .XXXXXXX+XXXXXXo. ",
2386 " .XXXXXXXXXXXXo. ",
2387 " .XXXXX+++XXXoo. ",
2413 /* Copyright (c) Julian Smart */
2414 static const char *warning_xpm
[] = {
2415 /* columns rows colors chars-per-pixel */
2445 " ..XXXXO@#XXX... ",
2446 " ...XXXXO@#XXXX.. ",
2447 " ..XXXXXO@#XXXX... ",
2448 " ...XXXXXo@OXXXXX.. ",
2449 " ...XXXXXXo@OXXXXXX.. ",
2450 " ..XXXXXXX$@OXXXXXX... ",
2451 " ...XXXXXXXX@XXXXXXXX.. ",
2452 " ...XXXXXXXXXXXXXXXXXX... ",
2453 " ..XXXXXXXXXXOXXXXXXXXX.. ",
2454 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
2455 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
2456 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
2457 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
2458 " .............................. ",
2459 " .............................. ",
2477 /* Copyright (c) Julian Smart */
2478 static const char *question_xpm
[] = {
2479 /* columns rows colors chars-per-pixel */
2509 " ..XXXXoooooXXXO+ ",
2510 " ..XXooooooooooooX@.. ",
2511 " ..XoooooooooooooooXX#. ",
2512 " $%XoooooooooooooooooXX#. ",
2513 " &.XoooooooXXXXXXooooooXX.. ",
2514 " .XooooooXX.$...$XXoooooX*. ",
2515 " $.XoooooX%.$ .*oooooo=.. ",
2516 " .XooooooX.. -.XoooooX.. ",
2517 " .XoooooX..+ .XoooooX;. ",
2518 " ...XXXX..: .XoooooX;. ",
2519 " ........ >.XoooooX;. ",
2553 wxBitmap
wxGTKArtProvider::CreateBitmap(const wxArtID
& id
,
2554 const wxArtClient
& WXUNUSED(client
),
2555 const wxSize
& WXUNUSED(size
))
2557 if ( id
== wxART_INFORMATION
)
2558 return wxBitmap(info_xpm
);
2559 if ( id
== wxART_ERROR
)
2560 return wxBitmap(error_xpm
);
2561 if ( id
== wxART_WARNING
)
2562 return wxBitmap(warning_xpm
);
2563 if ( id
== wxART_QUESTION
)
2564 return wxBitmap(question_xpm
);
2565 return wxNullBitmap
;
2569 // ============================================================================
2571 // ============================================================================
2573 // ----------------------------------------------------------------------------
2574 // wxGTKInputHandler
2575 // ----------------------------------------------------------------------------
2577 bool wxGTKInputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
2578 const wxKeyEvent
& WXUNUSED(event
),
2579 bool WXUNUSED(pressed
))
2584 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
2585 const wxMouseEvent
& event
)
2587 // clicking on the control gives it focus
2588 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
2590 control
->GetInputWindow()->SetFocus();
2598 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
2599 const wxMouseEvent
& event
)
2601 if ( event
.Entering() )
2603 control
->GetInputWindow()->SetCurrent(true);
2605 else if ( event
.Leaving() )
2607 control
->GetInputWindow()->SetCurrent(false);
2619 // ----------------------------------------------------------------------------
2620 // wxGTKCheckboxInputHandler
2621 // ----------------------------------------------------------------------------
2623 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
2624 const wxKeyEvent
& event
,
2629 int keycode
= event
.GetKeyCode();
2630 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
2632 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
2641 #endif // wxUSE_CHECKBOX
2645 // ----------------------------------------------------------------------------
2646 // wxGTKTextCtrlInputHandler
2647 // ----------------------------------------------------------------------------
2649 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
2650 const wxKeyEvent
& event
,
2653 // handle only GTK-specific text bindings here, the others are handled in
2657 wxControlAction action
;
2658 int keycode
= event
.GetKeyCode();
2659 if ( event
.ControlDown() )
2664 action
= wxACTION_TEXT_HOME
;
2668 action
= wxACTION_TEXT_LEFT
;
2672 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
2676 action
= wxACTION_TEXT_END
;
2680 action
= wxACTION_TEXT_RIGHT
;
2684 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
2688 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2692 action
= wxACTION_TEXT_DOWN
;
2696 action
= wxACTION_TEXT_UP
;
2700 //delete the entire line
2701 control
->PerformAction(wxACTION_TEXT_HOME
);
2702 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2706 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
2710 else if ( event
.AltDown() )
2715 action
= wxACTION_TEXT_WORD_LEFT
;
2719 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
2723 action
= wxACTION_TEXT_WORD_RIGHT
;
2728 if ( action
!= wxACTION_NONE
)
2730 control
->PerformAction(action
);
2736 return wxStdInputHandler::HandleKey(control
, event
, pressed
);
2739 #endif // wxUSE_TEXTCTRL
2741 #endif // wxUSE_THEME_GTK