1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: univ/themes/gtk.cpp
3 // Purpose: wxUniversal theme implementing GTK-like LNF
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
30 #include "wx/dcmemory.h"
31 #include "wx/window.h"
33 #include "wx/button.h"
34 #include "wx/checkbox.h"
35 #include "wx/listbox.h"
36 #include "wx/checklst.h"
37 #include "wx/combobox.h"
38 #include "wx/scrolbar.h"
39 #include "wx/slider.h"
40 #include "wx/textctrl.h"
43 #include "wx/notebook.h"
44 #include "wx/spinbutt.h"
46 #include "wx/univ/renderer.h"
47 #include "wx/univ/inphand.h"
48 #include "wx/univ/colschem.h"
49 #include "wx/univ/theme.h"
51 // ----------------------------------------------------------------------------
52 // constants (to be removed, for testing only)
53 // ----------------------------------------------------------------------------
55 static const size_t BORDER_THICKNESS
= 10;
57 // ----------------------------------------------------------------------------
58 // wxGTKRenderer: draw the GUI elements in GTK style
59 // ----------------------------------------------------------------------------
61 class wxGTKRenderer
: public wxRenderer
64 wxGTKRenderer(const wxColourScheme
*scheme
);
66 // implement the base class pure virtuals
67 virtual void DrawBackground(wxDC
& dc
,
71 virtual void DrawLabel(wxDC
& dc
,
72 const wxString
& label
,
75 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
77 wxRect
*rectBounds
= NULL
);
78 virtual void DrawButtonLabel(wxDC
& dc
,
79 const wxString
& label
,
80 const wxBitmap
& image
,
83 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
85 wxRect
*rectBounds
= NULL
);
86 virtual void DrawBorder(wxDC
& dc
,
90 wxRect
*rectIn
= (wxRect
*)NULL
);
91 virtual void DrawHorizontalLine(wxDC
& dc
,
92 wxCoord y
, wxCoord x1
, wxCoord x2
);
93 virtual void DrawVerticalLine(wxDC
& dc
,
94 wxCoord x
, wxCoord y1
, wxCoord y2
);
95 virtual void DrawFrame(wxDC
& dc
,
96 const wxString
& label
,
99 int alignment
= wxALIGN_LEFT
,
100 int indexAccel
= -1);
101 virtual void DrawTextBorder(wxDC
& dc
,
105 wxRect
*rectIn
= (wxRect
*)NULL
);
106 virtual void DrawButtonBorder(wxDC
& dc
,
109 wxRect
*rectIn
= (wxRect
*)NULL
);
110 virtual void DrawArrow(wxDC
& dc
,
114 virtual void DrawScrollbarArrow(wxDC
& dc
,
118 virtual void DrawScrollbarThumb(wxDC
& dc
,
119 wxOrientation orient
,
122 virtual void DrawScrollbarShaft(wxDC
& dc
,
123 wxOrientation orient
,
126 virtual void DrawScrollCorner(wxDC
& dc
,
128 virtual void DrawItem(wxDC
& dc
,
129 const wxString
& label
,
132 virtual void DrawCheckItem(wxDC
& dc
,
133 const wxString
& label
,
134 const wxBitmap
& bitmap
,
137 virtual void DrawCheckButton(wxDC
& dc
,
138 const wxString
& label
,
139 const wxBitmap
& bitmap
,
142 wxAlignment align
= wxALIGN_LEFT
,
143 int indexAccel
= -1);
145 virtual void DrawRadioButton(wxDC
& dc
,
146 const wxString
& label
,
147 const wxBitmap
& bitmap
,
150 wxAlignment align
= wxALIGN_LEFT
,
151 int indexAccel
= -1);
153 virtual void DrawTextLine(wxDC
& dc
,
154 const wxString
& text
,
159 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
160 virtual void DrawTab(wxDC
& dc
,
163 const wxString
& label
,
164 const wxBitmap
& bitmap
= wxNullBitmap
,
166 int indexAccel
= -1);
168 virtual void DrawSliderShaft(wxDC
& dc
,
170 wxOrientation orient
,
172 wxRect
*rectShaft
= NULL
);
173 virtual void DrawSliderThumb(wxDC
& dc
,
175 wxOrientation orient
,
177 virtual void DrawSliderTicks(wxDC
& dc
,
179 const wxSize
& sizeThumb
,
180 wxOrientation orient
,
186 // we don't have the ticks in GTK version
190 virtual void DrawMenuBarItem(wxDC
& dc
,
192 const wxString
& label
,
194 int indexAccel
= -1);
195 virtual void DrawMenuItem(wxDC
& dc
,
197 const wxMenuGeometryInfo
& geometryInfo
,
198 const wxString
& label
,
199 const wxString
& accel
,
200 const wxBitmap
& bitmap
= wxNullBitmap
,
202 int indexAccel
= -1);
203 virtual void DrawMenuSeparator(wxDC
& dc
,
205 const wxMenuGeometryInfo
& geomInfo
);
207 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
209 wxBitmap
*bmpPressed
,
210 wxBitmap
*bmpDisabled
);
212 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
213 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
214 virtual bool AreScrollbarsInsideBorder() const;
216 // geometry and hit testing
217 virtual wxSize
GetScrollbarArrowSize() const
218 { return m_sizeScrollbarArrow
; }
219 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
220 wxScrollBar::Element elem
,
221 int thumbPos
= -1) const;
222 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
223 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
224 const wxPoint
& pt
) const;
225 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
227 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
228 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
229 { return fontHeight
+ 2; }
230 virtual wxSize
GetCheckBitmapSize() const
231 { return wxSize(10, 10); }
232 virtual wxSize
GetRadioBitmapSize() const
233 { return wxSize(11, 11); }
234 virtual wxCoord
GetCheckItemMargin() const
237 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
239 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
241 wxCoord
*extraSpaceBeyond
);
243 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
244 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
246 virtual wxCoord
GetSliderDim() const { return 15; }
247 virtual wxCoord
GetSliderTickLen() const { return 0; }
248 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
249 wxOrientation orient
) const;
250 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
251 wxOrientation orient
) const;
252 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
255 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
256 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
257 const wxMenu
& menu
) const;
259 // helpers for "wxBitmap wxColourScheme::Get()"
260 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
261 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
264 // DrawBackground() helpers
266 // get the colour to use for background
267 wxColour
GetBackgroundColour(int flags
) const
269 if ( flags
& wxCONTROL_PRESSED
)
270 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
271 else if ( flags
& wxCONTROL_CURRENT
)
272 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
274 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
277 // draw the background with any colour, not only the default one(s)
278 void DoDrawBackground(wxDC
& dc
,
282 // DrawBorder() helpers: all of them shift and clip the DC after drawing
285 // just draw a rectangle with the given pen
286 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
288 // draw the lower left part of rectangle
289 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
291 // draw the rectange using the first brush for the left and top sides and
292 // the second one for the bottom and right ones
293 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
294 const wxPen
& pen1
, const wxPen
& pen2
);
296 // as DrawShadedRect() but the pixels in the bottom left and upper right
297 // border are drawn with the pen1, not pen2
298 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
299 const wxPen
& pen1
, const wxPen
& pen2
);
301 // used for drawing opened rectangles - draws only one side of it at once
302 // (and doesn't adjust the rect)
303 void DrawAntiShadedRectSide(wxDC
& dc
,
309 // draw an opened rect for the arrow in given direction
310 void DrawArrowBorder(wxDC
& dc
,
314 // draw two sides of the rectangle
315 void DrawThumbBorder(wxDC
& dc
,
317 wxOrientation orient
);
319 // draw the normal 3D border
320 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
322 // just as DrawRaisedBorder() except that the bottom left and up right
323 // pixels of the interior rect are drawn in another colour (i.e. the inner
324 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
325 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
327 // returns the size of the arrow for the scrollbar (depends on
329 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
332 if ( scrollbar
->IsVertical() )
334 size
= m_sizeScrollbarArrow
;
338 size
.x
= m_sizeScrollbarArrow
.y
;
339 size
.y
= m_sizeScrollbarArrow
.x
;
345 // get the line wrap indicator bitmap
346 wxBitmap
GetLineWrapBitmap();
348 // DrawCheckBitmap and DrawRadioBitmap helpers
350 // draw the check bitmaps once and cache them for later use
351 wxBitmap
GetCheckBitmap(int flags
);
353 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
355 void DrawUpZag(wxDC
& dc
,
356 wxCoord x1
, wxCoord x2
,
357 wxCoord y1
, wxCoord y2
);
358 void DrawDownZag(wxDC
& dc
,
359 wxCoord x1
, wxCoord x2
,
360 wxCoord y1
, wxCoord y2
);
362 // draw the radio button bitmap for the given state
363 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
365 // draw check/radio - the bitmap must be a valid one by now
366 void DoDrawCheckOrRadioBitmap(wxDC
& dc
,
367 const wxString
& label
,
368 const wxBitmap
& bitmap
,
369 const wxRect
& rectTotal
,
374 // initialize the combo bitmaps
375 void InitComboBitmaps();
378 const wxColourScheme
*m_scheme
;
381 wxSize m_sizeScrollbarArrow
;
390 // the checkbox bitmaps: first row is for the normal, second for the
391 // pressed state and the columns are for checked and unchecked status
393 wxBitmap m_bitmapsCheckbox
[2][2];
395 // the line wrap bitmap (drawn at the end of wrapped lines)
396 wxBitmap m_bmpLineWrap
;
398 // the combobox bitmaps
408 wxBitmap m_bitmapsCombo
[ComboState_Max
];
411 // ----------------------------------------------------------------------------
412 // wxGTKInputHandler and derived classes: process the keyboard and mouse
413 // messages according to GTK standards
414 // ----------------------------------------------------------------------------
416 class wxGTKInputHandler
: public wxInputHandler
419 wxGTKInputHandler(wxGTKRenderer
*renderer
);
421 virtual bool HandleKey(wxControl
*control
,
422 const wxKeyEvent
& event
,
424 virtual bool HandleMouse(wxControl
*control
,
425 const wxMouseEvent
& event
);
426 virtual bool HandleMouseMove(wxControl
*control
, const wxMouseEvent
& event
);
429 wxGTKRenderer
*m_renderer
;
432 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
435 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
436 : wxStdScrollBarInputHandler(renderer
, handler
) { }
439 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
441 // only arrows and the thumb can be highlighted
442 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
445 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
448 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
450 // only arrows can be pressed
454 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
457 virtual bool IsAllowedButton(int WXUNUSED(button
)) { return TRUE
; }
461 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
462 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
466 class wxGTKCheckboxInputHandler
: public wxStdCheckboxInputHandler
469 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
470 : wxStdCheckboxInputHandler(handler
) { }
472 virtual bool HandleKey(wxControl
*control
,
473 const wxKeyEvent
& event
,
477 class wxGTKTextCtrlInputHandler
: public wxStdTextCtrlInputHandler
480 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
481 : wxStdTextCtrlInputHandler(handler
) { }
483 virtual bool HandleKey(wxControl
*control
,
484 const wxKeyEvent
& event
,
488 // ----------------------------------------------------------------------------
489 // wxGTKColourScheme: uses the standard GTK colours
490 // ----------------------------------------------------------------------------
492 class wxGTKColourScheme
: public wxColourScheme
495 virtual wxColour
Get(StdColour col
) const;
496 virtual wxColour
GetBackground(wxWindow
*win
) const;
499 // ----------------------------------------------------------------------------
501 // ----------------------------------------------------------------------------
503 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
505 class wxGTKTheme
: public wxTheme
509 virtual ~wxGTKTheme();
511 virtual wxRenderer
*GetRenderer() { return m_renderer
; }
512 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
513 virtual wxColourScheme
*GetColourScheme() { return m_scheme
; }
516 // get the default input handler
517 wxInputHandler
*GetDefaultInputHandler();
519 wxGTKRenderer
*m_renderer
;
521 // the names of the already created handlers and the handlers themselves
522 // (these arrays are synchronized)
523 wxSortedArrayString m_handlerNames
;
524 wxArrayHandlers m_handlers
;
526 wxGTKInputHandler
*m_handlerDefault
;
528 wxGTKColourScheme
*m_scheme
;
530 WX_DECLARE_THEME(gtk
)
533 // ============================================================================
535 // ============================================================================
537 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
539 // ----------------------------------------------------------------------------
541 // ----------------------------------------------------------------------------
543 wxGTKTheme::wxGTKTheme()
545 m_scheme
= new wxGTKColourScheme
;
546 m_renderer
= new wxGTKRenderer(m_scheme
);
547 m_handlerDefault
= NULL
;
550 wxGTKTheme::~wxGTKTheme()
552 size_t count
= m_handlers
.GetCount();
553 for ( size_t n
= 0; n
< count
; n
++ )
555 if ( m_handlers
[n
] != m_handlerDefault
)
556 delete m_handlers
[n
];
559 delete m_handlerDefault
;
564 wxInputHandler
*wxGTKTheme::GetDefaultInputHandler()
566 if ( !m_handlerDefault
)
568 m_handlerDefault
= new wxGTKInputHandler(m_renderer
);
571 return m_handlerDefault
;
574 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
)
576 wxInputHandler
*handler
;
577 int n
= m_handlerNames
.Index(control
);
578 if ( n
== wxNOT_FOUND
)
580 // create a new handler
581 if ( control
== wxINP_HANDLER_SCROLLBAR
)
582 handler
= new wxGTKScrollBarInputHandler(m_renderer
,
583 GetDefaultInputHandler());
585 else if ( control
== wxINP_HANDLER_BUTTON
)
586 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
587 #endif // wxUSE_CHECKBOX
589 else if ( control
== wxINP_HANDLER_CHECKBOX
)
590 handler
= new wxGTKCheckboxInputHandler(GetDefaultInputHandler());
591 #endif // wxUSE_CHECKBOX
593 else if ( control
== wxINP_HANDLER_COMBOBOX
)
594 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
595 #endif // wxUSE_COMBOBOX
597 else if ( control
== wxINP_HANDLER_LISTBOX
)
598 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
599 #endif // wxUSE_LISTBOX
600 #if wxUSE_CHECKLISTBOX
601 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
602 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
603 #endif // wxUSE_CHECKLISTBOX
605 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
606 handler
= new wxGTKTextCtrlInputHandler(GetDefaultInputHandler());
607 #endif // wxUSE_TEXTCTRL
609 else if ( control
== wxINP_HANDLER_SLIDER
)
610 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
611 #endif // wxUSE_SLIDER
613 else if ( control
== wxINP_HANDLER_SPINBTN
)
614 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
615 #endif // wxUSE_SPINBTN
617 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
618 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
619 #endif // wxUSE_NOTEBOOK
621 handler
= GetDefaultInputHandler();
623 n
= m_handlerNames
.Add(control
);
624 m_handlers
.Insert(handler
, n
);
626 else // we already have it
628 handler
= m_handlers
[n
];
634 // ============================================================================
636 // ============================================================================
638 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
641 if ( win
->UseBgCol() )
643 // use the user specified colour
644 col
= win
->GetBackgroundColour();
647 if ( win
->IsContainerWindow() )
649 // doesn't depend on the state
657 int flags
= win
->GetStateFlags();
659 // the colour set by the user should be used for the normal state
660 // and for the states for which we don't have any specific colours
661 if ( !col
.Ok() || (flags
!= 0) )
663 if ( wxDynamicCast(win
, wxScrollBar
) )
664 col
= Get(SCROLLBAR
);
665 else if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
666 col
= Get(CONTROL_CURRENT
);
667 else if ( flags
& wxCONTROL_PRESSED
)
668 col
= Get(CONTROL_PRESSED
);
677 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
681 case WINDOW
: return *wxWHITE
;
683 case SHADOW_DARK
: return *wxBLACK
;
684 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
685 case SHADOW_IN
: return wxColour(0xd6d6d6);
686 case SHADOW_OUT
: return wxColour(0x969696);
688 case CONTROL
: return wxColour(0xd6d6d6);
689 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
690 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
692 case CONTROL_TEXT
: return *wxBLACK
;
693 case CONTROL_TEXT_DISABLED
:
694 return wxColour(0x757575);
695 case CONTROL_TEXT_DISABLED_SHADOW
:
699 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
701 case HIGHLIGHT
: return wxColour(0x9c0000);
702 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
706 wxFAIL_MSG(_T("invalid standard colour"));
711 // ============================================================================
713 // ============================================================================
715 // ----------------------------------------------------------------------------
717 // ----------------------------------------------------------------------------
719 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
723 m_sizeScrollbarArrow
= wxSize(15, 14);
726 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
727 m_penDarkGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_OUT
), 0, wxSOLID
);
728 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
), 0, wxSOLID
);
729 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
730 m_penHighlight
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
), 0, wxSOLID
);
733 // ----------------------------------------------------------------------------
735 // ----------------------------------------------------------------------------
737 void wxGTKRenderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
741 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
742 dc
.DrawRectangle(*rect
);
748 void wxGTKRenderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
750 // draw the bottom and right sides
752 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
753 rect
->GetRight() + 1, rect
->GetBottom());
754 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
755 rect
->GetRight(), rect
->GetBottom());
762 void wxGTKRenderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
763 const wxPen
& pen1
, const wxPen
& pen2
)
765 // draw the rectangle
767 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
768 rect
->GetLeft(), rect
->GetBottom());
769 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
770 rect
->GetRight(), rect
->GetTop());
772 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
773 rect
->GetRight(), rect
->GetBottom());
774 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
775 rect
->GetRight() + 1, rect
->GetBottom());
781 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
787 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
792 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
793 rect
.GetLeft(), rect
.GetBottom() + 1);
797 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
798 rect
.GetRight() + 1, rect
.GetTop());
802 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
803 rect
.GetRight(), rect
.GetBottom() + 1);
807 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
808 rect
.GetRight() + 1, rect
.GetBottom());
812 wxFAIL_MSG(_T("unknown rectangle side"));
816 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
817 const wxPen
& pen1
, const wxPen
& pen2
)
819 // draw the rectangle
821 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
822 rect
->GetLeft(), rect
->GetBottom() + 1);
823 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
824 rect
->GetRight() + 1, rect
->GetTop());
826 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
827 rect
->GetRight(), rect
->GetBottom());
828 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
829 rect
->GetRight() + 1, rect
->GetBottom());
835 void wxGTKRenderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
837 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
838 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
841 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
843 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
844 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
847 void wxGTKRenderer::DrawBorder(wxDC
& dc
,
849 const wxRect
& rectTotal
,
855 wxRect rect
= rectTotal
;
859 case wxBORDER_SUNKEN
:
860 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
862 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
863 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
867 case wxBORDER_STATIC
:
868 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
871 case wxBORDER_RAISED
:
872 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
874 DrawRaisedBorder(dc
, &rect
);
878 case wxBORDER_DOUBLE
:
879 DrawShadedRect(dc
, &rect
, m_penLightGrey
, m_penBlack
);
880 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penDarkGrey
);
881 DrawRect(dc
, &rect
, m_penLightGrey
);
884 case wxBORDER_SIMPLE
:
885 DrawRect(dc
, &rect
, m_penBlack
);
889 wxFAIL_MSG(_T("unknown border type"));
892 case wxBORDER_DEFAULT
:
901 wxRect
wxGTKRenderer::GetBorderDimensions(wxBorder border
) const
906 case wxBORDER_RAISED
:
907 case wxBORDER_SUNKEN
:
908 width
= 2*BORDER_THICKNESS
;
911 case wxBORDER_SIMPLE
:
912 case wxBORDER_STATIC
:
916 case wxBORDER_DOUBLE
:
921 wxFAIL_MSG(_T("unknown border type"));
924 case wxBORDER_DEFAULT
:
939 bool wxGTKRenderer::AreScrollbarsInsideBorder() const
941 // no, the scrollbars are outside the border in GTK+
945 // ----------------------------------------------------------------------------
947 // ----------------------------------------------------------------------------
949 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
951 const wxRect
& rectOrig
,
955 wxRect rect
= rectOrig
;
957 if ( flags
& wxCONTROL_FOCUSED
)
959 DrawRect(dc
, &rect
, m_penBlack
);
960 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
964 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
965 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penHighlight
);
972 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
973 const wxRect
& rectTotal
,
977 wxRect rect
= rectTotal
;
979 if ( flags
& wxCONTROL_PRESSED
)
981 // button pressed: draw a black border around it and an inward shade
982 DrawRect(dc
, &rect
, m_penBlack
);
983 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
984 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penDarkGrey
);
988 // button not pressed
990 if ( flags
& wxCONTROL_ISDEFAULT
)
995 if ( flags
& wxCONTROL_FOCUSED
)
997 // button is currently default: add an extra border around it
998 DrawRect(dc
, &rect
, m_penBlack
);
1001 // now draw a normal button
1002 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1003 DrawAntiShadedRect(dc
, &rect
,
1004 wxPen(GetBackgroundColour(flags
), 0, wxSOLID
),
1014 // ----------------------------------------------------------------------------
1016 // ----------------------------------------------------------------------------
1018 void wxGTKRenderer::DrawHorizontalLine(wxDC
& dc
,
1019 wxCoord y
, wxCoord x1
, wxCoord x2
)
1021 dc
.SetPen(m_penDarkGrey
);
1022 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1023 dc
.SetPen(m_penHighlight
);
1025 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1028 void wxGTKRenderer::DrawVerticalLine(wxDC
& dc
,
1029 wxCoord x
, wxCoord y1
, wxCoord y2
)
1031 dc
.SetPen(m_penDarkGrey
);
1032 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1033 dc
.SetPen(m_penHighlight
);
1035 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1038 void wxGTKRenderer::DrawFrame(wxDC
& dc
,
1039 const wxString
& label
,
1045 wxCoord height
= 0; // of the label
1046 wxRect rectFrame
= rect
;
1047 if ( !label
.empty() )
1049 // the text should touch the top border of the rect, so the frame
1050 // itself should be lower
1051 dc
.GetTextExtent(label
, NULL
, &height
);
1052 rectFrame
.y
+= height
/ 2;
1053 rectFrame
.height
-= height
/ 2;
1055 // TODO: the +4 should be customizable
1058 rectText
.x
= rectFrame
.x
+ 4;
1059 rectText
.y
= rect
.y
;
1060 rectText
.width
= rectFrame
.width
- 8;
1061 rectText
.height
= height
;
1064 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1066 rectLabel
.width
+= 2;
1068 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1070 // GTK+ does it like this
1071 dc
.SetPen(m_penHighlight
);
1072 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
1073 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
1077 // just draw the complete frame
1078 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1079 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1083 // ----------------------------------------------------------------------------
1085 // ----------------------------------------------------------------------------
1087 void wxGTKRenderer::DrawLabel(wxDC
& dc
,
1088 const wxString
& label
,
1095 DrawButtonLabel(dc
, label
, wxNullBitmap
, rect
, flags
,
1096 alignment
, indexAccel
, rectBounds
);
1099 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
1100 const wxString
& label
,
1101 const wxBitmap
& image
,
1108 if ( flags
& wxCONTROL_DISABLED
)
1110 // make the text grey and draw a shade for it
1111 dc
.SetTextForeground(*wxWHITE
); // FIXME hardcoded colour
1112 wxRect rectShadow
= rect
;
1115 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1116 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT_DISABLED
));
1119 dc
.DrawLabel(label
, image
, rect
, alignment
, indexAccel
, rectBounds
);
1122 void wxGTKRenderer::DrawItem(wxDC
& dc
,
1123 const wxString
& label
,
1127 wxLogTrace(_T("listbox"), _T("drawing item '%s' at (%d, %d)-(%d, %d)"),
1130 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1133 if ( flags
& wxCONTROL_SELECTED
)
1135 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
), wxSOLID
));
1136 dc
.SetPen(*wxTRANSPARENT_PEN
);
1137 dc
.DrawRectangle(rect
);
1139 colFg
= dc
.GetTextForeground();
1140 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
1143 if ( flags
& wxCONTROL_FOCUSED
)
1145 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1146 wxRect rectFocus
= rect
;
1147 DrawRect(dc
, &rectFocus
, m_penBlack
);
1150 wxRect rectText
= rect
;
1153 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
1155 if ( flags
& wxCONTROL_SELECTED
)
1157 dc
.SetBackgroundMode(wxTRANSPARENT
);
1160 // restore the text colour
1163 dc
.SetTextForeground(colFg
);
1167 void wxGTKRenderer::DrawCheckItem(wxDC
& dc
,
1168 const wxString
& label
,
1169 const wxBitmap
& bitmap
,
1173 wxRect rectBitmap
= rect
;
1175 rectBitmap
.width
= GetCheckBitmapSize().x
;
1176 // never draw the focus rect around the check indicators here
1177 DrawCheckButton(dc
, _T(""), bitmap
, rectBitmap
, flags
& ~wxCONTROL_FOCUSED
);
1179 wxRect rectLabel
= rect
;
1180 wxCoord shift
= rectBitmap
.width
+ 2*GetCheckItemMargin();
1181 rectLabel
.x
+= shift
;
1182 rectLabel
.width
-= shift
;
1183 DrawItem(dc
, label
, rectLabel
, flags
);
1186 // ----------------------------------------------------------------------------
1187 // check/radion buttons
1188 // ----------------------------------------------------------------------------
1190 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1191 const wxRect
& rectTotal
,
1194 wxRect rect
= rectTotal
;
1195 DrawAntiRaisedBorder(dc
, &rect
);
1197 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1198 dc
.SetPen(wxPen(col
, 0, wxSOLID
));
1199 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1202 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1203 //else: it is SHADOW_IN, leave as is
1205 dc
.SetPen(*wxTRANSPARENT_PEN
);
1206 dc
.SetBrush(wxBrush(col
, wxSOLID
));
1207 dc
.DrawRectangle(rect
);
1210 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1212 wxRect rect
= rectTotal
;
1213 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1214 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1216 dc
.SetPen(*wxTRANSPARENT_PEN
);
1217 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), wxSOLID
));
1218 dc
.DrawRectangle(rect
);
1221 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1227 xRight
= rect
.GetRight(),
1228 yBottom
= rect
.GetBottom();
1230 wxCoord yMid
= (y
+ yBottom
) / 2;
1232 // this looks ugly when the background colour of the control is not the
1233 // same ours - radiobox is not transparent as it should be
1235 // first fill the middle: as FloodFill() is not implemented on all
1236 // platforms, this is the only thing to do
1237 wxColour colBg
= flags
& wxCONTROL_CURRENT
1238 ? wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
)
1239 : wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1240 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
1241 dc
.SetPen(*wxTRANSPARENT_PEN
);
1242 dc
.DrawRectangle(rect
);
1245 // then draw the upper half
1246 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1247 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1248 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1251 if ( flags
& wxCONTROL_CHECKED
)
1252 dc
.SetPen(m_penBlack
);
1253 else if ( flags
& wxCONTROL_PRESSED
)
1254 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1255 else // unchecked and unpressed
1259 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1261 // and then the lower one
1262 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1263 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1264 if ( !(flags
& wxCONTROL_CHECKED
) )
1265 dc
.SetPen(m_penDarkGrey
);
1266 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1268 if ( !(flags
& wxCONTROL_CHECKED
) )
1269 drawIt
= TRUE
; // with the same pen
1270 else if ( flags
& wxCONTROL_PRESSED
)
1272 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1275 else // checked and unpressed
1279 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1282 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1288 wxCoord xMid
= (x1
+ x2
) / 2;
1289 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1290 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1293 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1299 wxCoord xMid
= (x1
+ x2
) / 2;
1300 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1301 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1304 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1306 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1308 // init the bitmaps once only
1310 wxSize size
= GetCheckBitmapSize();
1311 rect
.width
= size
.x
;
1312 rect
.height
= size
.y
;
1313 for ( int i
= 0; i
< 2; i
++ )
1315 for ( int j
= 0; j
< 2; j
++ )
1316 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1322 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1323 DrawCheckBitmap(dc
, rect
);
1326 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1327 DrawUncheckBitmap(dc
, rect
, FALSE
);
1330 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1332 // pressed unchecked
1333 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1334 DrawUncheckBitmap(dc
, rect
, TRUE
);
1337 int row
= flags
& wxCONTROL_PRESSED
? 1 : 0;
1338 int col
= flags
& wxCONTROL_CHECKED
? 0 : 1;
1340 return m_bitmapsCheckbox
[row
][col
];
1343 wxBitmap
wxGTKRenderer::GetLineWrapBitmap()
1345 if ( !m_bmpLineWrap
.Ok() )
1347 // the line wrap bitmap as used by GTK+
1348 #define line_wrap_width 6
1349 #define line_wrap_height 9
1350 static const char line_wrap_bits
[] =
1352 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1355 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1356 if ( !bmpLineWrap
.Ok() )
1358 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1362 m_bmpLineWrap
= bmpLineWrap
;
1366 return m_bmpLineWrap
;
1369 void wxGTKRenderer::DrawCheckButton(wxDC
& dc
,
1370 const wxString
& label
,
1371 const wxBitmap
& bitmapOrig
,
1372 const wxRect
& rectTotal
,
1378 if ( bitmapOrig
.Ok() )
1380 bitmap
= bitmapOrig
;
1384 bitmap
= GetCheckBitmap(flags
);
1387 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1388 flags
, align
, indexAccel
);
1391 void wxGTKRenderer::DoDrawCheckOrRadioBitmap(wxDC
& dc
,
1392 const wxString
& label
,
1393 const wxBitmap
& bitmap
,
1394 const wxRect
& rectTotal
,
1399 wxRect rect
= rectTotal
;
1401 if ( flags
& wxCONTROL_FOCUSED
)
1403 // draw the focus border around everything
1404 DrawRect(dc
, &rect
, m_penBlack
);
1408 // the border does not offset the string under GTK
1412 // calculate the position of the bitmap and of the label
1414 yBmp
= rect
.y
+ (rect
.height
- bitmap
.GetHeight()) / 2;
1417 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
1418 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
1420 if ( align
== wxALIGN_RIGHT
)
1422 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
1423 rectLabel
.x
= rect
.x
+ 2;
1424 rectLabel
.SetRight(xBmp
);
1426 else // normal (checkbox to the left of the text) case
1429 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 4;
1430 rectLabel
.SetRight(rect
.GetRight());
1433 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
1435 DrawLabel(dc
, label
, rectLabel
, flags
,
1436 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1439 void wxGTKRenderer::DrawRadioButton(wxDC
& dc
,
1440 const wxString
& label
,
1441 const wxBitmap
& bitmapOrig
,
1442 const wxRect
& rectTotal
,
1448 if ( bitmapOrig
.Ok() )
1450 bitmap
= bitmapOrig
;
1455 wxSize size
= GetRadioBitmapSize();
1456 rect
.width
= size
.x
;
1457 rect
.height
= size
.y
;
1458 bitmap
.Create(rect
.width
, rect
.height
);
1460 dc
.SelectObject(bitmap
);
1461 dc
.SetBackground(*wxLIGHT_GREY_BRUSH
);
1463 DrawRadioBitmap(dc
, rect
, flags
);
1464 bitmap
.SetMask(new wxMask(bitmap
, *wxLIGHT_GREY
));
1467 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1468 flags
, align
, indexAccel
);
1471 // ----------------------------------------------------------------------------
1473 // ----------------------------------------------------------------------------
1475 static const int TEXT_BORDER
= 2;
1477 wxRect
wxGTKRenderer::GetTextTotalArea(const wxTextCtrl
*text
,
1480 wxRect rectTotal
= rect
;
1481 rectTotal
.Inflate(TEXT_BORDER
);
1485 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1487 wxCoord
*extraSpaceBeyond
)
1489 wxRect rectText
= rect
;
1490 rectText
.Inflate(-TEXT_BORDER
);
1492 if ( text
->WrapLines() )
1494 // leave enough for the line wrap bitmap indicator
1495 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1497 rectText
.width
-= widthMark
;
1499 if ( extraSpaceBeyond
)
1500 *extraSpaceBeyond
= widthMark
;
1506 void wxGTKRenderer::DrawTextLine(wxDC
& dc
,
1507 const wxString
& text
,
1513 // TODO: GTK+ draws selection even for unfocused controls, just with
1514 // different colours
1515 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
1518 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1520 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1522 // for a mono bitmap he colours it appears in depends on the current text
1523 // colours, so set them correctly
1525 if ( bmpLineWrap
.GetDepth() == 1 )
1527 colFgOld
= dc
.GetTextForeground();
1529 // FIXME: I wonder what should we do if the background is black too?
1530 dc
.SetTextForeground(*wxBLACK
);
1533 dc
.DrawBitmap(bmpLineWrap
,
1534 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1536 if ( colFgOld
.Ok() )
1538 // restore old colour
1539 dc
.SetTextForeground(colFgOld
);
1543 // ----------------------------------------------------------------------------
1545 // ----------------------------------------------------------------------------
1547 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1548 const wxRect
& rectOrig
,
1550 const wxString
& label
,
1551 const wxBitmap
& bitmap
,
1555 wxRect rect
= rectOrig
;
1557 // the current tab is drawn indented (to the top for default case) and
1558 // bigger than the other ones
1559 const wxSize indent
= GetTabIndent();
1560 if ( flags
& wxCONTROL_SELECTED
)
1565 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1569 rect
.Inflate(indent
.x
, 0);
1571 rect
.height
+= indent
.y
;
1575 rect
.Inflate(indent
.x
, 0);
1576 rect
.height
+= indent
.y
;
1581 wxFAIL_MSG(_T("TODO"));
1586 // selected tab has different colour
1587 wxColour col
= flags
& wxCONTROL_SELECTED
1588 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1589 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1590 DoDrawBackground(dc
, col
, rect
);
1592 if ( flags
& wxCONTROL_FOCUSED
)
1594 // draw the focus rect
1595 wxRect rectBorder
= rect
;
1596 rectBorder
.Deflate(4, 3);
1597 if ( dir
== wxBOTTOM
)
1598 rectBorder
.Offset(0, -1);
1600 DrawRect(dc
, &rectBorder
, m_penBlack
);
1603 // draw the text, image and the focus around them (if necessary)
1604 wxRect rectLabel
= rect
;
1605 rectLabel
.Deflate(1, 1);
1606 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1608 // now draw the tab itself
1611 x2
= rect
.GetRight(),
1612 y2
= rect
.GetBottom();
1617 dc
.SetPen(m_penHighlight
);
1618 dc
.DrawLine(x
, y2
, x
, y
);
1619 dc
.DrawLine(x
+ 1, y
, x2
, y
);
1621 dc
.SetPen(m_penBlack
);
1622 dc
.DrawLine(x2
, y2
, x2
, y
);
1624 dc
.SetPen(m_penDarkGrey
);
1625 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ 1);
1627 if ( flags
& wxCONTROL_SELECTED
)
1629 dc
.SetPen(m_penLightGrey
);
1631 // overwrite the part of the border below this tab
1632 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
1634 // and the shadow of the tab to the left of us
1635 dc
.DrawLine(x
+ 1, y
+ 2, x
+ 1, y2
+ 1);
1640 dc
.SetPen(m_penHighlight
);
1642 // we need to continue one pixel further to overwrite the corner of
1643 // the border for the selected tab
1644 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
1647 // it doesn't work like this (TODO: implement it properly)
1649 // erase the corner of the tab to the right
1650 dc
.SetPen(m_penLightGrey
);
1651 dc
.DrawPoint(x2
- 1, y
- 2);
1652 dc
.DrawPoint(x2
- 2, y
- 2);
1653 dc
.DrawPoint(x2
- 2, y
- 1);
1656 dc
.SetPen(m_penBlack
);
1657 dc
.DrawLine(x
+ 1, y2
, x2
, y2
);
1658 dc
.DrawLine(x2
, y
, x2
, y2
);
1660 dc
.SetPen(m_penDarkGrey
);
1661 dc
.DrawLine(x
+ 2, y2
- 1, x2
- 1, y2
- 1);
1662 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
);
1664 if ( flags
& wxCONTROL_SELECTED
)
1666 dc
.SetPen(m_penLightGrey
);
1668 // overwrite the part of the (double!) border above this tab
1669 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
1670 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
1672 // and the shadow of the tab to the left of us
1673 dc
.DrawLine(x
+ 1, y2
- 1, x
+ 1, y
- 1);
1679 wxFAIL_MSG(_T("TODO"));
1683 // ----------------------------------------------------------------------------
1685 // ----------------------------------------------------------------------------
1687 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1688 wxOrientation orient
) const
1690 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1694 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
1695 if ( orient
== wxHORIZONTAL
)
1697 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1698 size
.y
= rectShaft
.height
;
1702 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1703 size
.x
= rectShaft
.width
;
1709 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1710 wxOrientation
WXUNUSED(orient
)) const
1712 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
1715 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
1716 const wxRect
& rectOrig
,
1717 wxOrientation orient
,
1721 wxRect rect
= rectOrig
;
1723 // draw the border first
1724 if ( flags
& wxCONTROL_FOCUSED
)
1726 DrawRect(dc
, &rect
, m_penBlack
);
1727 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1729 else // not focused, normal
1731 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1732 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1735 // and the background
1736 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
1742 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
1743 const wxRect
& rectOrig
,
1744 wxOrientation orient
,
1747 // draw the thumb border
1748 wxRect rect
= rectOrig
;
1749 DrawAntiRaisedBorder(dc
, &rect
);
1751 // draw the handle in the middle
1752 if ( orient
== wxVERTICAL
)
1754 rect
.height
= 2*BORDER_THICKNESS
;
1755 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
1759 rect
.width
= 2*BORDER_THICKNESS
;
1760 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
1763 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1767 // ----------------------------------------------------------------------------
1769 // ----------------------------------------------------------------------------
1771 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
1773 const wxString
& label
,
1777 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE
, indexAccel
);
1780 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
1782 const wxMenuGeometryInfo
& geometryInfo
,
1783 const wxString
& label
,
1784 const wxString
& accel
,
1785 const wxBitmap
& bitmap
,
1789 wxFAIL_MSG(_T("TODO"));
1792 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
1794 const wxMenuGeometryInfo
& geomInfo
)
1796 wxFAIL_MSG(_T("TODO"));
1799 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
1804 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
1805 const wxMenu
& menu
) const
1807 wxFAIL_MSG(_T("TODO"));
1811 #endif // wxUSE_MENUS
1813 // ----------------------------------------------------------------------------
1815 // ----------------------------------------------------------------------------
1817 void wxGTKRenderer::InitComboBitmaps()
1819 wxSize sizeArrow
= m_sizeScrollbarArrow
;
1825 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1827 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
1830 static const int comboButtonFlags
[ComboState_Max
] =
1838 wxRect
rect(wxPoint(0, 0), sizeArrow
);
1841 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1843 int flags
= comboButtonFlags
[n
];
1845 dc
.SelectObject(m_bitmapsCombo
[n
]);
1846 DoDrawBackground(dc
, GetBackgroundColour(flags
), rect
);
1847 DrawArrow(dc
, wxDOWN
, rect
, flags
);
1851 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
1853 wxBitmap
*bmpPressed
,
1854 wxBitmap
*bmpDisabled
)
1856 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
1862 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
1864 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
1866 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
1868 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
1871 // ----------------------------------------------------------------------------
1873 // ----------------------------------------------------------------------------
1875 void wxGTKRenderer::DoDrawBackground(wxDC
& dc
,
1876 const wxColour
& col
,
1879 wxBrush
brush(col
, wxSOLID
);
1881 dc
.SetPen(*wxTRANSPARENT_PEN
);
1882 dc
.DrawRectangle(rect
);
1885 void wxGTKRenderer::DrawBackground(wxDC
& dc
,
1886 const wxColour
& col
,
1890 wxColour colBg
= col
.Ok() ? col
: GetBackgroundColour(flags
);
1891 DoDrawBackground(dc
, colBg
, rect
);
1894 // ----------------------------------------------------------------------------
1896 // ----------------------------------------------------------------------------
1898 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
1902 static const wxDirection sides
[] =
1904 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
1907 wxRect rect1
, rect2
, rectInner
;
1913 rectInner
.Inflate(-2);
1915 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
1917 // find the side not to draw and also adjust the rectangles to compensate
1919 wxDirection sideToOmit
;
1923 sideToOmit
= wxDOWN
;
1925 rectInner
.height
+= 1;
1933 rectInner
.height
+= 1;
1937 sideToOmit
= wxRIGHT
;
1939 rectInner
.width
+= 1;
1943 sideToOmit
= wxLEFT
;
1947 rectInner
.width
+= 1;
1951 wxFAIL_MSG(_T("unknown arrow direction"));
1955 // the outer rect first
1957 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
1959 wxDirection side
= sides
[n
];
1960 if ( side
== sideToOmit
)
1963 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
1966 // and then the inner one
1967 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
1969 wxDirection side
= sides
[n
];
1970 if ( side
== sideToOmit
)
1973 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
1979 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
1981 const wxRect
& rectArrow
,
1984 // first of all, draw the border around it - but we don't want the border
1985 // on the side opposite to the arrow point
1986 wxRect rect
= rectArrow
;
1987 DrawArrowBorder(dc
, &rect
, dir
);
1989 // then the arrow itself
1990 DrawArrow(dc
, dir
, rect
, flags
);
1993 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
1994 // these people are just crazy :-(
1995 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2008 wxPoint ptArrow
[Point_Max
];
2010 wxColour colInside
= GetBackgroundColour(flags
);
2012 if ( flags
& wxCONTROL_DISABLED
)
2014 penShadow
[0] = m_penDarkGrey
;
2015 penShadow
[1] = m_penDarkGrey
;
2016 penShadow
[2] = wxNullPen
;
2017 penShadow
[3] = wxNullPen
;
2019 else if ( flags
& wxCONTROL_PRESSED
)
2021 penShadow
[0] = m_penDarkGrey
;
2022 penShadow
[1] = m_penHighlight
;
2023 penShadow
[2] = wxNullPen
;
2024 penShadow
[3] = m_penBlack
;
2026 else // normal arrow
2028 penShadow
[0] = m_penHighlight
;
2029 penShadow
[1] = m_penBlack
;
2030 penShadow
[2] = m_penDarkGrey
;
2031 penShadow
[3] = wxNullPen
;
2035 if ( dir
== wxUP
|| dir
== wxDOWN
)
2038 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2042 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2045 // draw the arrow interior
2046 dc
.SetPen(*wxTRANSPARENT_PEN
);
2047 dc
.SetBrush(wxBrush(colInside
, wxSOLID
));
2052 ptArrow
[Point_First
].x
= rect
.GetLeft();
2053 ptArrow
[Point_First
].y
= rect
.GetBottom();
2054 ptArrow
[Point_Second
].x
= middle
;
2055 ptArrow
[Point_Second
].y
= rect
.GetTop();
2056 ptArrow
[Point_Third
].x
= rect
.GetRight();
2057 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2061 ptArrow
[Point_First
] = rect
.GetPosition();
2062 ptArrow
[Point_Second
].x
= middle
;
2063 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2064 ptArrow
[Point_Third
].x
= rect
.GetRight();
2065 ptArrow
[Point_Third
].y
= rect
.GetTop();
2069 ptArrow
[Point_First
].x
= rect
.GetRight();
2070 ptArrow
[Point_First
].y
= rect
.GetTop();
2071 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2072 ptArrow
[Point_Second
].y
= middle
;
2073 ptArrow
[Point_Third
].x
= rect
.GetRight();
2074 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2078 ptArrow
[Point_First
] = rect
.GetPosition();
2079 ptArrow
[Point_Second
].x
= rect
.GetRight();
2080 ptArrow
[Point_Second
].y
= middle
;
2081 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2082 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2086 wxFAIL_MSG(_T("unknown arrow direction"));
2089 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2091 // draw the arrow border
2092 dc
.SetPen(penShadow
[0]);
2096 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2097 dc
.DrawPoint(ptArrow
[Point_First
]);
2098 if ( penShadow
[3].Ok() )
2100 dc
.SetPen(penShadow
[3]);
2101 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2102 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2104 dc
.SetPen(penShadow
[1]);
2105 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2106 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2107 dc
.DrawPoint(ptArrow
[Point_Third
]);
2108 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2109 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2110 if ( penShadow
[2].Ok() )
2112 dc
.SetPen(penShadow
[2]);
2113 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2114 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2115 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2116 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2121 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2122 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2123 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2124 if ( penShadow
[2].Ok() )
2126 dc
.SetPen(penShadow
[2]);
2127 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2128 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2130 dc
.SetPen(penShadow
[1]);
2131 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2132 dc
.DrawPoint(ptArrow
[Point_Third
]);
2136 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2137 dc
.DrawPoint(ptArrow
[Point_First
]);
2138 if ( penShadow
[2].Ok() )
2140 dc
.SetPen(penShadow
[2]);
2141 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2142 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2143 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2144 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2146 dc
.SetPen(penShadow
[1]);
2147 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2148 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2149 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2150 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2154 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2155 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2156 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2157 dc
.SetPen(penShadow
[1]);
2158 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2159 dc
.DrawPoint(ptArrow
[Point_Third
]);
2163 wxFAIL_MSG(_T("unknown arrow direction"));
2168 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2170 wxOrientation orient
)
2172 if ( orient
== wxVERTICAL
)
2174 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2176 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2178 rect
->Inflate(-1, 0);
2180 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2182 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2184 rect
->Inflate(-1, 0);
2188 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2190 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2192 rect
->Inflate(0, -1);
2194 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2196 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2198 rect
->Inflate(0, -1);
2202 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2203 wxOrientation orient
,
2207 // the thumb is never pressed never has focus border under GTK and the
2208 // scrollbar background never changes at all
2209 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2211 // we don't want the border in the direction of the scrollbar movement
2212 wxRect rectThumb
= rect
;
2213 DrawThumbBorder(dc
, &rectThumb
, orient
);
2215 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2216 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2219 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2220 wxOrientation orient
,
2224 wxRect rectBar
= rect
;
2225 DrawThumbBorder(dc
, &rectBar
, orient
);
2226 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2229 void wxGTKRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2231 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2234 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2235 wxScrollBar::Element elem
,
2238 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2239 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2241 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2243 elem
= wxScrollBar::Element_Bar_2
;
2246 return StandardGetScrollbarRect(scrollbar
, elem
,
2248 GetScrollbarArrowSize(scrollbar
));
2251 wxCoord
wxGTKRenderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
2253 return StandardScrollBarSize(scrollbar
, GetScrollbarArrowSize(scrollbar
));
2256 wxHitTest
wxGTKRenderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
2257 const wxPoint
& pt
) const
2259 return StandardHitTestScrollbar(scrollbar
, pt
,
2260 GetScrollbarArrowSize(scrollbar
));
2263 wxCoord
wxGTKRenderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
2266 return StandardScrollbarToPixel(scrollbar
, thumbPos
,
2267 GetScrollbarArrowSize(scrollbar
));
2270 int wxGTKRenderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
2273 return StandardPixelToScrollbar(scrollbar
, coord
,
2274 GetScrollbarArrowSize(scrollbar
));
2277 // ----------------------------------------------------------------------------
2279 // ----------------------------------------------------------------------------
2281 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2283 if ( wxDynamicCast(window
, wxButton
) )
2285 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2287 // TODO: this is ad hoc...
2288 size
->x
+= 3*window
->GetCharWidth();
2289 wxCoord minBtnHeight
= 18;
2290 if ( size
->y
< minBtnHeight
)
2291 size
->y
= minBtnHeight
;
2293 // button border width
2297 else if ( wxDynamicCast(window
, wxScrollBar
) )
2299 // we only set the width of vert scrollbars and height of the
2301 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2302 size
->y
= m_sizeScrollbarArrow
.x
;
2304 size
->x
= m_sizeScrollbarArrow
.x
;
2308 // take into account the border width
2309 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
2310 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
2311 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
2315 // ============================================================================
2317 // ============================================================================
2319 // ----------------------------------------------------------------------------
2320 // wxGTKInputHandler
2321 // ----------------------------------------------------------------------------
2323 wxGTKInputHandler::wxGTKInputHandler(wxGTKRenderer
*renderer
)
2325 m_renderer
= renderer
;
2328 bool wxGTKInputHandler::HandleKey(wxControl
*control
,
2329 const wxKeyEvent
& event
,
2335 bool wxGTKInputHandler::HandleMouse(wxControl
*control
,
2336 const wxMouseEvent
& event
)
2338 // clicking on the control gives it focus
2339 if ( event
.ButtonDown() )
2341 control
->SetFocus();
2349 bool wxGTKInputHandler::HandleMouseMove(wxControl
*control
,
2350 const wxMouseEvent
& event
)
2352 if ( event
.Entering() )
2354 control
->SetCurrent(TRUE
);
2356 else if ( event
.Leaving() )
2358 control
->SetCurrent(FALSE
);
2368 // ----------------------------------------------------------------------------
2369 // wxGTKCheckboxInputHandler
2370 // ----------------------------------------------------------------------------
2372 bool wxGTKCheckboxInputHandler::HandleKey(wxControl
*control
,
2373 const wxKeyEvent
& event
,
2378 int keycode
= event
.GetKeyCode();
2379 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
2381 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
2390 // ----------------------------------------------------------------------------
2391 // wxGTKTextCtrlInputHandler
2392 // ----------------------------------------------------------------------------
2394 bool wxGTKTextCtrlInputHandler::HandleKey(wxControl
*control
,
2395 const wxKeyEvent
& event
,
2398 // handle only GTK-specific text bindings here, the others are handled in
2402 wxControlAction action
;
2403 int keycode
= event
.GetKeyCode();
2404 if ( event
.ControlDown() )
2409 action
= wxACTION_TEXT_HOME
;
2413 action
= wxACTION_TEXT_LEFT
;
2417 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
2421 action
= wxACTION_TEXT_END
;
2425 action
= wxACTION_TEXT_RIGHT
;
2429 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
2433 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2437 action
= wxACTION_TEXT_DOWN
;
2441 action
= wxACTION_TEXT_UP
;
2445 //delete the entire line
2446 control
->PerformAction(wxACTION_TEXT_HOME
);
2447 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2451 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
2455 else if ( event
.AltDown() )
2460 action
= wxACTION_TEXT_WORD_LEFT
;
2464 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
2468 action
= wxACTION_TEXT_WORD_RIGHT
;
2473 if ( action
!= wxACTION_NONE
)
2475 control
->PerformAction(action
);
2481 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);