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/bmpbuttn.h"
34 #include "wx/button.h"
35 #include "wx/checkbox.h"
36 #include "wx/listbox.h"
37 #include "wx/checklst.h"
38 #include "wx/combobox.h"
39 #include "wx/scrolbar.h"
40 #include "wx/slider.h"
41 #include "wx/textctrl.h"
44 #include "wx/notebook.h"
45 #include "wx/spinbutt.h"
47 #include "wx/univ/renderer.h"
48 #include "wx/univ/inphand.h"
49 #include "wx/univ/colschem.h"
50 #include "wx/univ/theme.h"
52 // ----------------------------------------------------------------------------
53 // constants (to be removed, for testing only)
54 // ----------------------------------------------------------------------------
56 static const size_t BORDER_THICKNESS
= 1;
58 // ----------------------------------------------------------------------------
59 // wxGTKRenderer: draw the GUI elements in GTK style
60 // ----------------------------------------------------------------------------
62 class wxGTKRenderer
: public wxRenderer
65 wxGTKRenderer(const wxColourScheme
*scheme
);
67 // implement the base class pure virtuals
68 virtual void DrawBackground(wxDC
& dc
,
72 virtual void DrawLabel(wxDC
& dc
,
73 const wxString
& label
,
76 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
78 wxRect
*rectBounds
= NULL
);
79 virtual void DrawButtonLabel(wxDC
& dc
,
80 const wxString
& label
,
81 const wxBitmap
& image
,
84 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
86 wxRect
*rectBounds
= NULL
);
87 virtual void DrawBorder(wxDC
& dc
,
91 wxRect
*rectIn
= (wxRect
*)NULL
);
92 virtual void DrawHorizontalLine(wxDC
& dc
,
93 wxCoord y
, wxCoord x1
, wxCoord x2
);
94 virtual void DrawVerticalLine(wxDC
& dc
,
95 wxCoord x
, wxCoord y1
, wxCoord y2
);
96 virtual void DrawFrame(wxDC
& dc
,
97 const wxString
& label
,
100 int alignment
= wxALIGN_LEFT
,
101 int indexAccel
= -1);
102 virtual void DrawTextBorder(wxDC
& dc
,
106 wxRect
*rectIn
= (wxRect
*)NULL
);
107 virtual void DrawButtonBorder(wxDC
& dc
,
110 wxRect
*rectIn
= (wxRect
*)NULL
);
111 virtual void DrawArrow(wxDC
& dc
,
115 virtual void DrawScrollbarArrow(wxDC
& dc
,
119 virtual void DrawScrollbarThumb(wxDC
& dc
,
120 wxOrientation orient
,
123 virtual void DrawScrollbarShaft(wxDC
& dc
,
124 wxOrientation orient
,
127 virtual void DrawScrollCorner(wxDC
& dc
,
129 virtual void DrawItem(wxDC
& dc
,
130 const wxString
& label
,
133 virtual void DrawCheckItem(wxDC
& dc
,
134 const wxString
& label
,
135 const wxBitmap
& bitmap
,
138 virtual void DrawCheckButton(wxDC
& dc
,
139 const wxString
& label
,
140 const wxBitmap
& bitmap
,
143 wxAlignment align
= wxALIGN_LEFT
,
144 int indexAccel
= -1);
146 virtual void DrawRadioButton(wxDC
& dc
,
147 const wxString
& label
,
148 const wxBitmap
& bitmap
,
151 wxAlignment align
= wxALIGN_LEFT
,
152 int indexAccel
= -1);
154 virtual void DrawTextLine(wxDC
& dc
,
155 const wxString
& text
,
160 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
161 virtual void DrawTab(wxDC
& dc
,
164 const wxString
& label
,
165 const wxBitmap
& bitmap
= wxNullBitmap
,
167 int indexAccel
= -1);
169 virtual void DrawSliderShaft(wxDC
& dc
,
171 wxOrientation orient
,
173 wxRect
*rectShaft
= NULL
);
174 virtual void DrawSliderThumb(wxDC
& dc
,
176 wxOrientation orient
,
178 virtual void DrawSliderTicks(wxDC
& dc
,
180 const wxSize
& sizeThumb
,
181 wxOrientation orient
,
187 // we don't have the ticks in GTK version
191 virtual void DrawMenuBarItem(wxDC
& dc
,
193 const wxString
& label
,
195 int indexAccel
= -1);
196 virtual void DrawMenuItem(wxDC
& dc
,
198 const wxMenuGeometryInfo
& geometryInfo
,
199 const wxString
& label
,
200 const wxString
& accel
,
201 const wxBitmap
& bitmap
= wxNullBitmap
,
203 int indexAccel
= -1);
204 virtual void DrawMenuSeparator(wxDC
& dc
,
206 const wxMenuGeometryInfo
& geomInfo
);
208 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
210 wxBitmap
*bmpPressed
,
211 wxBitmap
*bmpDisabled
);
213 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
214 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
215 virtual bool AreScrollbarsInsideBorder() const;
217 // geometry and hit testing
218 virtual wxSize
GetScrollbarArrowSize() const
219 { return m_sizeScrollbarArrow
; }
220 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
221 wxScrollBar::Element elem
,
222 int thumbPos
= -1) const;
223 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
224 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
225 const wxPoint
& pt
) const;
226 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
228 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
229 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
230 { return fontHeight
+ 2; }
231 virtual wxSize
GetCheckBitmapSize() const
232 { return wxSize(10, 10); }
233 virtual wxSize
GetRadioBitmapSize() const
234 { return wxSize(11, 11); }
235 virtual wxCoord
GetCheckItemMargin() const
238 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
240 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
242 wxCoord
*extraSpaceBeyond
);
244 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
245 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
247 virtual wxCoord
GetSliderDim() const { return 15; }
248 virtual wxCoord
GetSliderTickLen() const { return 0; }
249 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
250 wxOrientation orient
) const;
251 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
252 wxOrientation orient
) const;
253 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
256 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
257 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
258 const wxMenu
& menu
) const;
260 // helpers for "wxBitmap wxColourScheme::Get()"
261 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
262 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
265 // DrawBackground() helpers
267 // get the colour to use for background
268 wxColour
GetBackgroundColour(int flags
) const
270 if ( flags
& wxCONTROL_PRESSED
)
271 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
272 else if ( flags
& wxCONTROL_CURRENT
)
273 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
275 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
278 // draw the background with any colour, not only the default one(s)
279 void DoDrawBackground(wxDC
& dc
,
283 // DrawBorder() helpers: all of them shift and clip the DC after drawing
286 // just draw a rectangle with the given pen
287 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
289 // draw the lower left part of rectangle
290 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
292 // draw the rectange using the first brush for the left and top sides and
293 // the second one for the bottom and right ones
294 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
295 const wxPen
& pen1
, const wxPen
& pen2
);
297 // as DrawShadedRect() but the pixels in the bottom left and upper right
298 // border are drawn with the pen1, not pen2
299 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
300 const wxPen
& pen1
, const wxPen
& pen2
);
302 // used for drawing opened rectangles - draws only one side of it at once
303 // (and doesn't adjust the rect)
304 void DrawAntiShadedRectSide(wxDC
& dc
,
310 // draw an opened rect for the arrow in given direction
311 void DrawArrowBorder(wxDC
& dc
,
315 // draw two sides of the rectangle
316 void DrawThumbBorder(wxDC
& dc
,
318 wxOrientation orient
);
320 // draw the normal 3D border
321 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
323 // just as DrawRaisedBorder() except that the bottom left and up right
324 // pixels of the interior rect are drawn in another colour (i.e. the inner
325 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
326 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
328 // returns the size of the arrow for the scrollbar (depends on
330 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
333 if ( scrollbar
->IsVertical() )
335 size
= m_sizeScrollbarArrow
;
339 size
.x
= m_sizeScrollbarArrow
.y
;
340 size
.y
= m_sizeScrollbarArrow
.x
;
346 // get the line wrap indicator bitmap
347 wxBitmap
GetLineWrapBitmap();
349 // DrawCheckBitmap and DrawRadioBitmap helpers
351 // draw the check bitmaps once and cache them for later use
352 wxBitmap
GetCheckBitmap(int flags
);
354 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
356 void DrawUpZag(wxDC
& dc
,
357 wxCoord x1
, wxCoord x2
,
358 wxCoord y1
, wxCoord y2
);
359 void DrawDownZag(wxDC
& dc
,
360 wxCoord x1
, wxCoord x2
,
361 wxCoord y1
, wxCoord y2
);
363 // draw the radio button bitmap for the given state
364 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
366 // draw check/radio - the bitmap must be a valid one by now
367 void DoDrawCheckOrRadioBitmap(wxDC
& dc
,
368 const wxString
& label
,
369 const wxBitmap
& bitmap
,
370 const wxRect
& rectTotal
,
375 // initialize the combo bitmaps
376 void InitComboBitmaps();
379 const wxColourScheme
*m_scheme
;
382 wxSize m_sizeScrollbarArrow
;
391 // the checkbox bitmaps: first row is for the normal, second for the
392 // pressed state and the columns are for checked and unchecked status
394 wxBitmap m_bitmapsCheckbox
[2][2];
396 // the line wrap bitmap (drawn at the end of wrapped lines)
397 wxBitmap m_bmpLineWrap
;
399 // the combobox bitmaps
409 wxBitmap m_bitmapsCombo
[ComboState_Max
];
412 // ----------------------------------------------------------------------------
413 // wxGTKInputHandler and derived classes: process the keyboard and mouse
414 // messages according to GTK standards
415 // ----------------------------------------------------------------------------
417 class wxGTKInputHandler
: public wxInputHandler
420 wxGTKInputHandler(wxGTKRenderer
*renderer
);
422 virtual bool HandleKey(wxControl
*control
,
423 const wxKeyEvent
& event
,
425 virtual bool HandleMouse(wxControl
*control
,
426 const wxMouseEvent
& event
);
427 virtual bool HandleMouseMove(wxControl
*control
, const wxMouseEvent
& event
);
430 wxGTKRenderer
*m_renderer
;
433 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
436 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
437 : wxStdScrollBarInputHandler(renderer
, handler
) { }
440 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
442 // only arrows and the thumb can be highlighted
443 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
446 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
449 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
451 // only arrows can be pressed
455 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
458 virtual bool IsAllowedButton(int WXUNUSED(button
)) { return TRUE
; }
462 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
463 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
467 class wxGTKCheckboxInputHandler
: public wxStdCheckboxInputHandler
470 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
471 : wxStdCheckboxInputHandler(handler
) { }
473 virtual bool HandleKey(wxControl
*control
,
474 const wxKeyEvent
& event
,
478 class wxGTKTextCtrlInputHandler
: public wxStdTextCtrlInputHandler
481 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
482 : wxStdTextCtrlInputHandler(handler
) { }
484 virtual bool HandleKey(wxControl
*control
,
485 const wxKeyEvent
& event
,
489 // ----------------------------------------------------------------------------
490 // wxGTKColourScheme: uses the standard GTK colours
491 // ----------------------------------------------------------------------------
493 class wxGTKColourScheme
: public wxColourScheme
496 virtual wxColour
Get(StdColour col
) const;
497 virtual wxColour
GetBackground(wxWindow
*win
) const;
500 // ----------------------------------------------------------------------------
502 // ----------------------------------------------------------------------------
504 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
506 class wxGTKTheme
: public wxTheme
510 virtual ~wxGTKTheme();
512 virtual wxRenderer
*GetRenderer() { return m_renderer
; }
513 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
514 virtual wxColourScheme
*GetColourScheme() { return m_scheme
; }
517 // get the default input handler
518 wxInputHandler
*GetDefaultInputHandler();
520 wxGTKRenderer
*m_renderer
;
522 // the names of the already created handlers and the handlers themselves
523 // (these arrays are synchronized)
524 wxSortedArrayString m_handlerNames
;
525 wxArrayHandlers m_handlers
;
527 wxGTKInputHandler
*m_handlerDefault
;
529 wxGTKColourScheme
*m_scheme
;
531 WX_DECLARE_THEME(gtk
)
534 // ============================================================================
536 // ============================================================================
538 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
540 // ----------------------------------------------------------------------------
542 // ----------------------------------------------------------------------------
544 wxGTKTheme::wxGTKTheme()
546 m_scheme
= new wxGTKColourScheme
;
547 m_renderer
= new wxGTKRenderer(m_scheme
);
548 m_handlerDefault
= NULL
;
551 wxGTKTheme::~wxGTKTheme()
553 size_t count
= m_handlers
.GetCount();
554 for ( size_t n
= 0; n
< count
; n
++ )
556 if ( m_handlers
[n
] != m_handlerDefault
)
557 delete m_handlers
[n
];
560 delete m_handlerDefault
;
565 wxInputHandler
*wxGTKTheme::GetDefaultInputHandler()
567 if ( !m_handlerDefault
)
569 m_handlerDefault
= new wxGTKInputHandler(m_renderer
);
572 return m_handlerDefault
;
575 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
)
577 wxInputHandler
*handler
;
578 int n
= m_handlerNames
.Index(control
);
579 if ( n
== wxNOT_FOUND
)
581 // create a new handler
582 if ( control
== wxINP_HANDLER_SCROLLBAR
)
583 handler
= new wxGTKScrollBarInputHandler(m_renderer
,
584 GetDefaultInputHandler());
586 else if ( control
== wxINP_HANDLER_BUTTON
)
587 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
588 #endif // wxUSE_CHECKBOX
590 else if ( control
== wxINP_HANDLER_CHECKBOX
)
591 handler
= new wxGTKCheckboxInputHandler(GetDefaultInputHandler());
592 #endif // wxUSE_CHECKBOX
594 else if ( control
== wxINP_HANDLER_COMBOBOX
)
595 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
596 #endif // wxUSE_COMBOBOX
598 else if ( control
== wxINP_HANDLER_LISTBOX
)
599 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
600 #endif // wxUSE_LISTBOX
601 #if wxUSE_CHECKLISTBOX
602 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
603 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
604 #endif // wxUSE_CHECKLISTBOX
606 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
607 handler
= new wxGTKTextCtrlInputHandler(GetDefaultInputHandler());
608 #endif // wxUSE_TEXTCTRL
610 else if ( control
== wxINP_HANDLER_SLIDER
)
611 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
612 #endif // wxUSE_SLIDER
614 else if ( control
== wxINP_HANDLER_SPINBTN
)
615 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
616 #endif // wxUSE_SPINBTN
618 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
619 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
620 #endif // wxUSE_NOTEBOOK
622 handler
= GetDefaultInputHandler();
624 n
= m_handlerNames
.Add(control
);
625 m_handlers
.Insert(handler
, n
);
627 else // we already have it
629 handler
= m_handlers
[n
];
635 // ============================================================================
637 // ============================================================================
639 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
642 if ( win
->UseBgCol() )
644 // use the user specified colour
645 col
= win
->GetBackgroundColour();
648 if ( win
->IsContainerWindow() )
650 // doesn't depend on the state
658 int flags
= win
->GetStateFlags();
660 // the colour set by the user should be used for the normal state
661 // and for the states for which we don't have any specific colours
662 if ( !col
.Ok() || (flags
!= 0) )
664 if ( wxDynamicCast(win
, wxScrollBar
) )
665 col
= Get(SCROLLBAR
);
666 else if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
667 col
= Get(CONTROL_CURRENT
);
668 else if ( flags
& wxCONTROL_PRESSED
)
669 col
= Get(CONTROL_PRESSED
);
678 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
682 case WINDOW
: return *wxWHITE
;
684 case SHADOW_DARK
: return *wxBLACK
;
685 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
686 case SHADOW_IN
: return wxColour(0xd6d6d6);
687 case SHADOW_OUT
: return wxColour(0x969696);
689 case CONTROL
: return wxColour(0xd6d6d6);
690 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
691 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
693 case CONTROL_TEXT
: return *wxBLACK
;
694 case CONTROL_TEXT_DISABLED
:
695 return wxColour(0x757575);
696 case CONTROL_TEXT_DISABLED_SHADOW
:
700 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
702 case HIGHLIGHT
: return wxColour(0x9c0000);
703 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
707 wxFAIL_MSG(_T("invalid standard colour"));
712 // ============================================================================
714 // ============================================================================
716 // ----------------------------------------------------------------------------
718 // ----------------------------------------------------------------------------
720 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
724 m_sizeScrollbarArrow
= wxSize(15, 14);
727 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
728 m_penDarkGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_OUT
), 0, wxSOLID
);
729 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
), 0, wxSOLID
);
730 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
731 m_penHighlight
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
), 0, wxSOLID
);
734 // ----------------------------------------------------------------------------
736 // ----------------------------------------------------------------------------
738 void wxGTKRenderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
742 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
743 dc
.DrawRectangle(*rect
);
749 void wxGTKRenderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
751 // draw the bottom and right sides
753 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
754 rect
->GetRight() + 1, rect
->GetBottom());
755 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
756 rect
->GetRight(), rect
->GetBottom());
763 void wxGTKRenderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
764 const wxPen
& pen1
, const wxPen
& pen2
)
766 // draw the rectangle
768 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
769 rect
->GetLeft(), rect
->GetBottom());
770 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
771 rect
->GetRight(), rect
->GetTop());
773 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
774 rect
->GetRight(), rect
->GetBottom());
775 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
776 rect
->GetRight() + 1, rect
->GetBottom());
782 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
788 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
793 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
794 rect
.GetLeft(), rect
.GetBottom() + 1);
798 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
799 rect
.GetRight() + 1, rect
.GetTop());
803 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
804 rect
.GetRight(), rect
.GetBottom() + 1);
808 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
809 rect
.GetRight() + 1, rect
.GetBottom());
813 wxFAIL_MSG(_T("unknown rectangle side"));
817 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
818 const wxPen
& pen1
, const wxPen
& pen2
)
820 // draw the rectangle
822 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
823 rect
->GetLeft(), rect
->GetBottom() + 1);
824 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
825 rect
->GetRight() + 1, rect
->GetTop());
827 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
828 rect
->GetRight(), rect
->GetBottom());
829 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
830 rect
->GetRight() + 1, rect
->GetBottom());
836 void wxGTKRenderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
838 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
839 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
842 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
844 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
845 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
848 void wxGTKRenderer::DrawBorder(wxDC
& dc
,
850 const wxRect
& rectTotal
,
856 wxRect rect
= rectTotal
;
860 case wxBORDER_SUNKEN
:
861 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
863 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
864 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
868 case wxBORDER_STATIC
:
869 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
871 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
875 case wxBORDER_RAISED
:
876 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
878 DrawRaisedBorder(dc
, &rect
);
882 case wxBORDER_DOUBLE
:
883 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
885 DrawShadedRect(dc
, &rect
, m_penLightGrey
, m_penBlack
);
886 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penDarkGrey
);
887 DrawRect(dc
, &rect
, m_penLightGrey
);
891 case wxBORDER_SIMPLE
:
892 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
894 DrawRect(dc
, &rect
, m_penBlack
);
899 wxFAIL_MSG(_T("unknown border type"));
902 case wxBORDER_DEFAULT
:
911 wxRect
wxGTKRenderer::GetBorderDimensions(wxBorder border
) const
916 case wxBORDER_RAISED
:
917 case wxBORDER_SUNKEN
:
918 width
= 2*BORDER_THICKNESS
;
921 case wxBORDER_SIMPLE
:
922 case wxBORDER_STATIC
:
923 width
= BORDER_THICKNESS
;
926 case wxBORDER_DOUBLE
:
927 width
= 3*BORDER_THICKNESS
;
931 wxFAIL_MSG(_T("unknown border type"));
934 case wxBORDER_DEFAULT
:
949 bool wxGTKRenderer::AreScrollbarsInsideBorder() const
951 // no, the scrollbars are outside the border in GTK+
955 // ----------------------------------------------------------------------------
957 // ----------------------------------------------------------------------------
959 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
961 const wxRect
& rectOrig
,
965 wxRect rect
= rectOrig
;
967 if ( border
!= wxBORDER_NONE
)
969 if ( flags
& wxCONTROL_FOCUSED
)
971 DrawRect(dc
, &rect
, m_penBlack
);
972 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
976 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
977 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penHighlight
);
985 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
986 const wxRect
& rectTotal
,
990 wxRect rect
= rectTotal
;
992 if ( flags
& wxCONTROL_PRESSED
)
994 // button pressed: draw a black border around it and an inward shade
995 DrawRect(dc
, &rect
, m_penBlack
);
997 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
999 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1000 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penDarkGrey
);
1005 // button not pressed
1007 if ( flags
& wxCONTROL_ISDEFAULT
)
1012 if ( flags
& wxCONTROL_FOCUSED
)
1014 // button is currently default: add an extra border around it
1015 DrawRect(dc
, &rect
, m_penBlack
);
1018 // now draw a normal button
1019 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1021 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1022 DrawAntiShadedRect(dc
, &rect
,
1023 wxPen(GetBackgroundColour(flags
), 0, wxSOLID
),
1034 // ----------------------------------------------------------------------------
1036 // ----------------------------------------------------------------------------
1038 void wxGTKRenderer::DrawHorizontalLine(wxDC
& dc
,
1039 wxCoord y
, wxCoord x1
, wxCoord x2
)
1041 dc
.SetPen(m_penDarkGrey
);
1042 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1043 dc
.SetPen(m_penHighlight
);
1045 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1048 void wxGTKRenderer::DrawVerticalLine(wxDC
& dc
,
1049 wxCoord x
, wxCoord y1
, wxCoord y2
)
1051 dc
.SetPen(m_penDarkGrey
);
1052 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1053 dc
.SetPen(m_penHighlight
);
1055 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1058 void wxGTKRenderer::DrawFrame(wxDC
& dc
,
1059 const wxString
& label
,
1065 wxCoord height
= 0; // of the label
1066 wxRect rectFrame
= rect
;
1067 if ( !label
.empty() )
1069 // the text should touch the top border of the rect, so the frame
1070 // itself should be lower
1071 dc
.GetTextExtent(label
, NULL
, &height
);
1072 rectFrame
.y
+= height
/ 2;
1073 rectFrame
.height
-= height
/ 2;
1075 // TODO: the +4 should be customizable
1078 rectText
.x
= rectFrame
.x
+ 4;
1079 rectText
.y
= rect
.y
;
1080 rectText
.width
= rectFrame
.width
- 8;
1081 rectText
.height
= height
;
1084 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1086 rectLabel
.width
+= 2;
1088 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1090 // GTK+ does it like this
1091 dc
.SetPen(m_penHighlight
);
1092 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
1093 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
1097 // just draw the complete frame
1098 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1099 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1103 // ----------------------------------------------------------------------------
1105 // ----------------------------------------------------------------------------
1107 void wxGTKRenderer::DrawLabel(wxDC
& dc
,
1108 const wxString
& label
,
1115 DrawButtonLabel(dc
, label
, wxNullBitmap
, rect
, flags
,
1116 alignment
, indexAccel
, rectBounds
);
1119 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
1120 const wxString
& label
,
1121 const wxBitmap
& image
,
1128 if ( flags
& wxCONTROL_DISABLED
)
1130 // make the text grey and draw a shade for it
1131 dc
.SetTextForeground(*wxWHITE
); // FIXME hardcoded colour
1132 wxRect rectShadow
= rect
;
1135 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1136 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT_DISABLED
));
1139 dc
.DrawLabel(label
, image
, rect
, alignment
, indexAccel
, rectBounds
);
1142 void wxGTKRenderer::DrawItem(wxDC
& dc
,
1143 const wxString
& label
,
1147 wxLogTrace(_T("listbox"), _T("drawing item '%s' at (%d, %d)-(%d, %d)"),
1150 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1153 if ( flags
& wxCONTROL_SELECTED
)
1155 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
), wxSOLID
));
1156 dc
.SetPen(*wxTRANSPARENT_PEN
);
1157 dc
.DrawRectangle(rect
);
1159 colFg
= dc
.GetTextForeground();
1160 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
1163 if ( flags
& wxCONTROL_FOCUSED
)
1165 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1166 wxRect rectFocus
= rect
;
1167 DrawRect(dc
, &rectFocus
, m_penBlack
);
1170 wxRect rectText
= rect
;
1173 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
1175 if ( flags
& wxCONTROL_SELECTED
)
1177 dc
.SetBackgroundMode(wxTRANSPARENT
);
1180 // restore the text colour
1183 dc
.SetTextForeground(colFg
);
1187 void wxGTKRenderer::DrawCheckItem(wxDC
& dc
,
1188 const wxString
& label
,
1189 const wxBitmap
& bitmap
,
1193 wxRect rectBitmap
= rect
;
1195 rectBitmap
.width
= GetCheckBitmapSize().x
;
1196 // never draw the focus rect around the check indicators here
1197 DrawCheckButton(dc
, _T(""), bitmap
, rectBitmap
, flags
& ~wxCONTROL_FOCUSED
);
1199 wxRect rectLabel
= rect
;
1200 wxCoord shift
= rectBitmap
.width
+ 2*GetCheckItemMargin();
1201 rectLabel
.x
+= shift
;
1202 rectLabel
.width
-= shift
;
1203 DrawItem(dc
, label
, rectLabel
, flags
);
1206 // ----------------------------------------------------------------------------
1207 // check/radion buttons
1208 // ----------------------------------------------------------------------------
1210 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1211 const wxRect
& rectTotal
,
1214 wxRect rect
= rectTotal
;
1215 DrawAntiRaisedBorder(dc
, &rect
);
1217 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1218 dc
.SetPen(wxPen(col
, 0, wxSOLID
));
1219 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1222 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1223 //else: it is SHADOW_IN, leave as is
1225 dc
.SetPen(*wxTRANSPARENT_PEN
);
1226 dc
.SetBrush(wxBrush(col
, wxSOLID
));
1227 dc
.DrawRectangle(rect
);
1230 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1232 wxRect rect
= rectTotal
;
1233 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1234 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1236 dc
.SetPen(*wxTRANSPARENT_PEN
);
1237 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), wxSOLID
));
1238 dc
.DrawRectangle(rect
);
1241 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1247 xRight
= rect
.GetRight(),
1248 yBottom
= rect
.GetBottom();
1250 wxCoord yMid
= (y
+ yBottom
) / 2;
1252 // this looks ugly when the background colour of the control is not the
1253 // same ours - radiobox is not transparent as it should be
1255 // first fill the middle: as FloodFill() is not implemented on all
1256 // platforms, this is the only thing to do
1257 wxColour colBg
= flags
& wxCONTROL_CURRENT
1258 ? wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
)
1259 : wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1260 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
1261 dc
.SetPen(*wxTRANSPARENT_PEN
);
1262 dc
.DrawRectangle(rect
);
1265 // then draw the upper half
1266 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1267 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1268 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1271 if ( flags
& wxCONTROL_CHECKED
)
1272 dc
.SetPen(m_penBlack
);
1273 else if ( flags
& wxCONTROL_PRESSED
)
1274 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1275 else // unchecked and unpressed
1279 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1281 // and then the lower one
1282 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1283 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1284 if ( !(flags
& wxCONTROL_CHECKED
) )
1285 dc
.SetPen(m_penDarkGrey
);
1286 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1288 if ( !(flags
& wxCONTROL_CHECKED
) )
1289 drawIt
= TRUE
; // with the same pen
1290 else if ( flags
& wxCONTROL_PRESSED
)
1292 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1295 else // checked and unpressed
1299 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1302 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1308 wxCoord xMid
= (x1
+ x2
) / 2;
1309 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1310 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1313 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1319 wxCoord xMid
= (x1
+ x2
) / 2;
1320 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1321 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1324 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1326 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1328 // init the bitmaps once only
1330 wxSize size
= GetCheckBitmapSize();
1331 rect
.width
= size
.x
;
1332 rect
.height
= size
.y
;
1333 for ( int i
= 0; i
< 2; i
++ )
1335 for ( int j
= 0; j
< 2; j
++ )
1336 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1342 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1343 DrawCheckBitmap(dc
, rect
);
1346 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1347 DrawUncheckBitmap(dc
, rect
, FALSE
);
1350 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1352 // pressed unchecked
1353 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1354 DrawUncheckBitmap(dc
, rect
, TRUE
);
1357 int row
= flags
& wxCONTROL_PRESSED
? 1 : 0;
1358 int col
= flags
& wxCONTROL_CHECKED
? 0 : 1;
1360 return m_bitmapsCheckbox
[row
][col
];
1363 wxBitmap
wxGTKRenderer::GetLineWrapBitmap()
1365 if ( !m_bmpLineWrap
.Ok() )
1367 // the line wrap bitmap as used by GTK+
1368 #define line_wrap_width 6
1369 #define line_wrap_height 9
1370 static const char line_wrap_bits
[] =
1372 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1375 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1376 if ( !bmpLineWrap
.Ok() )
1378 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1382 m_bmpLineWrap
= bmpLineWrap
;
1386 return m_bmpLineWrap
;
1389 void wxGTKRenderer::DrawCheckButton(wxDC
& dc
,
1390 const wxString
& label
,
1391 const wxBitmap
& bitmapOrig
,
1392 const wxRect
& rectTotal
,
1398 if ( bitmapOrig
.Ok() )
1400 bitmap
= bitmapOrig
;
1404 bitmap
= GetCheckBitmap(flags
);
1407 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1408 flags
, align
, indexAccel
);
1411 void wxGTKRenderer::DoDrawCheckOrRadioBitmap(wxDC
& dc
,
1412 const wxString
& label
,
1413 const wxBitmap
& bitmap
,
1414 const wxRect
& rectTotal
,
1419 wxRect rect
= rectTotal
;
1421 if ( flags
& wxCONTROL_FOCUSED
)
1423 // draw the focus border around everything
1424 DrawRect(dc
, &rect
, m_penBlack
);
1428 // the border does not offset the string under GTK
1432 // calculate the position of the bitmap and of the label
1434 yBmp
= rect
.y
+ (rect
.height
- bitmap
.GetHeight()) / 2;
1437 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
1438 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
1440 if ( align
== wxALIGN_RIGHT
)
1442 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
1443 rectLabel
.x
= rect
.x
+ 2;
1444 rectLabel
.SetRight(xBmp
);
1446 else // normal (checkbox to the left of the text) case
1449 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 4;
1450 rectLabel
.SetRight(rect
.GetRight());
1453 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
1455 DrawLabel(dc
, label
, rectLabel
, flags
,
1456 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1459 void wxGTKRenderer::DrawRadioButton(wxDC
& dc
,
1460 const wxString
& label
,
1461 const wxBitmap
& bitmapOrig
,
1462 const wxRect
& rectTotal
,
1468 if ( bitmapOrig
.Ok() )
1470 bitmap
= bitmapOrig
;
1475 wxSize size
= GetRadioBitmapSize();
1476 rect
.width
= size
.x
;
1477 rect
.height
= size
.y
;
1478 bitmap
.Create(rect
.width
, rect
.height
);
1480 dc
.SelectObject(bitmap
);
1481 dc
.SetBackground(*wxLIGHT_GREY_BRUSH
);
1483 DrawRadioBitmap(dc
, rect
, flags
);
1484 bitmap
.SetMask(new wxMask(bitmap
, *wxLIGHT_GREY
));
1487 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1488 flags
, align
, indexAccel
);
1491 // ----------------------------------------------------------------------------
1493 // ----------------------------------------------------------------------------
1495 wxRect
wxGTKRenderer::GetTextTotalArea(const wxTextCtrl
*text
,
1498 wxRect rectTotal
= rect
;
1499 rectTotal
.Inflate(2*BORDER_THICKNESS
);
1503 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1505 wxCoord
*extraSpaceBeyond
)
1507 wxRect rectText
= rect
;
1508 rectText
.Inflate(-2*BORDER_THICKNESS
);
1510 if ( text
->WrapLines() )
1512 // leave enough for the line wrap bitmap indicator
1513 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1515 rectText
.width
-= widthMark
;
1517 if ( extraSpaceBeyond
)
1518 *extraSpaceBeyond
= widthMark
;
1524 void wxGTKRenderer::DrawTextLine(wxDC
& dc
,
1525 const wxString
& text
,
1531 // TODO: GTK+ draws selection even for unfocused controls, just with
1532 // different colours
1533 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
1536 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1538 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1540 // for a mono bitmap he colours it appears in depends on the current text
1541 // colours, so set them correctly
1543 if ( bmpLineWrap
.GetDepth() == 1 )
1545 colFgOld
= dc
.GetTextForeground();
1547 // FIXME: I wonder what should we do if the background is black too?
1548 dc
.SetTextForeground(*wxBLACK
);
1551 dc
.DrawBitmap(bmpLineWrap
,
1552 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1554 if ( colFgOld
.Ok() )
1556 // restore old colour
1557 dc
.SetTextForeground(colFgOld
);
1561 // ----------------------------------------------------------------------------
1563 // ----------------------------------------------------------------------------
1565 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1566 const wxRect
& rectOrig
,
1568 const wxString
& label
,
1569 const wxBitmap
& bitmap
,
1573 wxRect rect
= rectOrig
;
1575 // the current tab is drawn indented (to the top for default case) and
1576 // bigger than the other ones
1577 const wxSize indent
= GetTabIndent();
1578 if ( flags
& wxCONTROL_SELECTED
)
1583 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1587 rect
.Inflate(indent
.x
, 0);
1589 rect
.height
+= indent
.y
;
1593 rect
.Inflate(indent
.x
, 0);
1594 rect
.height
+= indent
.y
;
1599 wxFAIL_MSG(_T("TODO"));
1604 // selected tab has different colour
1605 wxColour col
= flags
& wxCONTROL_SELECTED
1606 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1607 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1608 DoDrawBackground(dc
, col
, rect
);
1610 if ( flags
& wxCONTROL_FOCUSED
)
1612 // draw the focus rect
1613 wxRect rectBorder
= rect
;
1614 rectBorder
.Deflate(4, 3);
1615 if ( dir
== wxBOTTOM
)
1616 rectBorder
.Offset(0, -1);
1618 DrawRect(dc
, &rectBorder
, m_penBlack
);
1621 // draw the text, image and the focus around them (if necessary)
1622 wxRect rectLabel
= rect
;
1623 rectLabel
.Deflate(1, 1);
1624 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1626 // now draw the tab itself
1629 x2
= rect
.GetRight(),
1630 y2
= rect
.GetBottom();
1635 dc
.SetPen(m_penHighlight
);
1636 dc
.DrawLine(x
, y2
, x
, y
);
1637 dc
.DrawLine(x
+ 1, y
, x2
, y
);
1639 dc
.SetPen(m_penBlack
);
1640 dc
.DrawLine(x2
, y2
, x2
, y
);
1642 dc
.SetPen(m_penDarkGrey
);
1643 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ 1);
1645 if ( flags
& wxCONTROL_SELECTED
)
1647 dc
.SetPen(m_penLightGrey
);
1649 // overwrite the part of the border below this tab
1650 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
1652 // and the shadow of the tab to the left of us
1653 dc
.DrawLine(x
+ 1, y
+ 2, x
+ 1, y2
+ 1);
1658 dc
.SetPen(m_penHighlight
);
1660 // we need to continue one pixel further to overwrite the corner of
1661 // the border for the selected tab
1662 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
1665 // it doesn't work like this (TODO: implement it properly)
1667 // erase the corner of the tab to the right
1668 dc
.SetPen(m_penLightGrey
);
1669 dc
.DrawPoint(x2
- 1, y
- 2);
1670 dc
.DrawPoint(x2
- 2, y
- 2);
1671 dc
.DrawPoint(x2
- 2, y
- 1);
1674 dc
.SetPen(m_penBlack
);
1675 dc
.DrawLine(x
+ 1, y2
, x2
, y2
);
1676 dc
.DrawLine(x2
, y
, x2
, y2
);
1678 dc
.SetPen(m_penDarkGrey
);
1679 dc
.DrawLine(x
+ 2, y2
- 1, x2
- 1, y2
- 1);
1680 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
);
1682 if ( flags
& wxCONTROL_SELECTED
)
1684 dc
.SetPen(m_penLightGrey
);
1686 // overwrite the part of the (double!) border above this tab
1687 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
1688 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
1690 // and the shadow of the tab to the left of us
1691 dc
.DrawLine(x
+ 1, y2
- 1, x
+ 1, y
- 1);
1697 wxFAIL_MSG(_T("TODO"));
1701 // ----------------------------------------------------------------------------
1703 // ----------------------------------------------------------------------------
1705 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1706 wxOrientation orient
) const
1708 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1712 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
1713 if ( orient
== wxHORIZONTAL
)
1715 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1716 size
.y
= rectShaft
.height
;
1720 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1721 size
.x
= rectShaft
.width
;
1727 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1728 wxOrientation
WXUNUSED(orient
)) const
1730 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
1733 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
1734 const wxRect
& rectOrig
,
1735 wxOrientation orient
,
1739 wxRect rect
= rectOrig
;
1741 // draw the border first
1742 if ( flags
& wxCONTROL_FOCUSED
)
1744 DrawRect(dc
, &rect
, m_penBlack
);
1745 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1747 else // not focused, normal
1749 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1750 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1753 // and the background
1754 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
1760 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
1761 const wxRect
& rectOrig
,
1762 wxOrientation orient
,
1765 // draw the thumb border
1766 wxRect rect
= rectOrig
;
1767 DrawAntiRaisedBorder(dc
, &rect
);
1769 // draw the handle in the middle
1770 if ( orient
== wxVERTICAL
)
1772 rect
.height
= 2*BORDER_THICKNESS
;
1773 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
1777 rect
.width
= 2*BORDER_THICKNESS
;
1778 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
1781 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1785 // ----------------------------------------------------------------------------
1787 // ----------------------------------------------------------------------------
1789 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
1791 const wxString
& label
,
1795 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE
, indexAccel
);
1798 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
1800 const wxMenuGeometryInfo
& geometryInfo
,
1801 const wxString
& label
,
1802 const wxString
& accel
,
1803 const wxBitmap
& bitmap
,
1807 wxFAIL_MSG(_T("TODO"));
1810 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
1812 const wxMenuGeometryInfo
& geomInfo
)
1814 wxFAIL_MSG(_T("TODO"));
1817 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
1822 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
1823 const wxMenu
& menu
) const
1825 wxFAIL_MSG(_T("TODO"));
1829 #endif // wxUSE_MENUS
1831 // ----------------------------------------------------------------------------
1833 // ----------------------------------------------------------------------------
1835 void wxGTKRenderer::InitComboBitmaps()
1837 wxSize sizeArrow
= m_sizeScrollbarArrow
;
1843 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1845 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
1848 static const int comboButtonFlags
[ComboState_Max
] =
1856 wxRect
rect(wxPoint(0, 0), sizeArrow
);
1859 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1861 int flags
= comboButtonFlags
[n
];
1863 dc
.SelectObject(m_bitmapsCombo
[n
]);
1864 DoDrawBackground(dc
, GetBackgroundColour(flags
), rect
);
1865 DrawArrow(dc
, wxDOWN
, rect
, flags
);
1869 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
1871 wxBitmap
*bmpPressed
,
1872 wxBitmap
*bmpDisabled
)
1874 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
1880 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
1882 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
1884 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
1886 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
1889 // ----------------------------------------------------------------------------
1891 // ----------------------------------------------------------------------------
1893 void wxGTKRenderer::DoDrawBackground(wxDC
& dc
,
1894 const wxColour
& col
,
1897 wxBrush
brush(col
, wxSOLID
);
1899 dc
.SetPen(*wxTRANSPARENT_PEN
);
1900 dc
.DrawRectangle(rect
);
1903 void wxGTKRenderer::DrawBackground(wxDC
& dc
,
1904 const wxColour
& col
,
1908 wxColour colBg
= col
.Ok() ? col
: GetBackgroundColour(flags
);
1909 DoDrawBackground(dc
, colBg
, rect
);
1912 // ----------------------------------------------------------------------------
1914 // ----------------------------------------------------------------------------
1916 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
1920 static const wxDirection sides
[] =
1922 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
1925 wxRect rect1
, rect2
, rectInner
;
1931 rectInner
.Inflate(-2);
1933 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
1935 // find the side not to draw and also adjust the rectangles to compensate
1937 wxDirection sideToOmit
;
1941 sideToOmit
= wxDOWN
;
1943 rectInner
.height
+= 1;
1951 rectInner
.height
+= 1;
1955 sideToOmit
= wxRIGHT
;
1957 rectInner
.width
+= 1;
1961 sideToOmit
= wxLEFT
;
1965 rectInner
.width
+= 1;
1969 wxFAIL_MSG(_T("unknown arrow direction"));
1973 // the outer rect first
1975 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
1977 wxDirection side
= sides
[n
];
1978 if ( side
== sideToOmit
)
1981 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
1984 // and then the inner one
1985 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
1987 wxDirection side
= sides
[n
];
1988 if ( side
== sideToOmit
)
1991 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
1997 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
1999 const wxRect
& rectArrow
,
2002 // first of all, draw the border around it - but we don't want the border
2003 // on the side opposite to the arrow point
2004 wxRect rect
= rectArrow
;
2005 DrawArrowBorder(dc
, &rect
, dir
);
2007 // then the arrow itself
2008 DrawArrow(dc
, dir
, rect
, flags
);
2011 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
2012 // these people are just crazy :-(
2013 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2026 wxPoint ptArrow
[Point_Max
];
2028 wxColour colInside
= GetBackgroundColour(flags
);
2030 if ( flags
& wxCONTROL_DISABLED
)
2032 penShadow
[0] = m_penDarkGrey
;
2033 penShadow
[1] = m_penDarkGrey
;
2034 penShadow
[2] = wxNullPen
;
2035 penShadow
[3] = wxNullPen
;
2037 else if ( flags
& wxCONTROL_PRESSED
)
2039 penShadow
[0] = m_penDarkGrey
;
2040 penShadow
[1] = m_penHighlight
;
2041 penShadow
[2] = wxNullPen
;
2042 penShadow
[3] = m_penBlack
;
2044 else // normal arrow
2046 penShadow
[0] = m_penHighlight
;
2047 penShadow
[1] = m_penBlack
;
2048 penShadow
[2] = m_penDarkGrey
;
2049 penShadow
[3] = wxNullPen
;
2053 if ( dir
== wxUP
|| dir
== wxDOWN
)
2056 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2060 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2063 // draw the arrow interior
2064 dc
.SetPen(*wxTRANSPARENT_PEN
);
2065 dc
.SetBrush(wxBrush(colInside
, wxSOLID
));
2070 ptArrow
[Point_First
].x
= rect
.GetLeft();
2071 ptArrow
[Point_First
].y
= rect
.GetBottom();
2072 ptArrow
[Point_Second
].x
= middle
;
2073 ptArrow
[Point_Second
].y
= rect
.GetTop();
2074 ptArrow
[Point_Third
].x
= rect
.GetRight();
2075 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2079 ptArrow
[Point_First
] = rect
.GetPosition();
2080 ptArrow
[Point_Second
].x
= middle
;
2081 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2082 ptArrow
[Point_Third
].x
= rect
.GetRight();
2083 ptArrow
[Point_Third
].y
= rect
.GetTop();
2087 ptArrow
[Point_First
].x
= rect
.GetRight();
2088 ptArrow
[Point_First
].y
= rect
.GetTop();
2089 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2090 ptArrow
[Point_Second
].y
= middle
;
2091 ptArrow
[Point_Third
].x
= rect
.GetRight();
2092 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2096 ptArrow
[Point_First
] = rect
.GetPosition();
2097 ptArrow
[Point_Second
].x
= rect
.GetRight();
2098 ptArrow
[Point_Second
].y
= middle
;
2099 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2100 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2104 wxFAIL_MSG(_T("unknown arrow direction"));
2107 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2109 // draw the arrow border
2110 dc
.SetPen(penShadow
[0]);
2114 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2115 dc
.DrawPoint(ptArrow
[Point_First
]);
2116 if ( penShadow
[3].Ok() )
2118 dc
.SetPen(penShadow
[3]);
2119 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2120 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2122 dc
.SetPen(penShadow
[1]);
2123 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2124 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2125 dc
.DrawPoint(ptArrow
[Point_Third
]);
2126 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2127 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2128 if ( penShadow
[2].Ok() )
2130 dc
.SetPen(penShadow
[2]);
2131 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2132 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2133 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2134 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2139 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2140 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2141 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2142 if ( penShadow
[2].Ok() )
2144 dc
.SetPen(penShadow
[2]);
2145 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2146 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2148 dc
.SetPen(penShadow
[1]);
2149 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2150 dc
.DrawPoint(ptArrow
[Point_Third
]);
2154 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2155 dc
.DrawPoint(ptArrow
[Point_First
]);
2156 if ( penShadow
[2].Ok() )
2158 dc
.SetPen(penShadow
[2]);
2159 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2160 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2161 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2162 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2164 dc
.SetPen(penShadow
[1]);
2165 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2166 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2167 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2168 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2172 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2173 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2174 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2175 dc
.SetPen(penShadow
[1]);
2176 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2177 dc
.DrawPoint(ptArrow
[Point_Third
]);
2181 wxFAIL_MSG(_T("unknown arrow direction"));
2186 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2188 wxOrientation orient
)
2190 if ( orient
== wxVERTICAL
)
2192 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2194 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2196 rect
->Inflate(-1, 0);
2198 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2200 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2202 rect
->Inflate(-1, 0);
2206 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2208 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2210 rect
->Inflate(0, -1);
2212 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2214 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2216 rect
->Inflate(0, -1);
2220 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2221 wxOrientation orient
,
2225 // the thumb is never pressed never has focus border under GTK and the
2226 // scrollbar background never changes at all
2227 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2229 // we don't want the border in the direction of the scrollbar movement
2230 wxRect rectThumb
= rect
;
2231 DrawThumbBorder(dc
, &rectThumb
, orient
);
2233 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2234 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2237 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2238 wxOrientation orient
,
2242 wxRect rectBar
= rect
;
2243 DrawThumbBorder(dc
, &rectBar
, orient
);
2244 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2247 void wxGTKRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2249 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2252 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2253 wxScrollBar::Element elem
,
2256 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2257 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2259 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2261 elem
= wxScrollBar::Element_Bar_2
;
2264 return StandardGetScrollbarRect(scrollbar
, elem
,
2266 GetScrollbarArrowSize(scrollbar
));
2269 wxCoord
wxGTKRenderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
2271 return StandardScrollBarSize(scrollbar
, GetScrollbarArrowSize(scrollbar
));
2274 wxHitTest
wxGTKRenderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
2275 const wxPoint
& pt
) const
2277 return StandardHitTestScrollbar(scrollbar
, pt
,
2278 GetScrollbarArrowSize(scrollbar
));
2281 wxCoord
wxGTKRenderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
2284 return StandardScrollbarToPixel(scrollbar
, thumbPos
,
2285 GetScrollbarArrowSize(scrollbar
));
2288 int wxGTKRenderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
2291 return StandardPixelToScrollbar(scrollbar
, coord
,
2292 GetScrollbarArrowSize(scrollbar
));
2295 // ----------------------------------------------------------------------------
2297 // ----------------------------------------------------------------------------
2299 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2302 if ( wxDynamicCast(window
, wxBitmapButton
) )
2307 #endif // wxUSE_BMPBUTTON
2309 if ( wxDynamicCast(window
, wxButton
) )
2311 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2313 // TODO: this is ad hoc...
2314 size
->x
+= 3*window
->GetCharWidth();
2315 wxCoord minBtnHeight
= 18;
2316 if ( size
->y
< minBtnHeight
)
2317 size
->y
= minBtnHeight
;
2319 // button border width
2324 if ( wxDynamicCast(window
, wxScrollBar
) )
2326 // we only set the width of vert scrollbars and height of the
2328 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2329 size
->y
= m_sizeScrollbarArrow
.x
;
2331 size
->x
= m_sizeScrollbarArrow
.x
;
2335 // take into account the border width
2336 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
2337 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
2338 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
2342 // ============================================================================
2344 // ============================================================================
2346 // ----------------------------------------------------------------------------
2347 // wxGTKInputHandler
2348 // ----------------------------------------------------------------------------
2350 wxGTKInputHandler::wxGTKInputHandler(wxGTKRenderer
*renderer
)
2352 m_renderer
= renderer
;
2355 bool wxGTKInputHandler::HandleKey(wxControl
*control
,
2356 const wxKeyEvent
& event
,
2362 bool wxGTKInputHandler::HandleMouse(wxControl
*control
,
2363 const wxMouseEvent
& event
)
2365 // clicking on the control gives it focus
2366 if ( event
.ButtonDown() )
2368 control
->SetFocus();
2376 bool wxGTKInputHandler::HandleMouseMove(wxControl
*control
,
2377 const wxMouseEvent
& event
)
2379 if ( event
.Entering() )
2381 control
->SetCurrent(TRUE
);
2383 else if ( event
.Leaving() )
2385 control
->SetCurrent(FALSE
);
2395 // ----------------------------------------------------------------------------
2396 // wxGTKCheckboxInputHandler
2397 // ----------------------------------------------------------------------------
2399 bool wxGTKCheckboxInputHandler::HandleKey(wxControl
*control
,
2400 const wxKeyEvent
& event
,
2405 int keycode
= event
.GetKeyCode();
2406 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
2408 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
2417 // ----------------------------------------------------------------------------
2418 // wxGTKTextCtrlInputHandler
2419 // ----------------------------------------------------------------------------
2421 bool wxGTKTextCtrlInputHandler::HandleKey(wxControl
*control
,
2422 const wxKeyEvent
& event
,
2425 // handle only GTK-specific text bindings here, the others are handled in
2429 wxControlAction action
;
2430 int keycode
= event
.GetKeyCode();
2431 if ( event
.ControlDown() )
2436 action
= wxACTION_TEXT_HOME
;
2440 action
= wxACTION_TEXT_LEFT
;
2444 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
2448 action
= wxACTION_TEXT_END
;
2452 action
= wxACTION_TEXT_RIGHT
;
2456 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
2460 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2464 action
= wxACTION_TEXT_DOWN
;
2468 action
= wxACTION_TEXT_UP
;
2472 //delete the entire line
2473 control
->PerformAction(wxACTION_TEXT_HOME
);
2474 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2478 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
2482 else if ( event
.AltDown() )
2487 action
= wxACTION_TEXT_WORD_LEFT
;
2491 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
2495 action
= wxACTION_TEXT_WORD_RIGHT
;
2500 if ( action
!= wxACTION_NONE
)
2502 control
->PerformAction(action
);
2508 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);