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"
51 #include "wx/toplevel.h"
53 // ----------------------------------------------------------------------------
54 // constants (to be removed, for testing only)
55 // ----------------------------------------------------------------------------
57 static const wxCoord BORDER_THICKNESS
= 1;
59 // ----------------------------------------------------------------------------
60 // wxGTKRenderer: draw the GUI elements in GTK style
61 // ----------------------------------------------------------------------------
63 class wxGTKRenderer
: public wxRenderer
66 wxGTKRenderer(const wxColourScheme
*scheme
);
68 // implement the base class pure virtuals
69 virtual void DrawBackground(wxDC
& dc
,
73 virtual void DrawLabel(wxDC
& dc
,
74 const wxString
& label
,
77 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
79 wxRect
*rectBounds
= NULL
);
80 virtual void DrawButtonLabel(wxDC
& dc
,
81 const wxString
& label
,
82 const wxBitmap
& image
,
85 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
87 wxRect
*rectBounds
= NULL
);
88 virtual void DrawBorder(wxDC
& dc
,
92 wxRect
*rectIn
= (wxRect
*)NULL
);
93 virtual void DrawHorizontalLine(wxDC
& dc
,
94 wxCoord y
, wxCoord x1
, wxCoord x2
);
95 virtual void DrawVerticalLine(wxDC
& dc
,
96 wxCoord x
, wxCoord y1
, wxCoord y2
);
97 virtual void DrawFrame(wxDC
& dc
,
98 const wxString
& label
,
101 int alignment
= wxALIGN_LEFT
,
102 int indexAccel
= -1);
103 virtual void DrawTextBorder(wxDC
& dc
,
107 wxRect
*rectIn
= (wxRect
*)NULL
);
108 virtual void DrawButtonBorder(wxDC
& dc
,
111 wxRect
*rectIn
= (wxRect
*)NULL
);
112 virtual void DrawArrow(wxDC
& dc
,
116 virtual void DrawScrollbarArrow(wxDC
& dc
,
120 virtual void DrawScrollbarThumb(wxDC
& dc
,
121 wxOrientation orient
,
124 virtual void DrawScrollbarShaft(wxDC
& dc
,
125 wxOrientation orient
,
128 virtual void DrawScrollCorner(wxDC
& dc
,
130 virtual void DrawItem(wxDC
& dc
,
131 const wxString
& label
,
134 virtual void DrawCheckItem(wxDC
& dc
,
135 const wxString
& label
,
136 const wxBitmap
& bitmap
,
139 virtual void DrawCheckButton(wxDC
& dc
,
140 const wxString
& label
,
141 const wxBitmap
& bitmap
,
144 wxAlignment align
= wxALIGN_LEFT
,
145 int indexAccel
= -1);
147 virtual void DrawRadioButton(wxDC
& dc
,
148 const wxString
& label
,
149 const wxBitmap
& bitmap
,
152 wxAlignment align
= wxALIGN_LEFT
,
153 int indexAccel
= -1);
155 virtual void DrawTextLine(wxDC
& dc
,
156 const wxString
& text
,
161 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
162 virtual void DrawTab(wxDC
& dc
,
165 const wxString
& label
,
166 const wxBitmap
& bitmap
= wxNullBitmap
,
168 int indexAccel
= -1);
170 virtual void DrawSliderShaft(wxDC
& dc
,
172 wxOrientation orient
,
174 wxRect
*rectShaft
= NULL
);
175 virtual void DrawSliderThumb(wxDC
& dc
,
177 wxOrientation orient
,
179 virtual void DrawSliderTicks(wxDC
& dc
,
181 const wxSize
& sizeThumb
,
182 wxOrientation orient
,
188 // 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 DrawStatusField(wxDC
& dc
,
210 const wxString
& label
,
213 virtual void DrawFrameTitleBar(wxDC
& dc
,
215 const wxString
& title
,
218 int specialButton
= 0,
219 int specialButtonFlag
= 0);
220 virtual void DrawFrameBorder(wxDC
& dc
,
223 virtual void DrawFrameBackground(wxDC
& dc
,
226 virtual void DrawFrameTitle(wxDC
& dc
,
228 const wxString
& title
,
230 virtual void DrawFrameIcon(wxDC
& dc
,
234 virtual void DrawFrameButton(wxDC
& dc
,
235 wxCoord x
, wxCoord y
,
240 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
241 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
242 virtual wxSize
GetFrameIconSize() const;
243 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
245 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
247 wxBitmap
*bmpPressed
,
248 wxBitmap
*bmpDisabled
);
250 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
251 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
252 virtual bool AreScrollbarsInsideBorder() const;
254 // geometry and hit testing
255 virtual wxSize
GetScrollbarArrowSize() const
256 { return m_sizeScrollbarArrow
; }
257 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
258 wxScrollBar::Element elem
,
259 int thumbPos
= -1) const;
260 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
261 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
262 const wxPoint
& pt
) const;
263 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
265 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
266 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
267 { return fontHeight
+ 2; }
268 virtual wxSize
GetCheckBitmapSize() const
269 { return wxSize(10, 10); }
270 virtual wxSize
GetRadioBitmapSize() const
271 { return wxSize(11, 11); }
272 virtual wxCoord
GetCheckItemMargin() const
275 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
277 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
279 wxCoord
*extraSpaceBeyond
);
281 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
282 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
284 virtual wxCoord
GetSliderDim() const { return 15; }
285 virtual wxCoord
GetSliderTickLen() const { return 0; }
286 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
287 wxOrientation orient
) const;
288 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
289 wxOrientation orient
) const;
290 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
292 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
293 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
294 const wxMenu
& menu
) const;
296 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
298 // helpers for "wxBitmap wxColourScheme::Get()"
299 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
300 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
303 // DrawBackground() helpers
305 // get the colour to use for background
306 wxColour
GetBackgroundColour(int flags
) const
308 if ( flags
& wxCONTROL_PRESSED
)
309 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
310 else if ( flags
& wxCONTROL_CURRENT
)
311 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
313 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
316 // draw the background with any colour, not only the default one(s)
317 void DoDrawBackground(wxDC
& dc
,
321 // DrawBorder() helpers: all of them shift and clip the DC after drawing
324 // just draw a rectangle with the given pen
325 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
327 // draw the lower left part of rectangle
328 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
330 // draw the rectange using the first brush for the left and top sides and
331 // the second one for the bottom and right ones
332 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
333 const wxPen
& pen1
, const wxPen
& pen2
);
335 // as DrawShadedRect() but the pixels in the bottom left and upper right
336 // border are drawn with the pen1, not pen2
337 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
338 const wxPen
& pen1
, const wxPen
& pen2
);
340 // used for drawing opened rectangles - draws only one side of it at once
341 // (and doesn't adjust the rect)
342 void DrawAntiShadedRectSide(wxDC
& dc
,
348 // draw an opened rect for the arrow in given direction
349 void DrawArrowBorder(wxDC
& dc
,
353 // draw two sides of the rectangle
354 void DrawThumbBorder(wxDC
& dc
,
356 wxOrientation orient
);
358 // draw the normal 3D border
359 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
361 // just as DrawRaisedBorder() except that the bottom left and up right
362 // pixels of the interior rect are drawn in another colour (i.e. the inner
363 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
364 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
366 // returns the size of the arrow for the scrollbar (depends on
368 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
371 if ( scrollbar
->IsVertical() )
373 size
= m_sizeScrollbarArrow
;
377 size
.x
= m_sizeScrollbarArrow
.y
;
378 size
.y
= m_sizeScrollbarArrow
.x
;
384 // get the line wrap indicator bitmap
385 wxBitmap
GetLineWrapBitmap();
387 // DrawCheckBitmap and DrawRadioBitmap helpers
389 // draw the check bitmaps once and cache them for later use
390 wxBitmap
GetCheckBitmap(int flags
);
392 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
394 void DrawUpZag(wxDC
& dc
,
395 wxCoord x1
, wxCoord x2
,
396 wxCoord y1
, wxCoord y2
);
397 void DrawDownZag(wxDC
& dc
,
398 wxCoord x1
, wxCoord x2
,
399 wxCoord y1
, wxCoord y2
);
401 // draw the radio button bitmap for the given state
402 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
404 // draw check/radio - the bitmap must be a valid one by now
405 void DoDrawCheckOrRadioBitmap(wxDC
& dc
,
406 const wxString
& label
,
407 const wxBitmap
& bitmap
,
408 const wxRect
& rectTotal
,
413 // initialize the combo bitmaps
414 void InitComboBitmaps();
417 const wxColourScheme
*m_scheme
;
420 wxSize m_sizeScrollbarArrow
;
429 // the checkbox bitmaps: first row is for the normal, second for the
430 // pressed state and the columns are for checked and unchecked status
432 wxBitmap m_bitmapsCheckbox
[2][2];
434 // the line wrap bitmap (drawn at the end of wrapped lines)
435 wxBitmap m_bmpLineWrap
;
437 // the combobox bitmaps
447 wxBitmap m_bitmapsCombo
[ComboState_Max
];
450 // ----------------------------------------------------------------------------
451 // wxGTKInputHandler and derived classes: process the keyboard and mouse
452 // messages according to GTK standards
453 // ----------------------------------------------------------------------------
455 class wxGTKInputHandler
: public wxInputHandler
458 wxGTKInputHandler(wxGTKRenderer
*renderer
);
460 virtual bool HandleKey(wxInputConsumer
*control
,
461 const wxKeyEvent
& event
,
463 virtual bool HandleMouse(wxInputConsumer
*control
,
464 const wxMouseEvent
& event
);
465 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
468 wxGTKRenderer
*m_renderer
;
471 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
474 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
475 : wxStdScrollBarInputHandler(renderer
, handler
) { }
478 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
480 // only arrows and the thumb can be highlighted
481 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
484 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
487 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
489 // only arrows can be pressed
493 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
496 virtual bool IsAllowedButton(int WXUNUSED(button
)) { return TRUE
; }
500 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
501 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
505 class wxGTKCheckboxInputHandler
: public wxStdCheckboxInputHandler
508 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
509 : wxStdCheckboxInputHandler(handler
) { }
511 virtual bool HandleKey(wxInputConsumer
*control
,
512 const wxKeyEvent
& event
,
516 class wxGTKTextCtrlInputHandler
: public wxStdTextCtrlInputHandler
519 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
520 : wxStdTextCtrlInputHandler(handler
) { }
522 virtual bool HandleKey(wxInputConsumer
*control
,
523 const wxKeyEvent
& event
,
527 // ----------------------------------------------------------------------------
528 // wxGTKColourScheme: uses the standard GTK colours
529 // ----------------------------------------------------------------------------
531 class wxGTKColourScheme
: public wxColourScheme
534 virtual wxColour
Get(StdColour col
) const;
535 virtual wxColour
GetBackground(wxWindow
*win
) const;
538 // ----------------------------------------------------------------------------
540 // ----------------------------------------------------------------------------
542 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
544 class wxGTKTheme
: public wxTheme
548 virtual ~wxGTKTheme();
550 virtual wxRenderer
*GetRenderer() { return m_renderer
; }
551 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
552 virtual wxColourScheme
*GetColourScheme() { return m_scheme
; }
555 // get the default input handler
556 wxInputHandler
*GetDefaultInputHandler();
558 wxGTKRenderer
*m_renderer
;
560 // the names of the already created handlers and the handlers themselves
561 // (these arrays are synchronized)
562 wxSortedArrayString m_handlerNames
;
563 wxArrayHandlers m_handlers
;
565 wxGTKInputHandler
*m_handlerDefault
;
567 wxGTKColourScheme
*m_scheme
;
569 WX_DECLARE_THEME(gtk
)
572 // ============================================================================
574 // ============================================================================
576 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
578 // ----------------------------------------------------------------------------
580 // ----------------------------------------------------------------------------
582 wxGTKTheme::wxGTKTheme()
584 m_scheme
= new wxGTKColourScheme
;
585 m_renderer
= new wxGTKRenderer(m_scheme
);
586 m_handlerDefault
= NULL
;
589 wxGTKTheme::~wxGTKTheme()
591 size_t count
= m_handlers
.GetCount();
592 for ( size_t n
= 0; n
< count
; n
++ )
594 if ( m_handlers
[n
] != m_handlerDefault
)
595 delete m_handlers
[n
];
598 delete m_handlerDefault
;
603 wxInputHandler
*wxGTKTheme::GetDefaultInputHandler()
605 if ( !m_handlerDefault
)
607 m_handlerDefault
= new wxGTKInputHandler(m_renderer
);
610 return m_handlerDefault
;
613 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
)
615 wxInputHandler
*handler
;
616 int n
= m_handlerNames
.Index(control
);
617 if ( n
== wxNOT_FOUND
)
619 // create a new handler
620 if ( control
== wxINP_HANDLER_SCROLLBAR
)
621 handler
= new wxGTKScrollBarInputHandler(m_renderer
,
622 GetDefaultInputHandler());
624 else if ( control
== wxINP_HANDLER_BUTTON
)
625 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
626 #endif // wxUSE_CHECKBOX
628 else if ( control
== wxINP_HANDLER_CHECKBOX
)
629 handler
= new wxGTKCheckboxInputHandler(GetDefaultInputHandler());
630 #endif // wxUSE_CHECKBOX
632 else if ( control
== wxINP_HANDLER_COMBOBOX
)
633 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
634 #endif // wxUSE_COMBOBOX
636 else if ( control
== wxINP_HANDLER_LISTBOX
)
637 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
638 #endif // wxUSE_LISTBOX
639 #if wxUSE_CHECKLISTBOX
640 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
641 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
642 #endif // wxUSE_CHECKLISTBOX
644 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
645 handler
= new wxGTKTextCtrlInputHandler(GetDefaultInputHandler());
646 #endif // wxUSE_TEXTCTRL
648 else if ( control
== wxINP_HANDLER_SLIDER
)
649 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
650 #endif // wxUSE_SLIDER
652 else if ( control
== wxINP_HANDLER_SPINBTN
)
653 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
654 #endif // wxUSE_SPINBTN
656 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
657 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
658 #endif // wxUSE_NOTEBOOK
659 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
660 handler
= new wxStdFrameInputHandler(GetDefaultInputHandler());
662 handler
= GetDefaultInputHandler();
664 n
= m_handlerNames
.Add(control
);
665 m_handlers
.Insert(handler
, n
);
667 else // we already have it
669 handler
= m_handlers
[n
];
675 // ============================================================================
677 // ============================================================================
679 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
682 if ( win
->UseBgCol() )
684 // use the user specified colour
685 col
= win
->GetBackgroundColour();
688 if ( win
->IsContainerWindow() )
690 // doesn't depend on the state
698 int flags
= win
->GetStateFlags();
700 // the colour set by the user should be used for the normal state
701 // and for the states for which we don't have any specific colours
702 if ( !col
.Ok() || (flags
!= 0) )
704 if ( wxDynamicCast(win
, wxScrollBar
) )
705 col
= Get(SCROLLBAR
);
706 else if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
707 col
= Get(CONTROL_CURRENT
);
708 else if ( flags
& wxCONTROL_PRESSED
)
709 col
= Get(CONTROL_PRESSED
);
718 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
722 case WINDOW
: return *wxWHITE
;
724 case SHADOW_DARK
: return *wxBLACK
;
725 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
726 case SHADOW_IN
: return wxColour(0xd6d6d6);
727 case SHADOW_OUT
: return wxColour(0x969696);
729 case CONTROL
: return wxColour(0xd6d6d6);
730 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
731 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
733 case CONTROL_TEXT
: return *wxBLACK
;
734 case CONTROL_TEXT_DISABLED
:
735 return wxColour(0x757575);
736 case CONTROL_TEXT_DISABLED_SHADOW
:
740 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
742 case HIGHLIGHT
: return wxColour(0x9c0000);
743 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
747 wxFAIL_MSG(_T("invalid standard colour"));
752 // ============================================================================
754 // ============================================================================
756 // ----------------------------------------------------------------------------
758 // ----------------------------------------------------------------------------
760 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
764 m_sizeScrollbarArrow
= wxSize(15, 14);
767 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
768 m_penDarkGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_OUT
), 0, wxSOLID
);
769 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
), 0, wxSOLID
);
770 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
771 m_penHighlight
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
), 0, wxSOLID
);
774 // ----------------------------------------------------------------------------
776 // ----------------------------------------------------------------------------
778 void wxGTKRenderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
782 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
783 dc
.DrawRectangle(*rect
);
789 void wxGTKRenderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
791 // draw the bottom and right sides
793 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
794 rect
->GetRight() + 1, rect
->GetBottom());
795 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
796 rect
->GetRight(), rect
->GetBottom());
803 void wxGTKRenderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
804 const wxPen
& pen1
, const wxPen
& pen2
)
806 // draw the rectangle
808 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
809 rect
->GetLeft(), rect
->GetBottom());
810 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
811 rect
->GetRight(), rect
->GetTop());
813 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
814 rect
->GetRight(), rect
->GetBottom());
815 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
816 rect
->GetRight() + 1, rect
->GetBottom());
822 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
828 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
833 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
834 rect
.GetLeft(), rect
.GetBottom() + 1);
838 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
839 rect
.GetRight() + 1, rect
.GetTop());
843 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
844 rect
.GetRight(), rect
.GetBottom() + 1);
848 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
849 rect
.GetRight() + 1, rect
.GetBottom());
853 wxFAIL_MSG(_T("unknown rectangle side"));
857 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
858 const wxPen
& pen1
, const wxPen
& pen2
)
860 // draw the rectangle
862 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
863 rect
->GetLeft(), rect
->GetBottom() + 1);
864 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
865 rect
->GetRight() + 1, rect
->GetTop());
867 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
868 rect
->GetRight(), rect
->GetBottom());
869 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
870 rect
->GetRight() + 1, rect
->GetBottom());
876 void wxGTKRenderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
878 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
879 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
882 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
884 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
885 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
888 void wxGTKRenderer::DrawBorder(wxDC
& dc
,
890 const wxRect
& rectTotal
,
896 wxRect rect
= rectTotal
;
900 case wxBORDER_SUNKEN
:
901 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
903 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
904 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
908 case wxBORDER_STATIC
:
909 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
911 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
915 case wxBORDER_RAISED
:
916 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
918 DrawRaisedBorder(dc
, &rect
);
922 case wxBORDER_DOUBLE
:
923 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
925 DrawShadedRect(dc
, &rect
, m_penLightGrey
, m_penBlack
);
926 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penDarkGrey
);
927 DrawRect(dc
, &rect
, m_penLightGrey
);
931 case wxBORDER_SIMPLE
:
932 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
934 DrawRect(dc
, &rect
, m_penBlack
);
939 wxFAIL_MSG(_T("unknown border type"));
942 case wxBORDER_DEFAULT
:
951 wxRect
wxGTKRenderer::GetBorderDimensions(wxBorder border
) const
956 case wxBORDER_RAISED
:
957 case wxBORDER_SUNKEN
:
958 width
= 2*BORDER_THICKNESS
;
961 case wxBORDER_SIMPLE
:
962 case wxBORDER_STATIC
:
963 width
= BORDER_THICKNESS
;
966 case wxBORDER_DOUBLE
:
967 width
= 3*BORDER_THICKNESS
;
971 wxFAIL_MSG(_T("unknown border type"));
974 case wxBORDER_DEFAULT
:
989 bool wxGTKRenderer::AreScrollbarsInsideBorder() const
991 // no, the scrollbars are outside the border in GTK+
995 // ----------------------------------------------------------------------------
997 // ----------------------------------------------------------------------------
999 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
1001 const wxRect
& rectOrig
,
1005 wxRect rect
= rectOrig
;
1007 if ( border
!= wxBORDER_NONE
)
1009 if ( flags
& wxCONTROL_FOCUSED
)
1011 DrawRect(dc
, &rect
, m_penBlack
);
1012 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1016 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1017 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penHighlight
);
1025 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
1026 const wxRect
& rectTotal
,
1030 wxRect rect
= rectTotal
;
1032 if ( flags
& wxCONTROL_PRESSED
)
1034 // button pressed: draw a black border around it and an inward shade
1035 DrawRect(dc
, &rect
, m_penBlack
);
1037 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1039 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1040 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penDarkGrey
);
1045 // button not pressed
1047 if ( flags
& wxCONTROL_ISDEFAULT
)
1052 if ( flags
& wxCONTROL_FOCUSED
)
1054 // button is currently default: add an extra border around it
1055 DrawRect(dc
, &rect
, m_penBlack
);
1058 // now draw a normal button
1059 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1061 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1062 DrawAntiShadedRect(dc
, &rect
,
1063 wxPen(GetBackgroundColour(flags
), 0, wxSOLID
),
1074 // ----------------------------------------------------------------------------
1076 // ----------------------------------------------------------------------------
1078 void wxGTKRenderer::DrawHorizontalLine(wxDC
& dc
,
1079 wxCoord y
, wxCoord x1
, wxCoord x2
)
1081 dc
.SetPen(m_penDarkGrey
);
1082 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1083 dc
.SetPen(m_penHighlight
);
1085 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1088 void wxGTKRenderer::DrawVerticalLine(wxDC
& dc
,
1089 wxCoord x
, wxCoord y1
, wxCoord y2
)
1091 dc
.SetPen(m_penDarkGrey
);
1092 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1093 dc
.SetPen(m_penHighlight
);
1095 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1098 void wxGTKRenderer::DrawFrame(wxDC
& dc
,
1099 const wxString
& label
,
1105 wxCoord height
= 0; // of the label
1106 wxRect rectFrame
= rect
;
1107 if ( !label
.empty() )
1109 // the text should touch the top border of the rect, so the frame
1110 // itself should be lower
1111 dc
.GetTextExtent(label
, NULL
, &height
);
1112 rectFrame
.y
+= height
/ 2;
1113 rectFrame
.height
-= height
/ 2;
1115 // TODO: the +4 should be customizable
1118 rectText
.x
= rectFrame
.x
+ 4;
1119 rectText
.y
= rect
.y
;
1120 rectText
.width
= rectFrame
.width
- 8;
1121 rectText
.height
= height
;
1124 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1126 rectLabel
.width
+= 2;
1128 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1130 // GTK+ does it like this
1131 dc
.SetPen(m_penHighlight
);
1132 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
1133 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
1137 // just draw the complete frame
1138 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1139 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1143 // ----------------------------------------------------------------------------
1145 // ----------------------------------------------------------------------------
1147 void wxGTKRenderer::DrawLabel(wxDC
& dc
,
1148 const wxString
& label
,
1155 DrawButtonLabel(dc
, label
, wxNullBitmap
, rect
, flags
,
1156 alignment
, indexAccel
, rectBounds
);
1159 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
1160 const wxString
& label
,
1161 const wxBitmap
& image
,
1168 if ( flags
& wxCONTROL_DISABLED
)
1170 // make the text grey and draw a shade for it
1171 dc
.SetTextForeground(*wxWHITE
); // FIXME hardcoded colour
1172 wxRect rectShadow
= rect
;
1175 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1176 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT_DISABLED
));
1179 dc
.DrawLabel(label
, image
, rect
, alignment
, indexAccel
, rectBounds
);
1182 void wxGTKRenderer::DrawItem(wxDC
& dc
,
1183 const wxString
& label
,
1187 wxLogTrace(_T("listbox"), _T("drawing item '%s' at (%d, %d)-(%d, %d)"),
1190 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1193 if ( flags
& wxCONTROL_SELECTED
)
1195 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
), wxSOLID
));
1196 dc
.SetPen(*wxTRANSPARENT_PEN
);
1197 dc
.DrawRectangle(rect
);
1199 colFg
= dc
.GetTextForeground();
1200 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
1203 if ( flags
& wxCONTROL_FOCUSED
)
1205 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1206 wxRect rectFocus
= rect
;
1207 DrawRect(dc
, &rectFocus
, m_penBlack
);
1210 wxRect rectText
= rect
;
1213 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
1215 if ( flags
& wxCONTROL_SELECTED
)
1217 dc
.SetBackgroundMode(wxTRANSPARENT
);
1220 // restore the text colour
1223 dc
.SetTextForeground(colFg
);
1227 void wxGTKRenderer::DrawCheckItem(wxDC
& dc
,
1228 const wxString
& label
,
1229 const wxBitmap
& bitmap
,
1233 wxRect rectBitmap
= rect
;
1235 rectBitmap
.width
= GetCheckBitmapSize().x
;
1236 // never draw the focus rect around the check indicators here
1237 DrawCheckButton(dc
, _T(""), bitmap
, rectBitmap
, flags
& ~wxCONTROL_FOCUSED
);
1239 wxRect rectLabel
= rect
;
1240 wxCoord shift
= rectBitmap
.width
+ 2*GetCheckItemMargin();
1241 rectLabel
.x
+= shift
;
1242 rectLabel
.width
-= shift
;
1243 DrawItem(dc
, label
, rectLabel
, flags
);
1246 // ----------------------------------------------------------------------------
1247 // check/radion buttons
1248 // ----------------------------------------------------------------------------
1250 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1251 const wxRect
& rectTotal
,
1254 wxRect rect
= rectTotal
;
1255 DrawAntiRaisedBorder(dc
, &rect
);
1257 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1258 dc
.SetPen(wxPen(col
, 0, wxSOLID
));
1259 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1262 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1263 //else: it is SHADOW_IN, leave as is
1265 dc
.SetPen(*wxTRANSPARENT_PEN
);
1266 dc
.SetBrush(wxBrush(col
, wxSOLID
));
1267 dc
.DrawRectangle(rect
);
1270 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1272 wxRect rect
= rectTotal
;
1273 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1274 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1276 dc
.SetPen(*wxTRANSPARENT_PEN
);
1277 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), wxSOLID
));
1278 dc
.DrawRectangle(rect
);
1281 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1287 xRight
= rect
.GetRight(),
1288 yBottom
= rect
.GetBottom();
1290 wxCoord yMid
= (y
+ yBottom
) / 2;
1292 // this looks ugly when the background colour of the control is not the
1293 // same ours - radiobox is not transparent as it should be
1295 // first fill the middle: as FloodFill() is not implemented on all
1296 // platforms, this is the only thing to do
1297 wxColour colBg
= flags
& wxCONTROL_CURRENT
1298 ? wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
)
1299 : wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1300 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
1301 dc
.SetPen(*wxTRANSPARENT_PEN
);
1302 dc
.DrawRectangle(rect
);
1305 // then draw the upper half
1306 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1307 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1308 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1311 if ( flags
& wxCONTROL_CHECKED
)
1312 dc
.SetPen(m_penBlack
);
1313 else if ( flags
& wxCONTROL_PRESSED
)
1314 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1315 else // unchecked and unpressed
1319 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1321 // and then the lower one
1322 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1323 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1324 if ( !(flags
& wxCONTROL_CHECKED
) )
1325 dc
.SetPen(m_penDarkGrey
);
1326 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1328 if ( !(flags
& wxCONTROL_CHECKED
) )
1329 drawIt
= TRUE
; // with the same pen
1330 else if ( flags
& wxCONTROL_PRESSED
)
1332 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1335 else // checked and unpressed
1339 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1342 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1348 wxCoord xMid
= (x1
+ x2
) / 2;
1349 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1350 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1353 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1359 wxCoord xMid
= (x1
+ x2
) / 2;
1360 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1361 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1364 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1366 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1368 // init the bitmaps once only
1370 wxSize size
= GetCheckBitmapSize();
1371 rect
.width
= size
.x
;
1372 rect
.height
= size
.y
;
1373 for ( int i
= 0; i
< 2; i
++ )
1375 for ( int j
= 0; j
< 2; j
++ )
1376 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1382 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1383 DrawCheckBitmap(dc
, rect
);
1386 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1387 DrawUncheckBitmap(dc
, rect
, FALSE
);
1390 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1392 // pressed unchecked
1393 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1394 DrawUncheckBitmap(dc
, rect
, TRUE
);
1397 int row
= flags
& wxCONTROL_PRESSED
? 1 : 0;
1398 int col
= flags
& wxCONTROL_CHECKED
? 0 : 1;
1400 return m_bitmapsCheckbox
[row
][col
];
1403 wxBitmap
wxGTKRenderer::GetLineWrapBitmap()
1405 if ( !m_bmpLineWrap
.Ok() )
1407 // the line wrap bitmap as used by GTK+
1408 #define line_wrap_width 6
1409 #define line_wrap_height 9
1410 static const char line_wrap_bits
[] =
1412 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1415 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1416 if ( !bmpLineWrap
.Ok() )
1418 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1422 m_bmpLineWrap
= bmpLineWrap
;
1426 return m_bmpLineWrap
;
1429 void wxGTKRenderer::DrawCheckButton(wxDC
& dc
,
1430 const wxString
& label
,
1431 const wxBitmap
& bitmapOrig
,
1432 const wxRect
& rectTotal
,
1438 if ( bitmapOrig
.Ok() )
1440 bitmap
= bitmapOrig
;
1444 bitmap
= GetCheckBitmap(flags
);
1447 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1448 flags
, align
, indexAccel
);
1451 void wxGTKRenderer::DoDrawCheckOrRadioBitmap(wxDC
& dc
,
1452 const wxString
& label
,
1453 const wxBitmap
& bitmap
,
1454 const wxRect
& rectTotal
,
1459 wxRect rect
= rectTotal
;
1461 if ( flags
& wxCONTROL_FOCUSED
)
1463 // draw the focus border around everything
1464 DrawRect(dc
, &rect
, m_penBlack
);
1468 // the border does not offset the string under GTK
1472 // calculate the position of the bitmap and of the label
1474 yBmp
= rect
.y
+ (rect
.height
- bitmap
.GetHeight()) / 2;
1477 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
1478 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
1480 if ( align
== wxALIGN_RIGHT
)
1482 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
1483 rectLabel
.x
= rect
.x
+ 2;
1484 rectLabel
.SetRight(xBmp
);
1486 else // normal (checkbox to the left of the text) case
1489 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 4;
1490 rectLabel
.SetRight(rect
.GetRight());
1493 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
1495 DrawLabel(dc
, label
, rectLabel
, flags
,
1496 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1499 void wxGTKRenderer::DrawRadioButton(wxDC
& dc
,
1500 const wxString
& label
,
1501 const wxBitmap
& bitmapOrig
,
1502 const wxRect
& rectTotal
,
1508 if ( bitmapOrig
.Ok() )
1510 bitmap
= bitmapOrig
;
1515 wxSize size
= GetRadioBitmapSize();
1516 rect
.width
= size
.x
;
1517 rect
.height
= size
.y
;
1518 bitmap
.Create(rect
.width
, rect
.height
);
1520 dc
.SelectObject(bitmap
);
1521 dc
.SetBackground(*wxLIGHT_GREY_BRUSH
);
1523 DrawRadioBitmap(dc
, rect
, flags
);
1524 bitmap
.SetMask(new wxMask(bitmap
, *wxLIGHT_GREY
));
1527 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1528 flags
, align
, indexAccel
);
1531 // ----------------------------------------------------------------------------
1533 // ----------------------------------------------------------------------------
1535 wxRect
wxGTKRenderer::GetTextTotalArea(const wxTextCtrl
*text
,
1538 wxRect rectTotal
= rect
;
1539 rectTotal
.Inflate(2*BORDER_THICKNESS
);
1543 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1545 wxCoord
*extraSpaceBeyond
)
1547 wxRect rectText
= rect
;
1548 rectText
.Inflate(-2*BORDER_THICKNESS
);
1550 if ( text
->WrapLines() )
1552 // leave enough for the line wrap bitmap indicator
1553 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1555 rectText
.width
-= widthMark
;
1557 if ( extraSpaceBeyond
)
1558 *extraSpaceBeyond
= widthMark
;
1564 void wxGTKRenderer::DrawTextLine(wxDC
& dc
,
1565 const wxString
& text
,
1571 // TODO: GTK+ draws selection even for unfocused controls, just with
1572 // different colours
1573 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
1576 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1578 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1580 // for a mono bitmap he colours it appears in depends on the current text
1581 // colours, so set them correctly
1583 if ( bmpLineWrap
.GetDepth() == 1 )
1585 colFgOld
= dc
.GetTextForeground();
1587 // FIXME: I wonder what should we do if the background is black too?
1588 dc
.SetTextForeground(*wxBLACK
);
1591 dc
.DrawBitmap(bmpLineWrap
,
1592 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1594 if ( colFgOld
.Ok() )
1596 // restore old colour
1597 dc
.SetTextForeground(colFgOld
);
1601 // ----------------------------------------------------------------------------
1603 // ----------------------------------------------------------------------------
1605 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1606 const wxRect
& rectOrig
,
1608 const wxString
& label
,
1609 const wxBitmap
& bitmap
,
1613 wxRect rect
= rectOrig
;
1615 // the current tab is drawn indented (to the top for default case) and
1616 // bigger than the other ones
1617 const wxSize indent
= GetTabIndent();
1618 if ( flags
& wxCONTROL_SELECTED
)
1623 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1627 rect
.Inflate(indent
.x
, 0);
1629 rect
.height
+= indent
.y
;
1633 rect
.Inflate(indent
.x
, 0);
1634 rect
.height
+= indent
.y
;
1639 wxFAIL_MSG(_T("TODO"));
1644 // selected tab has different colour
1645 wxColour col
= flags
& wxCONTROL_SELECTED
1646 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1647 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1648 DoDrawBackground(dc
, col
, rect
);
1650 if ( flags
& wxCONTROL_FOCUSED
)
1652 // draw the focus rect
1653 wxRect rectBorder
= rect
;
1654 rectBorder
.Deflate(4, 3);
1655 if ( dir
== wxBOTTOM
)
1656 rectBorder
.Offset(0, -1);
1658 DrawRect(dc
, &rectBorder
, m_penBlack
);
1661 // draw the text, image and the focus around them (if necessary)
1662 wxRect rectLabel
= rect
;
1663 rectLabel
.Deflate(1, 1);
1664 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1666 // now draw the tab itself
1669 x2
= rect
.GetRight(),
1670 y2
= rect
.GetBottom();
1675 dc
.SetPen(m_penHighlight
);
1676 dc
.DrawLine(x
, y2
, x
, y
);
1677 dc
.DrawLine(x
+ 1, y
, x2
, y
);
1679 dc
.SetPen(m_penBlack
);
1680 dc
.DrawLine(x2
, y2
, x2
, y
);
1682 dc
.SetPen(m_penDarkGrey
);
1683 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ 1);
1685 if ( flags
& wxCONTROL_SELECTED
)
1687 dc
.SetPen(m_penLightGrey
);
1689 // overwrite the part of the border below this tab
1690 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
1692 // and the shadow of the tab to the left of us
1693 dc
.DrawLine(x
+ 1, y
+ 2, x
+ 1, y2
+ 1);
1698 dc
.SetPen(m_penHighlight
);
1700 // we need to continue one pixel further to overwrite the corner of
1701 // the border for the selected tab
1702 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
1705 // it doesn't work like this (TODO: implement it properly)
1707 // erase the corner of the tab to the right
1708 dc
.SetPen(m_penLightGrey
);
1709 dc
.DrawPoint(x2
- 1, y
- 2);
1710 dc
.DrawPoint(x2
- 2, y
- 2);
1711 dc
.DrawPoint(x2
- 2, y
- 1);
1714 dc
.SetPen(m_penBlack
);
1715 dc
.DrawLine(x
+ 1, y2
, x2
, y2
);
1716 dc
.DrawLine(x2
, y
, x2
, y2
);
1718 dc
.SetPen(m_penDarkGrey
);
1719 dc
.DrawLine(x
+ 2, y2
- 1, x2
- 1, y2
- 1);
1720 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
);
1722 if ( flags
& wxCONTROL_SELECTED
)
1724 dc
.SetPen(m_penLightGrey
);
1726 // overwrite the part of the (double!) border above this tab
1727 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
1728 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
1730 // and the shadow of the tab to the left of us
1731 dc
.DrawLine(x
+ 1, y2
- 1, x
+ 1, y
- 1);
1737 wxFAIL_MSG(_T("TODO"));
1741 // ----------------------------------------------------------------------------
1743 // ----------------------------------------------------------------------------
1745 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1746 wxOrientation orient
) const
1748 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1752 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
1753 if ( orient
== wxHORIZONTAL
)
1755 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1756 size
.y
= rectShaft
.height
;
1760 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1761 size
.x
= rectShaft
.width
;
1767 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1768 wxOrientation
WXUNUSED(orient
)) const
1770 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
1773 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
1774 const wxRect
& rectOrig
,
1775 wxOrientation orient
,
1779 wxRect rect
= rectOrig
;
1781 // draw the border first
1782 if ( flags
& wxCONTROL_FOCUSED
)
1784 DrawRect(dc
, &rect
, m_penBlack
);
1785 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1787 else // not focused, normal
1789 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1790 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1793 // and the background
1794 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
1800 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
1801 const wxRect
& rectOrig
,
1802 wxOrientation orient
,
1805 // draw the thumb border
1806 wxRect rect
= rectOrig
;
1807 DrawAntiRaisedBorder(dc
, &rect
);
1809 // draw the handle in the middle
1810 if ( orient
== wxVERTICAL
)
1812 rect
.height
= 2*BORDER_THICKNESS
;
1813 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
1817 rect
.width
= 2*BORDER_THICKNESS
;
1818 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
1821 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1824 // ----------------------------------------------------------------------------
1826 // ----------------------------------------------------------------------------
1828 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
1830 const wxString
& label
,
1834 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE
, indexAccel
);
1837 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
1839 const wxMenuGeometryInfo
& geometryInfo
,
1840 const wxString
& label
,
1841 const wxString
& accel
,
1842 const wxBitmap
& bitmap
,
1846 wxFAIL_MSG(_T("TODO"));
1849 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
1851 const wxMenuGeometryInfo
& geomInfo
)
1853 wxFAIL_MSG(_T("TODO"));
1856 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
1861 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
1862 const wxMenu
& menu
) const
1864 wxFAIL_MSG(_T("TODO"));
1869 // ----------------------------------------------------------------------------
1871 // ----------------------------------------------------------------------------
1873 wxSize
wxGTKRenderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
1875 return wxSize(0, 0);
1878 void wxGTKRenderer::DrawStatusField(wxDC
& dc
,
1880 const wxString
& label
,
1885 // ----------------------------------------------------------------------------
1887 // ----------------------------------------------------------------------------
1889 void wxGTKRenderer::InitComboBitmaps()
1891 wxSize sizeArrow
= m_sizeScrollbarArrow
;
1897 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1899 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
1902 static const int comboButtonFlags
[ComboState_Max
] =
1910 wxRect
rect(wxPoint(0, 0), sizeArrow
);
1913 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1915 int flags
= comboButtonFlags
[n
];
1917 dc
.SelectObject(m_bitmapsCombo
[n
]);
1918 DoDrawBackground(dc
, GetBackgroundColour(flags
), rect
);
1919 DrawArrow(dc
, wxDOWN
, rect
, flags
);
1923 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
1925 wxBitmap
*bmpPressed
,
1926 wxBitmap
*bmpDisabled
)
1928 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
1934 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
1936 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
1938 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
1940 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
1943 // ----------------------------------------------------------------------------
1945 // ----------------------------------------------------------------------------
1947 void wxGTKRenderer::DoDrawBackground(wxDC
& dc
,
1948 const wxColour
& col
,
1951 wxBrush
brush(col
, wxSOLID
);
1953 dc
.SetPen(*wxTRANSPARENT_PEN
);
1954 dc
.DrawRectangle(rect
);
1957 void wxGTKRenderer::DrawBackground(wxDC
& dc
,
1958 const wxColour
& col
,
1962 wxColour colBg
= col
.Ok() ? col
: GetBackgroundColour(flags
);
1963 DoDrawBackground(dc
, colBg
, rect
);
1966 // ----------------------------------------------------------------------------
1968 // ----------------------------------------------------------------------------
1970 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
1974 static const wxDirection sides
[] =
1976 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
1979 wxRect rect1
, rect2
, rectInner
;
1985 rectInner
.Inflate(-2);
1987 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
1989 // find the side not to draw and also adjust the rectangles to compensate
1991 wxDirection sideToOmit
;
1995 sideToOmit
= wxDOWN
;
1997 rectInner
.height
+= 1;
2005 rectInner
.height
+= 1;
2009 sideToOmit
= wxRIGHT
;
2011 rectInner
.width
+= 1;
2015 sideToOmit
= wxLEFT
;
2019 rectInner
.width
+= 1;
2023 wxFAIL_MSG(_T("unknown arrow direction"));
2027 // the outer rect first
2029 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2031 wxDirection side
= sides
[n
];
2032 if ( side
== sideToOmit
)
2035 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
2038 // and then the inner one
2039 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2041 wxDirection side
= sides
[n
];
2042 if ( side
== sideToOmit
)
2045 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
2051 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
2053 const wxRect
& rectArrow
,
2056 // first of all, draw the border around it - but we don't want the border
2057 // on the side opposite to the arrow point
2058 wxRect rect
= rectArrow
;
2059 DrawArrowBorder(dc
, &rect
, dir
);
2061 // then the arrow itself
2062 DrawArrow(dc
, dir
, rect
, flags
);
2065 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
2066 // these people are just crazy :-(
2067 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2080 wxPoint ptArrow
[Point_Max
];
2082 wxColour colInside
= GetBackgroundColour(flags
);
2084 if ( flags
& wxCONTROL_DISABLED
)
2086 penShadow
[0] = m_penDarkGrey
;
2087 penShadow
[1] = m_penDarkGrey
;
2088 penShadow
[2] = wxNullPen
;
2089 penShadow
[3] = wxNullPen
;
2091 else if ( flags
& wxCONTROL_PRESSED
)
2093 penShadow
[0] = m_penDarkGrey
;
2094 penShadow
[1] = m_penHighlight
;
2095 penShadow
[2] = wxNullPen
;
2096 penShadow
[3] = m_penBlack
;
2098 else // normal arrow
2100 penShadow
[0] = m_penHighlight
;
2101 penShadow
[1] = m_penBlack
;
2102 penShadow
[2] = m_penDarkGrey
;
2103 penShadow
[3] = wxNullPen
;
2107 if ( dir
== wxUP
|| dir
== wxDOWN
)
2110 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2114 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2117 // draw the arrow interior
2118 dc
.SetPen(*wxTRANSPARENT_PEN
);
2119 dc
.SetBrush(wxBrush(colInside
, wxSOLID
));
2124 ptArrow
[Point_First
].x
= rect
.GetLeft();
2125 ptArrow
[Point_First
].y
= rect
.GetBottom();
2126 ptArrow
[Point_Second
].x
= middle
;
2127 ptArrow
[Point_Second
].y
= rect
.GetTop();
2128 ptArrow
[Point_Third
].x
= rect
.GetRight();
2129 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2133 ptArrow
[Point_First
] = rect
.GetPosition();
2134 ptArrow
[Point_Second
].x
= middle
;
2135 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2136 ptArrow
[Point_Third
].x
= rect
.GetRight();
2137 ptArrow
[Point_Third
].y
= rect
.GetTop();
2141 ptArrow
[Point_First
].x
= rect
.GetRight();
2142 ptArrow
[Point_First
].y
= rect
.GetTop();
2143 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2144 ptArrow
[Point_Second
].y
= middle
;
2145 ptArrow
[Point_Third
].x
= rect
.GetRight();
2146 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2150 ptArrow
[Point_First
] = rect
.GetPosition();
2151 ptArrow
[Point_Second
].x
= rect
.GetRight();
2152 ptArrow
[Point_Second
].y
= middle
;
2153 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2154 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2158 wxFAIL_MSG(_T("unknown arrow direction"));
2161 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2163 // draw the arrow border
2164 dc
.SetPen(penShadow
[0]);
2168 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2169 dc
.DrawPoint(ptArrow
[Point_First
]);
2170 if ( penShadow
[3].Ok() )
2172 dc
.SetPen(penShadow
[3]);
2173 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2174 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2176 dc
.SetPen(penShadow
[1]);
2177 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2178 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2179 dc
.DrawPoint(ptArrow
[Point_Third
]);
2180 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2181 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2182 if ( penShadow
[2].Ok() )
2184 dc
.SetPen(penShadow
[2]);
2185 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2186 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2187 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2188 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2193 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2194 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2195 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2196 if ( penShadow
[2].Ok() )
2198 dc
.SetPen(penShadow
[2]);
2199 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2200 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2202 dc
.SetPen(penShadow
[1]);
2203 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2204 dc
.DrawPoint(ptArrow
[Point_Third
]);
2208 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2209 dc
.DrawPoint(ptArrow
[Point_First
]);
2210 if ( penShadow
[2].Ok() )
2212 dc
.SetPen(penShadow
[2]);
2213 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2214 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2215 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2216 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2218 dc
.SetPen(penShadow
[1]);
2219 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2220 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2221 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2222 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2226 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2227 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2228 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2229 dc
.SetPen(penShadow
[1]);
2230 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2231 dc
.DrawPoint(ptArrow
[Point_Third
]);
2235 wxFAIL_MSG(_T("unknown arrow direction"));
2240 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2242 wxOrientation orient
)
2244 if ( orient
== wxVERTICAL
)
2246 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2248 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2250 rect
->Inflate(-1, 0);
2252 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2254 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2256 rect
->Inflate(-1, 0);
2260 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2262 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2264 rect
->Inflate(0, -1);
2266 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2268 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2270 rect
->Inflate(0, -1);
2274 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2275 wxOrientation orient
,
2279 // the thumb is never pressed never has focus border under GTK and the
2280 // scrollbar background never changes at all
2281 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2283 // we don't want the border in the direction of the scrollbar movement
2284 wxRect rectThumb
= rect
;
2285 DrawThumbBorder(dc
, &rectThumb
, orient
);
2287 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2288 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2291 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2292 wxOrientation orient
,
2296 wxRect rectBar
= rect
;
2297 DrawThumbBorder(dc
, &rectBar
, orient
);
2298 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2301 void wxGTKRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2303 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2306 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2307 wxScrollBar::Element elem
,
2310 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2311 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2313 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2315 elem
= wxScrollBar::Element_Bar_2
;
2318 return StandardGetScrollbarRect(scrollbar
, elem
,
2320 GetScrollbarArrowSize(scrollbar
));
2323 wxCoord
wxGTKRenderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
2325 return StandardScrollBarSize(scrollbar
, GetScrollbarArrowSize(scrollbar
));
2328 wxHitTest
wxGTKRenderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
2329 const wxPoint
& pt
) const
2331 return StandardHitTestScrollbar(scrollbar
, pt
,
2332 GetScrollbarArrowSize(scrollbar
));
2335 wxCoord
wxGTKRenderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
2338 return StandardScrollbarToPixel(scrollbar
, thumbPos
,
2339 GetScrollbarArrowSize(scrollbar
));
2342 int wxGTKRenderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
2345 return StandardPixelToScrollbar(scrollbar
, coord
,
2346 GetScrollbarArrowSize(scrollbar
));
2349 // ----------------------------------------------------------------------------
2351 // ----------------------------------------------------------------------------
2353 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2356 if ( wxDynamicCast(window
, wxBitmapButton
) )
2361 #endif // wxUSE_BMPBUTTON
2363 if ( wxDynamicCast(window
, wxButton
) )
2365 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2367 // TODO: this is ad hoc...
2368 size
->x
+= 3*window
->GetCharWidth();
2369 wxCoord minBtnHeight
= 18;
2370 if ( size
->y
< minBtnHeight
)
2371 size
->y
= minBtnHeight
;
2373 // button border width
2378 if ( wxDynamicCast(window
, wxScrollBar
) )
2380 // we only set the width of vert scrollbars and height of the
2382 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2383 size
->y
= m_sizeScrollbarArrow
.x
;
2385 size
->x
= m_sizeScrollbarArrow
.x
;
2389 // take into account the border width
2390 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
2391 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
2392 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
2396 // ----------------------------------------------------------------------------
2397 // top level windows
2398 // ----------------------------------------------------------------------------
2400 void wxGTKRenderer::DrawFrameTitleBar(wxDC
& dc
,
2402 const wxString
& title
,
2406 int specialButtonFlag
)
2410 void wxGTKRenderer::DrawFrameBorder(wxDC
& dc
,
2416 void wxGTKRenderer::DrawFrameBackground(wxDC
& dc
,
2422 void wxGTKRenderer::DrawFrameTitle(wxDC
& dc
,
2424 const wxString
& title
,
2429 void wxGTKRenderer::DrawFrameIcon(wxDC
& dc
,
2436 void wxGTKRenderer::DrawFrameButton(wxDC
& dc
,
2437 wxCoord x
, wxCoord y
,
2443 wxRect
wxGTKRenderer::GetFrameClientArea(const wxRect
& rect
, int flags
) const
2448 wxSize
wxGTKRenderer::GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const
2453 wxSize
wxGTKRenderer::GetFrameIconSize() const
2455 return wxSize(-1, -1);
2458 int wxGTKRenderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
2460 return wxHT_TOPLEVEL_CLIENT_AREA
;
2465 // ============================================================================
2467 // ============================================================================
2469 // ----------------------------------------------------------------------------
2470 // wxGTKInputHandler
2471 // ----------------------------------------------------------------------------
2473 wxGTKInputHandler::wxGTKInputHandler(wxGTKRenderer
*renderer
)
2475 m_renderer
= renderer
;
2478 bool wxGTKInputHandler::HandleKey(wxInputConsumer
*control
,
2479 const wxKeyEvent
& event
,
2485 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
2486 const wxMouseEvent
& event
)
2488 // clicking on the control gives it focus
2489 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
2491 control
->GetInputWindow()->SetFocus();
2499 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
2500 const wxMouseEvent
& event
)
2502 if ( event
.Entering() )
2504 control
->GetInputWindow()->SetCurrent(TRUE
);
2506 else if ( event
.Leaving() )
2508 control
->GetInputWindow()->SetCurrent(FALSE
);
2518 // ----------------------------------------------------------------------------
2519 // wxGTKCheckboxInputHandler
2520 // ----------------------------------------------------------------------------
2522 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
2523 const wxKeyEvent
& event
,
2528 int keycode
= event
.GetKeyCode();
2529 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
2531 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
2540 // ----------------------------------------------------------------------------
2541 // wxGTKTextCtrlInputHandler
2542 // ----------------------------------------------------------------------------
2544 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
2545 const wxKeyEvent
& event
,
2548 // handle only GTK-specific text bindings here, the others are handled in
2552 wxControlAction action
;
2553 int keycode
= event
.GetKeyCode();
2554 if ( event
.ControlDown() )
2559 action
= wxACTION_TEXT_HOME
;
2563 action
= wxACTION_TEXT_LEFT
;
2567 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
2571 action
= wxACTION_TEXT_END
;
2575 action
= wxACTION_TEXT_RIGHT
;
2579 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
2583 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2587 action
= wxACTION_TEXT_DOWN
;
2591 action
= wxACTION_TEXT_UP
;
2595 //delete the entire line
2596 control
->PerformAction(wxACTION_TEXT_HOME
);
2597 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2601 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
2605 else if ( event
.AltDown() )
2610 action
= wxACTION_TEXT_WORD_LEFT
;
2614 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
2618 action
= wxACTION_TEXT_WORD_RIGHT
;
2623 if ( action
!= wxACTION_NONE
)
2625 control
->PerformAction(action
);
2631 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);