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
) )
2270 // we only set the width of vert scrollbars and height of the
2272 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2273 size
->y
= m_sizeScrollbarArrow
.x
;
2275 size
->x
= m_sizeScrollbarArrow
.x
;
2278 #endif // wxUSE_SCROLLBAR
2280 // take into account the border width
2281 wxStdRenderer::AdjustSize(size
, window
);
2285 // ----------------------------------------------------------------------------
2287 // ----------------------------------------------------------------------------
2289 /* Copyright (c) Julian Smart */
2290 static const char *error_xpm
[] = {
2291 /* columns rows colors chars-per-pixel */
2305 " ................. ",
2306 " ................... ",
2307 " ....................... ",
2308 " ......................... ",
2309 " ........................... ",
2310 " ...........................X ",
2311 " .............................X ",
2312 " ............................... ",
2313 " ...............................X ",
2314 " .................................X ",
2315 " .................................X ",
2316 " .................................XX ",
2317 " ...ooooooooooooooooooooooooooo...XX ",
2318 " ....ooooooooooooooooooooooooooo....X ",
2319 " ....ooooooooooooooooooooooooooo....X ",
2320 " ....ooooooooooooooooooooooooooo....XX ",
2321 " ....ooooooooooooooooooooooooooo....XX ",
2322 " ....ooooooooooooooooooooooooooo....XX ",
2323 " ...ooooooooooooooooooooooooooo...XXX ",
2324 " ...ooooooooooooooooooooooooooo...XXX ",
2325 " .................................XX ",
2326 " .................................XX ",
2327 " ...............................XXX ",
2328 " ...............................XXX ",
2329 " .............................XXX ",
2330 " ...........................XXXX ",
2331 " ...........................XXX ",
2332 " .........................XXX ",
2333 " .......................XXXX ",
2334 " X...................XXXXX ",
2335 " X.................XXXXX ",
2336 " X.............XXXXX ",
2337 " XXXX.....XXXXXXXX ",
2348 /* Copyright (c) Julian Smart */
2349 static const char *info_xpm
[] = {
2350 /* columns rows colors chars-per-pixel */
2374 " .XXXOXXXXXXXoo. ",
2375 " .XOOXXX+XXXXXo. ",
2376 " .XOOOXX+++XXXXoo. ",
2377 " .XOOXXX+++XXXXXo. ",
2378 " .XOOOXXX+++XXXXXXo. ",
2379 " .XOOXXXX+++XXXXXXo. ",
2380 " .XXXXXXX+++XXXXXXX. ",
2381 " .XXXXXXX+++XXXXXXo. ",
2382 " .XXXXXXX+++XXXXXoo. ",
2383 " .XXXXXX+++XXXXXo. ",
2384 " .XXXXXXX+XXXXXXo. ",
2385 " .XXXXXXXXXXXXo. ",
2386 " .XXXXX+++XXXoo. ",
2412 /* Copyright (c) Julian Smart */
2413 static const char *warning_xpm
[] = {
2414 /* columns rows colors chars-per-pixel */
2444 " ..XXXXO@#XXX... ",
2445 " ...XXXXO@#XXXX.. ",
2446 " ..XXXXXO@#XXXX... ",
2447 " ...XXXXXo@OXXXXX.. ",
2448 " ...XXXXXXo@OXXXXXX.. ",
2449 " ..XXXXXXX$@OXXXXXX... ",
2450 " ...XXXXXXXX@XXXXXXXX.. ",
2451 " ...XXXXXXXXXXXXXXXXXX... ",
2452 " ..XXXXXXXXXXOXXXXXXXXX.. ",
2453 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
2454 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
2455 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
2456 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
2457 " .............................. ",
2458 " .............................. ",
2476 /* Copyright (c) Julian Smart */
2477 static const char *question_xpm
[] = {
2478 /* columns rows colors chars-per-pixel */
2508 " ..XXXXoooooXXXO+ ",
2509 " ..XXooooooooooooX@.. ",
2510 " ..XoooooooooooooooXX#. ",
2511 " $%XoooooooooooooooooXX#. ",
2512 " &.XoooooooXXXXXXooooooXX.. ",
2513 " .XooooooXX.$...$XXoooooX*. ",
2514 " $.XoooooX%.$ .*oooooo=.. ",
2515 " .XooooooX.. -.XoooooX.. ",
2516 " .XoooooX..+ .XoooooX;. ",
2517 " ...XXXX..: .XoooooX;. ",
2518 " ........ >.XoooooX;. ",
2552 wxBitmap
wxGTKArtProvider::CreateBitmap(const wxArtID
& id
,
2553 const wxArtClient
& WXUNUSED(client
),
2554 const wxSize
& WXUNUSED(size
))
2556 if ( id
== wxART_INFORMATION
)
2557 return wxBitmap(info_xpm
);
2558 if ( id
== wxART_ERROR
)
2559 return wxBitmap(error_xpm
);
2560 if ( id
== wxART_WARNING
)
2561 return wxBitmap(warning_xpm
);
2562 if ( id
== wxART_QUESTION
)
2563 return wxBitmap(question_xpm
);
2564 return wxNullBitmap
;
2568 // ============================================================================
2570 // ============================================================================
2572 // ----------------------------------------------------------------------------
2573 // wxGTKInputHandler
2574 // ----------------------------------------------------------------------------
2576 bool wxGTKInputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
2577 const wxKeyEvent
& WXUNUSED(event
),
2578 bool WXUNUSED(pressed
))
2583 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
2584 const wxMouseEvent
& event
)
2586 // clicking on the control gives it focus
2587 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
2589 control
->GetInputWindow()->SetFocus();
2597 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
2598 const wxMouseEvent
& event
)
2600 if ( event
.Entering() )
2602 control
->GetInputWindow()->SetCurrent(true);
2604 else if ( event
.Leaving() )
2606 control
->GetInputWindow()->SetCurrent(false);
2618 // ----------------------------------------------------------------------------
2619 // wxGTKCheckboxInputHandler
2620 // ----------------------------------------------------------------------------
2622 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
2623 const wxKeyEvent
& event
,
2628 int keycode
= event
.GetKeyCode();
2629 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
2631 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
2640 #endif // wxUSE_CHECKBOX
2644 // ----------------------------------------------------------------------------
2645 // wxGTKTextCtrlInputHandler
2646 // ----------------------------------------------------------------------------
2648 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
2649 const wxKeyEvent
& event
,
2652 // handle only GTK-specific text bindings here, the others are handled in
2656 wxControlAction action
;
2657 int keycode
= event
.GetKeyCode();
2658 if ( event
.ControlDown() )
2663 action
= wxACTION_TEXT_HOME
;
2667 action
= wxACTION_TEXT_LEFT
;
2671 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
2675 action
= wxACTION_TEXT_END
;
2679 action
= wxACTION_TEXT_RIGHT
;
2683 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
2687 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2691 action
= wxACTION_TEXT_DOWN
;
2695 action
= wxACTION_TEXT_UP
;
2699 //delete the entire line
2700 control
->PerformAction(wxACTION_TEXT_HOME
);
2701 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2705 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
2709 else if ( event
.AltDown() )
2714 action
= wxACTION_TEXT_WORD_LEFT
;
2718 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
2722 action
= wxACTION_TEXT_WORD_RIGHT
;
2727 if ( action
!= wxACTION_NONE
)
2729 control
->PerformAction(action
);
2735 return wxStdInputHandler::HandleKey(control
, event
, pressed
);
2738 #endif // wxUSE_TEXTCTRL
2740 #endif // wxUSE_THEME_GTK