1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: univ/themes/gtk.cpp
3 // Purpose: wxUniversal theme implementing GTK-like LNF
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
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/scrolbar.h"
38 #include "wx/slider.h"
39 #include "wx/textctrl.h"
42 #include "wx/notebook.h"
43 #include "wx/spinbutt.h"
45 #include "wx/univ/renderer.h"
46 #include "wx/univ/inphand.h"
47 #include "wx/univ/colschem.h"
48 #include "wx/univ/theme.h"
50 // ----------------------------------------------------------------------------
51 // constants (to be removed, for testing only)
52 // ----------------------------------------------------------------------------
54 static const size_t BORDER_THICKNESS
= 1;
56 // ----------------------------------------------------------------------------
57 // wxGTKRenderer: draw the GUI elements in GTK style
58 // ----------------------------------------------------------------------------
60 class wxGTKRenderer
: public wxRenderer
63 wxGTKRenderer(const wxColourScheme
*scheme
);
65 // implement the base class pure virtuals
66 virtual void DrawBackground(wxDC
& dc
,
70 virtual void DrawLabel(wxDC
& dc
,
71 const wxString
& label
,
74 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
76 wxRect
*rectBounds
= NULL
);
77 virtual void DrawButtonLabel(wxDC
& dc
,
78 const wxString
& label
,
79 const wxBitmap
& image
,
82 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
84 wxRect
*rectBounds
= NULL
);
85 virtual void DrawBorder(wxDC
& dc
,
89 wxRect
*rectIn
= (wxRect
*)NULL
);
90 virtual void DrawHorizontalLine(wxDC
& dc
,
91 wxCoord y
, wxCoord x1
, wxCoord x2
);
92 virtual void DrawVerticalLine(wxDC
& dc
,
93 wxCoord x
, wxCoord y1
, wxCoord y2
);
94 virtual void DrawFrame(wxDC
& dc
,
95 const wxString
& label
,
98 int alignment
= wxALIGN_LEFT
,
100 virtual void DrawTextBorder(wxDC
& dc
,
104 wxRect
*rectIn
= (wxRect
*)NULL
);
105 virtual void DrawButtonBorder(wxDC
& dc
,
108 wxRect
*rectIn
= (wxRect
*)NULL
);
109 virtual void DrawArrow(wxDC
& dc
,
113 virtual void DrawScrollbarArrow(wxDC
& dc
,
117 virtual void DrawScrollbarThumb(wxDC
& dc
,
118 wxOrientation orient
,
121 virtual void DrawScrollbarShaft(wxDC
& dc
,
122 wxOrientation orient
,
125 virtual void DrawScrollCorner(wxDC
& dc
,
127 virtual void DrawItem(wxDC
& dc
,
128 const wxString
& label
,
131 virtual void DrawCheckItem(wxDC
& dc
,
132 const wxString
& label
,
133 const wxBitmap
& bitmap
,
136 virtual void DrawCheckButton(wxDC
& dc
,
137 const wxString
& label
,
138 const wxBitmap
& bitmap
,
141 wxAlignment align
= wxALIGN_LEFT
,
142 int indexAccel
= -1);
144 virtual void DrawRadioButton(wxDC
& dc
,
145 const wxString
& label
,
146 const wxBitmap
& bitmap
,
149 wxAlignment align
= wxALIGN_LEFT
,
150 int indexAccel
= -1);
152 virtual void DrawTextLine(wxDC
& dc
,
153 const wxString
& text
,
158 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
159 virtual void DrawTab(wxDC
& dc
,
162 const wxString
& label
,
163 const wxBitmap
& bitmap
= wxNullBitmap
,
165 int indexAccel
= -1);
167 virtual void DrawSliderShaft(wxDC
& dc
,
169 wxOrientation orient
,
171 wxRect
*rectShaft
= NULL
);
172 virtual void DrawSliderThumb(wxDC
& dc
,
174 wxOrientation orient
,
176 virtual void DrawSliderTicks(wxDC
& dc
,
178 const wxSize
& sizeThumb
,
179 wxOrientation orient
,
185 // we don't have the ticks in GTK version
188 virtual void DrawMenuBarItem(wxDC
& dc
,
190 const wxString
& label
,
192 int indexAccel
= -1);
193 virtual void DrawMenuItem(wxDC
& dc
,
195 const wxMenuGeometryInfo
& geometryInfo
,
196 const wxString
& label
,
197 const wxString
& accel
,
198 const wxBitmap
& bitmap
= wxNullBitmap
,
200 int indexAccel
= -1);
201 virtual void DrawMenuSeparator(wxDC
& dc
,
203 const wxMenuGeometryInfo
& geomInfo
);
205 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
206 wxBitmap
*bmpPressed
,
207 wxBitmap
*bmpDisabled
);
209 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
210 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
211 virtual bool AreScrollbarsInsideBorder() const;
213 // geometry and hit testing
214 virtual wxSize
GetScrollbarArrowSize() const
215 { return m_sizeScrollbarArrow
; }
216 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
217 wxScrollBar::Element elem
,
218 int thumbPos
= -1) const;
219 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
220 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
221 const wxPoint
& pt
) const;
222 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
224 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
225 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
226 { return fontHeight
+ 2; }
227 virtual wxSize
GetCheckBitmapSize() const
228 { return wxSize(10, 10); }
229 virtual wxSize
GetRadioBitmapSize() const
230 { return wxSize(11, 11); }
231 virtual wxCoord
GetCheckItemMargin() const
234 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
236 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
238 wxCoord
*extraSpaceBeyond
);
240 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
241 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
243 virtual wxCoord
GetSliderDim() const { return 15; }
244 virtual wxCoord
GetSliderTickLen() const { return 0; }
245 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
246 wxOrientation orient
) const;
247 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
248 wxOrientation orient
) const;
249 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
251 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
252 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
253 const wxMenu
& menu
) const;
255 // helpers for "wxBitmap wxColourScheme::Get()"
256 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
257 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
260 // DrawBackground() helpers
262 // get the colour to use for background
263 wxColour
GetBackgroundColour(int flags
) const
265 if ( flags
& wxCONTROL_PRESSED
)
266 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
267 else if ( flags
& wxCONTROL_CURRENT
)
268 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
270 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
273 // draw the background with any colour, not only the default one(s)
274 void DoDrawBackground(wxDC
& dc
,
278 // DrawBorder() helpers: all of them shift and clip the DC after drawing
281 // just draw a rectangle with the given pen
282 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
284 // draw the lower left part of rectangle
285 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
287 // draw the rectange using the first brush for the left and top sides and
288 // the second one for the bottom and right ones
289 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
290 const wxPen
& pen1
, const wxPen
& pen2
);
292 // as DrawShadedRect() but the pixels in the bottom left and upper right
293 // border are drawn with the pen1, not pen2
294 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
295 const wxPen
& pen1
, const wxPen
& pen2
);
297 // used for drawing opened rectangles - draws only one side of it at once
298 // (and doesn't adjust the rect)
299 void DrawAntiShadedRectSide(wxDC
& dc
,
305 // draw an opened rect for the arrow in given direction
306 void DrawArrowBorder(wxDC
& dc
,
310 // draw two sides of the rectangle
311 void DrawThumbBorder(wxDC
& dc
,
313 wxOrientation orient
);
315 // draw the normal 3D border
316 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
318 // just as DrawRaisedBorder() except that the bottom left and up right
319 // pixels of the interior rect are drawn in another colour (i.e. the inner
320 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
321 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
323 // returns the size of the arrow for the scrollbar (depends on
325 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
328 if ( scrollbar
->IsVertical() )
330 size
= m_sizeScrollbarArrow
;
334 size
.x
= m_sizeScrollbarArrow
.y
;
335 size
.y
= m_sizeScrollbarArrow
.x
;
341 // get the line wrap indicator bitmap
342 wxBitmap
GetLineWrapBitmap();
344 // DrawCheckBitmap and DrawRadioBitmap helpers
346 // draw the check bitmaps once and cache them for later use
347 wxBitmap
GetCheckBitmap(int flags
);
349 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
351 void DrawUpZag(wxDC
& dc
,
352 wxCoord x1
, wxCoord x2
,
353 wxCoord y1
, wxCoord y2
);
354 void DrawDownZag(wxDC
& dc
,
355 wxCoord x1
, wxCoord x2
,
356 wxCoord y1
, wxCoord y2
);
358 // draw the radio button bitmap for the given state
359 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
361 // draw check/radio - the bitmap must be a valid one by now
362 void DoDrawCheckOrRadioBitmap(wxDC
& dc
,
363 const wxString
& label
,
364 const wxBitmap
& bitmap
,
365 const wxRect
& rectTotal
,
371 const wxColourScheme
*m_scheme
;
374 wxSize m_sizeScrollbarArrow
;
383 // the checkbox bitmaps: first row is for the normal, second for the
384 // pressed state and the columns are for checked and unchecked status
386 wxBitmap m_bitmapsCheckbox
[2][2];
388 // the line wrap bitmap (drawn at the end of wrapped lines)
389 wxBitmap m_bmpLineWrap
;
392 // ----------------------------------------------------------------------------
393 // wxGTKInputHandler and derived classes: process the keyboard and mouse
394 // messages according to GTK standards
395 // ----------------------------------------------------------------------------
397 class wxGTKInputHandler
: public wxInputHandler
400 wxGTKInputHandler(wxGTKRenderer
*renderer
);
402 virtual bool HandleKey(wxControl
*control
,
403 const wxKeyEvent
& event
,
405 virtual bool HandleMouse(wxControl
*control
,
406 const wxMouseEvent
& event
);
407 virtual bool HandleMouseMove(wxControl
*control
, const wxMouseEvent
& event
);
410 wxGTKRenderer
*m_renderer
;
413 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
416 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
417 : wxStdScrollBarInputHandler(renderer
, handler
) { }
420 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
422 // only arrows and the thumb can be highlighted
423 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
426 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
429 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
431 // only arrows can be pressed
435 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
438 virtual bool IsAllowedButton(int WXUNUSED(button
)) { return TRUE
; }
442 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
443 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
447 class wxGTKCheckboxInputHandler
: public wxStdCheckboxInputHandler
450 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
451 : wxStdCheckboxInputHandler(handler
) { }
453 virtual bool HandleKey(wxControl
*control
,
454 const wxKeyEvent
& event
,
458 class wxGTKTextCtrlInputHandler
: public wxStdTextCtrlInputHandler
461 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
462 : wxStdTextCtrlInputHandler(handler
) { }
464 virtual bool HandleKey(wxControl
*control
,
465 const wxKeyEvent
& event
,
469 // ----------------------------------------------------------------------------
470 // wxGTKColourScheme: uses the standard GTK colours
471 // ----------------------------------------------------------------------------
473 class wxGTKColourScheme
: public wxColourScheme
476 virtual wxColour
Get(StdColour col
) const;
477 virtual wxColour
GetBackground(wxWindow
*win
) const;
480 // ----------------------------------------------------------------------------
482 // ----------------------------------------------------------------------------
484 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
486 class wxGTKTheme
: public wxTheme
490 virtual ~wxGTKTheme();
492 virtual wxRenderer
*GetRenderer() { return m_renderer
; }
493 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
494 virtual wxColourScheme
*GetColourScheme() { return m_scheme
; }
497 // get the default input handler
498 wxInputHandler
*GetDefaultInputHandler();
500 wxGTKRenderer
*m_renderer
;
502 // the names of the already created handlers and the handlers themselves
503 // (these arrays are synchronized)
504 wxSortedArrayString m_handlerNames
;
505 wxArrayHandlers m_handlers
;
507 wxGTKInputHandler
*m_handlerDefault
;
509 wxGTKColourScheme
*m_scheme
;
511 WX_DECLARE_THEME(gtk
)
514 // ============================================================================
516 // ============================================================================
518 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
520 // ----------------------------------------------------------------------------
522 // ----------------------------------------------------------------------------
524 wxGTKTheme::wxGTKTheme()
526 m_scheme
= new wxGTKColourScheme
;
527 m_renderer
= new wxGTKRenderer(m_scheme
);
528 m_handlerDefault
= NULL
;
531 wxGTKTheme::~wxGTKTheme()
533 size_t count
= m_handlers
.GetCount();
534 for ( size_t n
= 0; n
< count
; n
++ )
536 if ( m_handlers
[n
] != m_handlerDefault
)
537 delete m_handlers
[n
];
540 delete m_handlerDefault
;
545 wxInputHandler
*wxGTKTheme::GetDefaultInputHandler()
547 if ( !m_handlerDefault
)
549 m_handlerDefault
= new wxGTKInputHandler(m_renderer
);
552 return m_handlerDefault
;
555 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
)
557 wxInputHandler
*handler
;
558 int n
= m_handlerNames
.Index(control
);
559 if ( n
== wxNOT_FOUND
)
561 // create a new handler
562 if ( control
== wxINP_HANDLER_SCROLLBAR
)
563 handler
= new wxGTKScrollBarInputHandler(m_renderer
,
564 GetDefaultInputHandler());
566 else if ( control
== wxINP_HANDLER_BUTTON
)
567 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
568 #endif // wxUSE_CHECKBOX
570 else if ( control
== wxINP_HANDLER_CHECKBOX
)
571 handler
= new wxGTKCheckboxInputHandler(GetDefaultInputHandler());
572 #endif // wxUSE_CHECKBOX
574 else if ( control
== wxINP_HANDLER_COMBOBOX
)
575 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
576 #endif // wxUSE_COMBOBOX
578 else if ( control
== wxINP_HANDLER_LISTBOX
)
579 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
580 #endif // wxUSE_LISTBOX
581 #if wxUSE_CHECKLISTBOX
582 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
583 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
584 #endif // wxUSE_CHECKLISTBOX
586 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
587 handler
= new wxGTKTextCtrlInputHandler(GetDefaultInputHandler());
588 #endif // wxUSE_TEXTCTRL
590 else if ( control
== wxINP_HANDLER_SLIDER
)
591 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
592 #endif // wxUSE_SLIDER
594 else if ( control
== wxINP_HANDLER_SPINBTN
)
595 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
596 #endif // wxUSE_SPINBTN
598 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
599 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
600 #endif // wxUSE_NOTEBOOK
602 handler
= GetDefaultInputHandler();
604 n
= m_handlerNames
.Add(control
);
605 m_handlers
.Insert(handler
, n
);
607 else // we already have it
609 handler
= m_handlers
[n
];
615 // ============================================================================
617 // ============================================================================
619 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
622 if ( win
->UseBgCol() )
624 // use the user specified colour
625 col
= win
->GetBackgroundColour();
628 if ( win
->IsContainerWindow() )
630 // doesn't depend on the state
638 int flags
= win
->GetStateFlags();
640 // the colour set by the user should be used for the normal state
641 // and for the states for which we don't have any specific colours
642 if ( !col
.Ok() || (flags
!= 0) )
644 if ( wxDynamicCast(win
, wxScrollBar
) )
645 col
= Get(SCROLLBAR
);
646 else if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
647 col
= Get(CONTROL_CURRENT
);
648 else if ( flags
& wxCONTROL_PRESSED
)
649 col
= Get(CONTROL_PRESSED
);
658 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
662 case WINDOW
: return *wxWHITE
;
664 case SHADOW_DARK
: return *wxBLACK
;
665 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
666 case SHADOW_IN
: return wxColour(0xd6d6d6);
667 case SHADOW_OUT
: return wxColour(0x969696);
669 case CONTROL
: return wxColour(0xd6d6d6);
670 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
671 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
673 case CONTROL_TEXT
: return *wxBLACK
;
674 case CONTROL_TEXT_DISABLED
:
675 return wxColour(0x757575);
676 case CONTROL_TEXT_DISABLED_SHADOW
:
680 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
682 case HIGHLIGHT
: return wxColour(0x9c0000);
683 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
687 wxFAIL_MSG(_T("invalid standard colour"));
692 // ============================================================================
694 // ============================================================================
696 // ----------------------------------------------------------------------------
698 // ----------------------------------------------------------------------------
700 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
704 m_sizeScrollbarArrow
= wxSize(15, 14);
707 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
708 m_penDarkGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_OUT
), 0, wxSOLID
);
709 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
), 0, wxSOLID
);
710 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
711 m_penHighlight
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
), 0, wxSOLID
);
714 // ----------------------------------------------------------------------------
716 // ----------------------------------------------------------------------------
718 void wxGTKRenderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
722 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
723 dc
.DrawRectangle(*rect
);
729 void wxGTKRenderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
731 // draw the bottom and right sides
733 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
734 rect
->GetRight() + 1, rect
->GetBottom());
735 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
736 rect
->GetRight(), rect
->GetBottom());
743 void wxGTKRenderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
744 const wxPen
& pen1
, const wxPen
& pen2
)
746 // draw the rectangle
748 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
749 rect
->GetLeft(), rect
->GetBottom());
750 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
751 rect
->GetRight(), rect
->GetTop());
753 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
754 rect
->GetRight(), rect
->GetBottom());
755 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
756 rect
->GetRight() + 1, rect
->GetBottom());
762 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
768 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
773 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
774 rect
.GetLeft(), rect
.GetBottom() + 1);
778 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
779 rect
.GetRight() + 1, rect
.GetTop());
783 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
784 rect
.GetRight(), rect
.GetBottom() + 1);
788 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
789 rect
.GetRight() + 1, rect
.GetBottom());
793 wxFAIL_MSG(_T("unknown rectangle side"));
797 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
798 const wxPen
& pen1
, const wxPen
& pen2
)
800 // draw the rectangle
802 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
803 rect
->GetLeft(), rect
->GetBottom() + 1);
804 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
805 rect
->GetRight() + 1, rect
->GetTop());
807 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
808 rect
->GetRight(), rect
->GetBottom());
809 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
810 rect
->GetRight() + 1, rect
->GetBottom());
816 void wxGTKRenderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
818 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
819 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
822 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
824 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
825 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
828 void wxGTKRenderer::DrawBorder(wxDC
& dc
,
830 const wxRect
& rectTotal
,
836 wxRect rect
= rectTotal
;
840 case wxBORDER_SUNKEN
:
841 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
843 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
844 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
848 case wxBORDER_STATIC
:
849 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
852 case wxBORDER_RAISED
:
853 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
855 DrawRaisedBorder(dc
, &rect
);
859 case wxBORDER_DOUBLE
:
860 DrawShadedRect(dc
, &rect
, m_penLightGrey
, m_penBlack
);
861 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penDarkGrey
);
862 DrawRect(dc
, &rect
, m_penLightGrey
);
865 case wxBORDER_SIMPLE
:
866 DrawRect(dc
, &rect
, m_penBlack
);
870 wxFAIL_MSG(_T("unknown border type"));
873 case wxBORDER_DEFAULT
:
882 wxRect
wxGTKRenderer::GetBorderDimensions(wxBorder border
) const
887 case wxBORDER_RAISED
:
888 case wxBORDER_SUNKEN
:
889 width
= 2*BORDER_THICKNESS
;
892 case wxBORDER_SIMPLE
:
893 case wxBORDER_STATIC
:
897 case wxBORDER_DOUBLE
:
902 wxFAIL_MSG(_T("unknown border type"));
905 case wxBORDER_DEFAULT
:
920 bool wxGTKRenderer::AreScrollbarsInsideBorder() const
922 // no, the scrollbars are outside the border in GTK+
926 // ----------------------------------------------------------------------------
928 // ----------------------------------------------------------------------------
930 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
932 const wxRect
& rectOrig
,
936 wxRect rect
= rectOrig
;
938 if ( flags
& wxCONTROL_FOCUSED
)
940 DrawRect(dc
, &rect
, m_penBlack
);
941 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
945 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
946 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penHighlight
);
953 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
954 const wxRect
& rectTotal
,
958 wxRect rect
= rectTotal
;
960 if ( flags
& wxCONTROL_PRESSED
)
962 // button pressed: draw a black border around it and an inward shade
963 DrawRect(dc
, &rect
, m_penBlack
);
964 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
965 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penDarkGrey
);
969 // button not pressed
971 if ( flags
& wxCONTROL_ISDEFAULT
)
976 if ( flags
& wxCONTROL_FOCUSED
)
978 // button is currently default: add an extra border around it
979 DrawRect(dc
, &rect
, m_penBlack
);
982 // now draw a normal button
983 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
984 DrawAntiShadedRect(dc
, &rect
,
985 wxPen(GetBackgroundColour(flags
), 0, wxSOLID
),
995 // ----------------------------------------------------------------------------
997 // ----------------------------------------------------------------------------
999 void wxGTKRenderer::DrawHorizontalLine(wxDC
& dc
,
1000 wxCoord y
, wxCoord x1
, wxCoord x2
)
1002 dc
.SetPen(m_penDarkGrey
);
1003 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1004 dc
.SetPen(m_penHighlight
);
1006 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1009 void wxGTKRenderer::DrawVerticalLine(wxDC
& dc
,
1010 wxCoord x
, wxCoord y1
, wxCoord y2
)
1012 dc
.SetPen(m_penDarkGrey
);
1013 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1014 dc
.SetPen(m_penHighlight
);
1016 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1019 void wxGTKRenderer::DrawFrame(wxDC
& dc
,
1020 const wxString
& label
,
1026 wxCoord height
= 0; // of the label
1027 wxRect rectFrame
= rect
;
1028 if ( !label
.empty() )
1030 // the text should touch the top border of the rect, so the frame
1031 // itself should be lower
1032 dc
.GetTextExtent(label
, NULL
, &height
);
1033 rectFrame
.y
+= height
/ 2;
1034 rectFrame
.height
-= height
/ 2;
1036 // TODO: the +4 should be customizable
1039 rectText
.x
= rectFrame
.x
+ 4;
1040 rectText
.y
= rect
.y
;
1041 rectText
.width
= rectFrame
.width
- 8;
1042 rectText
.height
= height
;
1045 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1047 rectLabel
.width
+= 2;
1049 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1051 // GTK+ does it like this
1052 dc
.SetPen(m_penHighlight
);
1053 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
1054 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
1058 // just draw the complete frame
1059 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1060 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1064 // ----------------------------------------------------------------------------
1066 // ----------------------------------------------------------------------------
1068 void wxGTKRenderer::DrawLabel(wxDC
& dc
,
1069 const wxString
& label
,
1076 DrawButtonLabel(dc
, label
, wxNullBitmap
, rect
, flags
,
1077 alignment
, indexAccel
, rectBounds
);
1080 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
1081 const wxString
& label
,
1082 const wxBitmap
& image
,
1089 if ( flags
& wxCONTROL_DISABLED
)
1091 // make the text grey and draw a shade for it
1092 dc
.SetTextForeground(*wxWHITE
); // FIXME hardcoded colour
1093 wxRect rectShadow
= rect
;
1096 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1097 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT_DISABLED
));
1100 dc
.DrawLabel(label
, image
, rect
, alignment
, indexAccel
, rectBounds
);
1103 void wxGTKRenderer::DrawItem(wxDC
& dc
,
1104 const wxString
& label
,
1108 wxLogTrace(_T("listbox"), _T("drawing item '%s' at (%d, %d)-(%d, %d)"),
1111 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1114 if ( flags
& wxCONTROL_SELECTED
)
1116 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
), wxSOLID
));
1117 dc
.SetPen(*wxTRANSPARENT_PEN
);
1118 dc
.DrawRectangle(rect
);
1120 colFg
= dc
.GetTextForeground();
1121 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
1124 if ( flags
& wxCONTROL_FOCUSED
)
1126 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1127 wxRect rectFocus
= rect
;
1128 DrawRect(dc
, &rectFocus
, m_penBlack
);
1131 wxRect rectText
= rect
;
1134 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
1136 if ( flags
& wxCONTROL_SELECTED
)
1138 dc
.SetBackgroundMode(wxTRANSPARENT
);
1141 // restore the text colour
1144 dc
.SetTextForeground(colFg
);
1148 void wxGTKRenderer::DrawCheckItem(wxDC
& dc
,
1149 const wxString
& label
,
1150 const wxBitmap
& bitmap
,
1154 wxRect rectBitmap
= rect
;
1156 rectBitmap
.width
= GetCheckBitmapSize().x
;
1157 // never draw the focus rect around the check indicators here
1158 DrawCheckButton(dc
, _T(""), bitmap
, rectBitmap
, flags
& ~wxCONTROL_FOCUSED
);
1160 wxRect rectLabel
= rect
;
1161 wxCoord shift
= rectBitmap
.width
+ 2*GetCheckItemMargin();
1162 rectLabel
.x
+= shift
;
1163 rectLabel
.width
-= shift
;
1164 DrawItem(dc
, label
, rectLabel
, flags
);
1167 // ----------------------------------------------------------------------------
1168 // check/radion buttons
1169 // ----------------------------------------------------------------------------
1171 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1172 const wxRect
& rectTotal
,
1175 wxRect rect
= rectTotal
;
1176 DrawAntiRaisedBorder(dc
, &rect
);
1178 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1179 dc
.SetPen(wxPen(col
, 0, wxSOLID
));
1180 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1183 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1184 //else: it is SHADOW_IN, leave as is
1186 dc
.SetPen(*wxTRANSPARENT_PEN
);
1187 dc
.SetBrush(wxBrush(col
, wxSOLID
));
1188 dc
.DrawRectangle(rect
);
1191 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1193 wxRect rect
= rectTotal
;
1194 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1195 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1197 dc
.SetPen(*wxTRANSPARENT_PEN
);
1198 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), wxSOLID
));
1199 dc
.DrawRectangle(rect
);
1202 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1208 xRight
= rect
.GetRight(),
1209 yBottom
= rect
.GetBottom();
1211 wxCoord yMid
= (y
+ yBottom
) / 2;
1213 // this looks ugly when the background colour of the control is not the
1214 // same ours - radiobox is not transparent as it should be
1216 // first fill the middle: as FloodFill() is not implemented on all
1217 // platforms, this is the only thing to do
1218 wxColour colBg
= flags
& wxCONTROL_CURRENT
1219 ? wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
)
1220 : wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1221 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
1222 dc
.SetPen(*wxTRANSPARENT_PEN
);
1223 dc
.DrawRectangle(rect
);
1226 // then draw the upper half
1227 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1228 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1229 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1232 if ( flags
& wxCONTROL_CHECKED
)
1233 dc
.SetPen(m_penBlack
);
1234 else if ( flags
& wxCONTROL_PRESSED
)
1235 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1236 else // unchecked and unpressed
1240 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1242 // and then the lower one
1243 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1244 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1245 if ( !(flags
& wxCONTROL_CHECKED
) )
1246 dc
.SetPen(m_penDarkGrey
);
1247 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1249 if ( !(flags
& wxCONTROL_CHECKED
) )
1250 drawIt
= TRUE
; // with the same pen
1251 else if ( flags
& wxCONTROL_PRESSED
)
1253 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1256 else // checked and unpressed
1260 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1263 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1269 wxCoord xMid
= (x1
+ x2
) / 2;
1270 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1271 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1274 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1280 wxCoord xMid
= (x1
+ x2
) / 2;
1281 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1282 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1285 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1287 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1289 // init the bitmaps once only
1291 wxSize size
= GetCheckBitmapSize();
1292 rect
.width
= size
.x
;
1293 rect
.height
= size
.y
;
1294 for ( int i
= 0; i
< 2; i
++ )
1296 for ( int j
= 0; j
< 2; j
++ )
1297 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1303 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1304 DrawCheckBitmap(dc
, rect
);
1307 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1308 DrawUncheckBitmap(dc
, rect
, FALSE
);
1311 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1313 // pressed unchecked
1314 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1315 DrawUncheckBitmap(dc
, rect
, TRUE
);
1318 int row
= flags
& wxCONTROL_PRESSED
? 1 : 0;
1319 int col
= flags
& wxCONTROL_CHECKED
? 0 : 1;
1321 return m_bitmapsCheckbox
[row
][col
];
1324 wxBitmap
wxGTKRenderer::GetLineWrapBitmap()
1326 if ( !m_bmpLineWrap
.Ok() )
1328 // the line wrap bitmap as used by GTK+
1329 #define line_wrap_width 6
1330 #define line_wrap_height 9
1331 static const char line_wrap_bits
[] =
1333 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1336 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1337 if ( !bmpLineWrap
.Ok() )
1339 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1343 m_bmpLineWrap
= bmpLineWrap
;
1347 return m_bmpLineWrap
;
1350 void wxGTKRenderer::DrawCheckButton(wxDC
& dc
,
1351 const wxString
& label
,
1352 const wxBitmap
& bitmapOrig
,
1353 const wxRect
& rectTotal
,
1359 if ( bitmapOrig
.Ok() )
1361 bitmap
= bitmapOrig
;
1365 bitmap
= GetCheckBitmap(flags
);
1368 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1369 flags
, align
, indexAccel
);
1372 void wxGTKRenderer::DoDrawCheckOrRadioBitmap(wxDC
& dc
,
1373 const wxString
& label
,
1374 const wxBitmap
& bitmap
,
1375 const wxRect
& rectTotal
,
1380 wxRect rect
= rectTotal
;
1382 if ( flags
& wxCONTROL_FOCUSED
)
1384 // draw the focus border around everything
1385 DrawRect(dc
, &rect
, m_penBlack
);
1389 // the border does not offset the string under GTK
1393 // calculate the position of the bitmap and of the label
1395 yBmp
= rect
.y
+ (rect
.height
- bitmap
.GetHeight()) / 2;
1398 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
1399 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
1401 if ( align
== wxALIGN_RIGHT
)
1403 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
1404 rectLabel
.x
= rect
.x
+ 2;
1405 rectLabel
.SetRight(xBmp
);
1407 else // normal (checkbox to the left of the text) case
1410 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 4;
1411 rectLabel
.SetRight(rect
.GetRight());
1414 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
1416 DrawLabel(dc
, label
, rectLabel
, flags
,
1417 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1420 void wxGTKRenderer::DrawRadioButton(wxDC
& dc
,
1421 const wxString
& label
,
1422 const wxBitmap
& bitmapOrig
,
1423 const wxRect
& rectTotal
,
1429 if ( bitmapOrig
.Ok() )
1431 bitmap
= bitmapOrig
;
1436 wxSize size
= GetRadioBitmapSize();
1437 rect
.width
= size
.x
;
1438 rect
.height
= size
.y
;
1439 bitmap
.Create(rect
.width
, rect
.height
);
1441 dc
.SelectObject(bitmap
);
1442 dc
.SetBackground(*wxLIGHT_GREY_BRUSH
);
1444 DrawRadioBitmap(dc
, rect
, flags
);
1445 bitmap
.SetMask(new wxMask(bitmap
, *wxLIGHT_GREY
));
1448 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1449 flags
, align
, indexAccel
);
1452 // ----------------------------------------------------------------------------
1454 // ----------------------------------------------------------------------------
1456 wxRect
wxGTKRenderer::GetTextTotalArea(const wxTextCtrl
*text
,
1459 wxRect rectTotal
= rect
;
1460 rectTotal
.Inflate(2);
1464 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1466 wxCoord
*extraSpaceBeyond
)
1468 wxRect rectText
= rect
;
1469 rectText
.Inflate(-2);
1471 if ( text
->WrapLines() )
1473 // leave enough for the line wrap bitmap indicator
1474 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1476 rectText
.width
-= widthMark
;
1478 if ( extraSpaceBeyond
)
1479 *extraSpaceBeyond
= widthMark
;
1485 void wxGTKRenderer::DrawTextLine(wxDC
& dc
,
1486 const wxString
& text
,
1492 // TODO: GTK+ draws selection even for unfocused controls, just with
1493 // different colours
1494 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
1497 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1499 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1501 // for a mono bitmap he colours it appears in depends on the current text
1502 // colours, so set them correctly
1504 if ( bmpLineWrap
.GetDepth() == 1 )
1506 colFgOld
= dc
.GetTextForeground();
1508 // FIXME: I wonder what should we do if the background is black too?
1509 dc
.SetTextForeground(*wxBLACK
);
1512 dc
.DrawBitmap(bmpLineWrap
,
1513 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1515 if ( colFgOld
.Ok() )
1517 // restore old colour
1518 dc
.SetTextForeground(colFgOld
);
1522 // ----------------------------------------------------------------------------
1524 // ----------------------------------------------------------------------------
1526 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1527 const wxRect
& rectOrig
,
1529 const wxString
& label
,
1530 const wxBitmap
& bitmap
,
1534 wxRect rect
= rectOrig
;
1536 // the current tab is drawn indented (to the top for default case) and
1537 // bigger than the other ones
1538 const wxSize indent
= GetTabIndent();
1539 if ( flags
& wxCONTROL_SELECTED
)
1544 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1548 rect
.Inflate(indent
.x
, 0);
1550 rect
.height
+= indent
.y
;
1554 rect
.Inflate(indent
.x
, 0);
1555 rect
.height
+= indent
.y
;
1560 wxFAIL_MSG(_T("TODO"));
1565 // selected tab has different colour
1566 wxColour col
= flags
& wxCONTROL_SELECTED
1567 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1568 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1569 DoDrawBackground(dc
, col
, rect
);
1571 if ( flags
& wxCONTROL_FOCUSED
)
1573 // draw the focus rect
1574 wxRect rectBorder
= rect
;
1575 rectBorder
.Deflate(4, 3);
1576 if ( dir
== wxBOTTOM
)
1577 rectBorder
.Offset(0, -1);
1579 DrawRect(dc
, &rectBorder
, m_penBlack
);
1582 // draw the text, image and the focus around them (if necessary)
1583 wxRect rectLabel
= rect
;
1584 rectLabel
.Deflate(1, 1);
1585 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1587 // now draw the tab itself
1590 x2
= rect
.GetRight(),
1591 y2
= rect
.GetBottom();
1596 dc
.SetPen(m_penHighlight
);
1597 dc
.DrawLine(x
, y2
, x
, y
);
1598 dc
.DrawLine(x
+ 1, y
, x2
, y
);
1600 dc
.SetPen(m_penBlack
);
1601 dc
.DrawLine(x2
, y2
, x2
, y
);
1603 dc
.SetPen(m_penDarkGrey
);
1604 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ 1);
1606 if ( flags
& wxCONTROL_SELECTED
)
1608 dc
.SetPen(m_penLightGrey
);
1610 // overwrite the part of the border below this tab
1611 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
1613 // and the shadow of the tab to the left of us
1614 dc
.DrawLine(x
+ 1, y
+ 2, x
+ 1, y2
+ 1);
1619 dc
.SetPen(m_penHighlight
);
1621 // we need to continue one pixel further to overwrite the corner of
1622 // the border for the selected tab
1623 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
1626 // it doesn't work like this (TODO: implement it properly)
1628 // erase the corner of the tab to the right
1629 dc
.SetPen(m_penLightGrey
);
1630 dc
.DrawPoint(x2
- 1, y
- 2);
1631 dc
.DrawPoint(x2
- 2, y
- 2);
1632 dc
.DrawPoint(x2
- 2, y
- 1);
1635 dc
.SetPen(m_penBlack
);
1636 dc
.DrawLine(x
+ 1, y2
, x2
, y2
);
1637 dc
.DrawLine(x2
, y
, x2
, y2
);
1639 dc
.SetPen(m_penDarkGrey
);
1640 dc
.DrawLine(x
+ 2, y2
- 1, x2
- 1, y2
- 1);
1641 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
);
1643 if ( flags
& wxCONTROL_SELECTED
)
1645 dc
.SetPen(m_penLightGrey
);
1647 // overwrite the part of the (double!) border above this tab
1648 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
1649 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
1651 // and the shadow of the tab to the left of us
1652 dc
.DrawLine(x
+ 1, y2
- 1, x
+ 1, y
- 1);
1658 wxFAIL_MSG(_T("TODO"));
1662 // ----------------------------------------------------------------------------
1664 // ----------------------------------------------------------------------------
1666 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1667 wxOrientation orient
) const
1669 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1673 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
1674 if ( orient
== wxHORIZONTAL
)
1676 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1677 size
.y
= rectShaft
.height
;
1681 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1682 size
.x
= rectShaft
.width
;
1688 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1689 wxOrientation
WXUNUSED(orient
)) const
1691 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
1694 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
1695 const wxRect
& rectOrig
,
1696 wxOrientation orient
,
1700 wxRect rect
= rectOrig
;
1702 // draw the border first
1703 if ( flags
& wxCONTROL_FOCUSED
)
1705 DrawRect(dc
, &rect
, m_penBlack
);
1706 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1708 else // not focused, normal
1710 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1711 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1714 // and the background
1715 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
1721 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
1722 const wxRect
& rectOrig
,
1723 wxOrientation orient
,
1726 // draw the thumb border
1727 wxRect rect
= rectOrig
;
1728 DrawAntiRaisedBorder(dc
, &rect
);
1730 // draw the handle in the middle
1731 if ( orient
== wxVERTICAL
)
1733 rect
.height
= 2*BORDER_THICKNESS
;
1734 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
1738 rect
.width
= 2*BORDER_THICKNESS
;
1739 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
1742 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1745 // ----------------------------------------------------------------------------
1747 // ----------------------------------------------------------------------------
1749 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
1751 const wxString
& label
,
1755 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE
, indexAccel
);
1758 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
1760 const wxMenuGeometryInfo
& geometryInfo
,
1761 const wxString
& label
,
1762 const wxString
& accel
,
1763 const wxBitmap
& bitmap
,
1767 wxFAIL_MSG(_T("TODO"));
1770 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
1772 const wxMenuGeometryInfo
& geomInfo
)
1774 wxFAIL_MSG(_T("TODO"));
1777 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
1782 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
1783 const wxMenu
& menu
) const
1785 wxFAIL_MSG(_T("TODO"));
1790 // ----------------------------------------------------------------------------
1792 // ----------------------------------------------------------------------------
1794 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
1795 wxBitmap
*bmpPressed
,
1796 wxBitmap
*bmpDisabled
)
1801 // ----------------------------------------------------------------------------
1803 // ----------------------------------------------------------------------------
1805 void wxGTKRenderer::DoDrawBackground(wxDC
& dc
,
1806 const wxColour
& col
,
1809 wxBrush
brush(col
, wxSOLID
);
1811 dc
.SetPen(*wxTRANSPARENT_PEN
);
1812 dc
.DrawRectangle(rect
);
1815 void wxGTKRenderer::DrawBackground(wxDC
& dc
,
1816 const wxColour
& col
,
1820 wxColour colBg
= col
.Ok() ? col
: GetBackgroundColour(flags
);
1821 DoDrawBackground(dc
, colBg
, rect
);
1824 // ----------------------------------------------------------------------------
1826 // ----------------------------------------------------------------------------
1828 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
1832 static const wxDirection sides
[] =
1834 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
1837 wxRect rect1
, rect2
, rectInner
;
1843 rectInner
.Inflate(-2);
1845 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
1847 // find the side not to draw and also adjust the rectangles to compensate
1849 wxDirection sideToOmit
;
1853 sideToOmit
= wxDOWN
;
1855 rectInner
.height
+= 1;
1863 rectInner
.height
+= 1;
1867 sideToOmit
= wxRIGHT
;
1869 rectInner
.width
+= 1;
1873 sideToOmit
= wxLEFT
;
1877 rectInner
.width
+= 1;
1881 wxFAIL_MSG(_T("unknown arrow direction"));
1885 // the outer rect first
1887 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
1889 wxDirection side
= sides
[n
];
1890 if ( side
== sideToOmit
)
1893 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
1896 // and then the inner one
1897 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
1899 wxDirection side
= sides
[n
];
1900 if ( side
== sideToOmit
)
1903 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
1909 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
1911 const wxRect
& rectArrow
,
1914 // first of all, draw the border around it - but we don't want the border
1915 // on the side opposite to the arrow point
1916 wxRect rect
= rectArrow
;
1917 DrawArrowBorder(dc
, &rect
, dir
);
1919 // then the arrow itself
1920 DrawArrow(dc
, dir
, rect
, flags
);
1923 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
1924 // these people are just crazy :-(
1925 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
1938 wxPoint ptArrow
[Point_Max
];
1940 wxColour colInside
= GetBackgroundColour(flags
);
1942 if ( flags
& wxCONTROL_DISABLED
)
1944 penShadow
[0] = m_penDarkGrey
;
1945 penShadow
[1] = m_penDarkGrey
;
1946 penShadow
[2] = wxNullPen
;
1947 penShadow
[3] = wxNullPen
;
1949 else if ( flags
& wxCONTROL_PRESSED
)
1951 penShadow
[0] = m_penDarkGrey
;
1952 penShadow
[1] = m_penHighlight
;
1953 penShadow
[2] = wxNullPen
;
1954 penShadow
[3] = m_penBlack
;
1956 else // normal arrow
1958 penShadow
[0] = m_penHighlight
;
1959 penShadow
[1] = m_penBlack
;
1960 penShadow
[2] = m_penDarkGrey
;
1961 penShadow
[3] = wxNullPen
;
1965 if ( dir
== wxUP
|| dir
== wxDOWN
)
1968 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
1972 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
1975 // draw the arrow interior
1976 dc
.SetPen(*wxTRANSPARENT_PEN
);
1977 dc
.SetBrush(wxBrush(colInside
, wxSOLID
));
1982 ptArrow
[Point_First
].x
= rect
.GetLeft();
1983 ptArrow
[Point_First
].y
= rect
.GetBottom();
1984 ptArrow
[Point_Second
].x
= middle
;
1985 ptArrow
[Point_Second
].y
= rect
.GetTop();
1986 ptArrow
[Point_Third
].x
= rect
.GetRight();
1987 ptArrow
[Point_Third
].y
= rect
.GetBottom();
1991 ptArrow
[Point_First
] = rect
.GetPosition();
1992 ptArrow
[Point_Second
].x
= middle
;
1993 ptArrow
[Point_Second
].y
= rect
.GetBottom();
1994 ptArrow
[Point_Third
].x
= rect
.GetRight();
1995 ptArrow
[Point_Third
].y
= rect
.GetTop();
1999 ptArrow
[Point_First
].x
= rect
.GetRight();
2000 ptArrow
[Point_First
].y
= rect
.GetTop();
2001 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2002 ptArrow
[Point_Second
].y
= middle
;
2003 ptArrow
[Point_Third
].x
= rect
.GetRight();
2004 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2008 ptArrow
[Point_First
] = rect
.GetPosition();
2009 ptArrow
[Point_Second
].x
= rect
.GetRight();
2010 ptArrow
[Point_Second
].y
= middle
;
2011 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2012 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2016 wxFAIL_MSG(_T("unknown arrow direction"));
2019 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2021 // draw the arrow border
2022 dc
.SetPen(penShadow
[0]);
2026 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2027 dc
.DrawPoint(ptArrow
[Point_First
]);
2028 if ( penShadow
[3].Ok() )
2030 dc
.SetPen(penShadow
[3]);
2031 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2032 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2034 dc
.SetPen(penShadow
[1]);
2035 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2036 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2037 dc
.DrawPoint(ptArrow
[Point_Third
]);
2038 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2039 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2040 if ( penShadow
[2].Ok() )
2042 dc
.SetPen(penShadow
[2]);
2043 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2044 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2045 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2046 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2051 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2052 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2053 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2054 if ( penShadow
[2].Ok() )
2056 dc
.SetPen(penShadow
[2]);
2057 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2058 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2060 dc
.SetPen(penShadow
[1]);
2061 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2062 dc
.DrawPoint(ptArrow
[Point_Third
]);
2066 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2067 dc
.DrawPoint(ptArrow
[Point_First
]);
2068 if ( penShadow
[2].Ok() )
2070 dc
.SetPen(penShadow
[2]);
2071 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2072 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2073 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2074 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2076 dc
.SetPen(penShadow
[1]);
2077 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2078 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2079 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2080 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2084 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2085 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2086 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2087 dc
.SetPen(penShadow
[1]);
2088 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2089 dc
.DrawPoint(ptArrow
[Point_Third
]);
2093 wxFAIL_MSG(_T("unknown arrow direction"));
2098 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2100 wxOrientation orient
)
2102 if ( orient
== wxVERTICAL
)
2104 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2106 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2108 rect
->Inflate(-1, 0);
2110 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2112 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2114 rect
->Inflate(-1, 0);
2118 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2120 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2122 rect
->Inflate(0, -1);
2124 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2126 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2128 rect
->Inflate(0, -1);
2132 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2133 wxOrientation orient
,
2137 // the thumb is never pressed never has focus border under GTK and the
2138 // scrollbar background never changes at all
2139 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2141 // we don't want the border in the direction of the scrollbar movement
2142 wxRect rectThumb
= rect
;
2143 DrawThumbBorder(dc
, &rectThumb
, orient
);
2145 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2146 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2149 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2150 wxOrientation orient
,
2154 wxRect rectBar
= rect
;
2155 DrawThumbBorder(dc
, &rectBar
, orient
);
2156 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2159 void wxGTKRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2161 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2164 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2165 wxScrollBar::Element elem
,
2168 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2169 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2171 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2173 elem
= wxScrollBar::Element_Bar_2
;
2176 return StandardGetScrollbarRect(scrollbar
, elem
,
2178 GetScrollbarArrowSize(scrollbar
));
2181 wxCoord
wxGTKRenderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
2183 return StandardScrollBarSize(scrollbar
, GetScrollbarArrowSize(scrollbar
));
2186 wxHitTest
wxGTKRenderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
2187 const wxPoint
& pt
) const
2189 return StandardHitTestScrollbar(scrollbar
, pt
,
2190 GetScrollbarArrowSize(scrollbar
));
2193 wxCoord
wxGTKRenderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
2196 return StandardScrollbarToPixel(scrollbar
, thumbPos
,
2197 GetScrollbarArrowSize(scrollbar
));
2200 int wxGTKRenderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
2203 return StandardPixelToScrollbar(scrollbar
, coord
,
2204 GetScrollbarArrowSize(scrollbar
));
2207 // ----------------------------------------------------------------------------
2209 // ----------------------------------------------------------------------------
2211 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2213 if ( wxDynamicCast(window
, wxButton
) )
2215 // TODO: this is ad hoc...
2216 size
->x
+= 3*window
->GetCharWidth();
2219 wxCoord minBtnHeight
= 22;
2220 if ( size
->y
< minBtnHeight
)
2221 size
->y
= minBtnHeight
;
2223 // button border width
2226 else if ( wxDynamicCast(window
, wxScrollBar
) )
2228 // we only set the width of vert scrollbars and height of the
2230 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2231 size
->y
= m_sizeScrollbarArrow
.x
;
2233 size
->x
= m_sizeScrollbarArrow
.x
;
2237 // take into account the border width
2238 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
2239 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
2240 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
2244 // ============================================================================
2246 // ============================================================================
2248 // ----------------------------------------------------------------------------
2249 // wxGTKInputHandler
2250 // ----------------------------------------------------------------------------
2252 wxGTKInputHandler::wxGTKInputHandler(wxGTKRenderer
*renderer
)
2254 m_renderer
= renderer
;
2257 bool wxGTKInputHandler::HandleKey(wxControl
*control
,
2258 const wxKeyEvent
& event
,
2264 bool wxGTKInputHandler::HandleMouse(wxControl
*control
,
2265 const wxMouseEvent
& event
)
2267 // clicking on the control gives it focus
2268 if ( event
.ButtonDown() )
2270 control
->SetFocus();
2278 bool wxGTKInputHandler::HandleMouseMove(wxControl
*control
,
2279 const wxMouseEvent
& event
)
2281 if ( event
.Entering() )
2283 control
->SetCurrent(TRUE
);
2285 else if ( event
.Leaving() )
2287 control
->SetCurrent(FALSE
);
2297 // ----------------------------------------------------------------------------
2298 // wxGTKCheckboxInputHandler
2299 // ----------------------------------------------------------------------------
2301 bool wxGTKCheckboxInputHandler::HandleKey(wxControl
*control
,
2302 const wxKeyEvent
& event
,
2307 int keycode
= event
.GetKeyCode();
2308 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
2310 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
2319 // ----------------------------------------------------------------------------
2320 // wxGTKTextCtrlInputHandler
2321 // ----------------------------------------------------------------------------
2323 bool wxGTKTextCtrlInputHandler::HandleKey(wxControl
*control
,
2324 const wxKeyEvent
& event
,
2327 // handle only GTK-specific text bindings here, the others are handled in
2331 wxControlAction action
;
2332 int keycode
= event
.GetKeyCode();
2333 if ( event
.ControlDown() )
2338 action
= wxACTION_TEXT_HOME
;
2342 action
= wxACTION_TEXT_LEFT
;
2346 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
2350 action
= wxACTION_TEXT_END
;
2354 action
= wxACTION_TEXT_RIGHT
;
2358 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
2362 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2366 action
= wxACTION_TEXT_DOWN
;
2370 action
= wxACTION_TEXT_UP
;
2374 //delete the entire line
2375 control
->PerformAction(wxACTION_TEXT_HOME
);
2376 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2380 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
2384 else if ( event
.AltDown() )
2389 action
= wxACTION_TEXT_WORD_LEFT
;
2393 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
2397 action
= wxACTION_TEXT_WORD_RIGHT
;
2402 if ( action
!= wxACTION_NONE
)
2404 control
->PerformAction(action
);
2410 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);