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
192 virtual void DrawMenuBarItem(wxDC
& dc
,
194 const wxString
& label
,
196 int indexAccel
= -1);
197 virtual void DrawMenuItem(wxDC
& dc
,
199 const wxMenuGeometryInfo
& geometryInfo
,
200 const wxString
& label
,
201 const wxString
& accel
,
202 const wxBitmap
& bitmap
= wxNullBitmap
,
204 int indexAccel
= -1);
205 virtual void DrawMenuSeparator(wxDC
& dc
,
207 const wxMenuGeometryInfo
& geomInfo
);
210 virtual void DrawFrameTitleBar(wxDC
& dc
,
212 const wxString
& title
,
215 int specialButton
= 0,
216 int specialButtonFlag
= 0);
217 virtual void DrawFrameBorder(wxDC
& dc
,
220 virtual void DrawFrameBackground(wxDC
& dc
,
223 virtual void DrawFrameTitle(wxDC
& dc
,
225 const wxString
& title
,
227 virtual void DrawFrameIcon(wxDC
& dc
,
231 virtual void DrawFrameButton(wxDC
& dc
,
232 wxCoord x
, wxCoord y
,
237 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
238 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
239 virtual wxSize
GetFrameIconSize() const;
240 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
242 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
244 wxBitmap
*bmpPressed
,
245 wxBitmap
*bmpDisabled
);
247 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
248 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
249 virtual bool AreScrollbarsInsideBorder() const;
251 // geometry and hit testing
252 virtual wxSize
GetScrollbarArrowSize() const
253 { return m_sizeScrollbarArrow
; }
254 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
255 wxScrollBar::Element elem
,
256 int thumbPos
= -1) const;
257 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
258 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
259 const wxPoint
& pt
) const;
260 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
262 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
263 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
264 { return fontHeight
+ 2; }
265 virtual wxSize
GetCheckBitmapSize() const
266 { return wxSize(10, 10); }
267 virtual wxSize
GetRadioBitmapSize() const
268 { return wxSize(11, 11); }
269 virtual wxCoord
GetCheckItemMargin() const
272 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
274 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
276 wxCoord
*extraSpaceBeyond
);
278 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
279 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
281 virtual wxCoord
GetSliderDim() const { return 15; }
282 virtual wxCoord
GetSliderTickLen() const { return 0; }
283 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
284 wxOrientation orient
) const;
285 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
286 wxOrientation orient
) const;
287 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
290 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
291 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
292 const wxMenu
& menu
) const;
294 // helpers for "wxBitmap wxColourScheme::Get()"
295 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
296 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
299 // DrawBackground() helpers
301 // get the colour to use for background
302 wxColour
GetBackgroundColour(int flags
) const
304 if ( flags
& wxCONTROL_PRESSED
)
305 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
306 else if ( flags
& wxCONTROL_CURRENT
)
307 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
309 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
312 // draw the background with any colour, not only the default one(s)
313 void DoDrawBackground(wxDC
& dc
,
317 // DrawBorder() helpers: all of them shift and clip the DC after drawing
320 // just draw a rectangle with the given pen
321 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
323 // draw the lower left part of rectangle
324 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
326 // draw the rectange using the first brush for the left and top sides and
327 // the second one for the bottom and right ones
328 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
329 const wxPen
& pen1
, const wxPen
& pen2
);
331 // as DrawShadedRect() but the pixels in the bottom left and upper right
332 // border are drawn with the pen1, not pen2
333 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
334 const wxPen
& pen1
, const wxPen
& pen2
);
336 // used for drawing opened rectangles - draws only one side of it at once
337 // (and doesn't adjust the rect)
338 void DrawAntiShadedRectSide(wxDC
& dc
,
344 // draw an opened rect for the arrow in given direction
345 void DrawArrowBorder(wxDC
& dc
,
349 // draw two sides of the rectangle
350 void DrawThumbBorder(wxDC
& dc
,
352 wxOrientation orient
);
354 // draw the normal 3D border
355 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
357 // just as DrawRaisedBorder() except that the bottom left and up right
358 // pixels of the interior rect are drawn in another colour (i.e. the inner
359 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
360 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
362 // returns the size of the arrow for the scrollbar (depends on
364 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
367 if ( scrollbar
->IsVertical() )
369 size
= m_sizeScrollbarArrow
;
373 size
.x
= m_sizeScrollbarArrow
.y
;
374 size
.y
= m_sizeScrollbarArrow
.x
;
380 // get the line wrap indicator bitmap
381 wxBitmap
GetLineWrapBitmap();
383 // DrawCheckBitmap and DrawRadioBitmap helpers
385 // draw the check bitmaps once and cache them for later use
386 wxBitmap
GetCheckBitmap(int flags
);
388 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
390 void DrawUpZag(wxDC
& dc
,
391 wxCoord x1
, wxCoord x2
,
392 wxCoord y1
, wxCoord y2
);
393 void DrawDownZag(wxDC
& dc
,
394 wxCoord x1
, wxCoord x2
,
395 wxCoord y1
, wxCoord y2
);
397 // draw the radio button bitmap for the given state
398 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
400 // draw check/radio - the bitmap must be a valid one by now
401 void DoDrawCheckOrRadioBitmap(wxDC
& dc
,
402 const wxString
& label
,
403 const wxBitmap
& bitmap
,
404 const wxRect
& rectTotal
,
409 // initialize the combo bitmaps
410 void InitComboBitmaps();
413 const wxColourScheme
*m_scheme
;
416 wxSize m_sizeScrollbarArrow
;
425 // the checkbox bitmaps: first row is for the normal, second for the
426 // pressed state and the columns are for checked and unchecked status
428 wxBitmap m_bitmapsCheckbox
[2][2];
430 // the line wrap bitmap (drawn at the end of wrapped lines)
431 wxBitmap m_bmpLineWrap
;
433 // the combobox bitmaps
443 wxBitmap m_bitmapsCombo
[ComboState_Max
];
446 // ----------------------------------------------------------------------------
447 // wxGTKInputHandler and derived classes: process the keyboard and mouse
448 // messages according to GTK standards
449 // ----------------------------------------------------------------------------
451 class wxGTKInputHandler
: public wxInputHandler
454 wxGTKInputHandler(wxGTKRenderer
*renderer
);
456 virtual bool HandleKey(wxInputConsumer
*control
,
457 const wxKeyEvent
& event
,
459 virtual bool HandleMouse(wxInputConsumer
*control
,
460 const wxMouseEvent
& event
);
461 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
464 wxGTKRenderer
*m_renderer
;
467 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
470 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
471 : wxStdScrollBarInputHandler(renderer
, handler
) { }
474 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
476 // only arrows and the thumb can be highlighted
477 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
480 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
483 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
485 // only arrows can be pressed
489 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
492 virtual bool IsAllowedButton(int WXUNUSED(button
)) { return TRUE
; }
496 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
497 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
501 class wxGTKCheckboxInputHandler
: public wxStdCheckboxInputHandler
504 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
505 : wxStdCheckboxInputHandler(handler
) { }
507 virtual bool HandleKey(wxInputConsumer
*control
,
508 const wxKeyEvent
& event
,
512 class wxGTKTextCtrlInputHandler
: public wxStdTextCtrlInputHandler
515 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
516 : wxStdTextCtrlInputHandler(handler
) { }
518 virtual bool HandleKey(wxInputConsumer
*control
,
519 const wxKeyEvent
& event
,
523 // ----------------------------------------------------------------------------
524 // wxGTKColourScheme: uses the standard GTK colours
525 // ----------------------------------------------------------------------------
527 class wxGTKColourScheme
: public wxColourScheme
530 virtual wxColour
Get(StdColour col
) const;
531 virtual wxColour
GetBackground(wxWindow
*win
) const;
534 // ----------------------------------------------------------------------------
536 // ----------------------------------------------------------------------------
538 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
540 class wxGTKTheme
: public wxTheme
544 virtual ~wxGTKTheme();
546 virtual wxRenderer
*GetRenderer() { return m_renderer
; }
547 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
548 virtual wxColourScheme
*GetColourScheme() { return m_scheme
; }
551 // get the default input handler
552 wxInputHandler
*GetDefaultInputHandler();
554 wxGTKRenderer
*m_renderer
;
556 // the names of the already created handlers and the handlers themselves
557 // (these arrays are synchronized)
558 wxSortedArrayString m_handlerNames
;
559 wxArrayHandlers m_handlers
;
561 wxGTKInputHandler
*m_handlerDefault
;
563 wxGTKColourScheme
*m_scheme
;
565 WX_DECLARE_THEME(gtk
)
568 // ============================================================================
570 // ============================================================================
572 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
574 // ----------------------------------------------------------------------------
576 // ----------------------------------------------------------------------------
578 wxGTKTheme::wxGTKTheme()
580 m_scheme
= new wxGTKColourScheme
;
581 m_renderer
= new wxGTKRenderer(m_scheme
);
582 m_handlerDefault
= NULL
;
585 wxGTKTheme::~wxGTKTheme()
587 size_t count
= m_handlers
.GetCount();
588 for ( size_t n
= 0; n
< count
; n
++ )
590 if ( m_handlers
[n
] != m_handlerDefault
)
591 delete m_handlers
[n
];
594 delete m_handlerDefault
;
599 wxInputHandler
*wxGTKTheme::GetDefaultInputHandler()
601 if ( !m_handlerDefault
)
603 m_handlerDefault
= new wxGTKInputHandler(m_renderer
);
606 return m_handlerDefault
;
609 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
)
611 wxInputHandler
*handler
;
612 int n
= m_handlerNames
.Index(control
);
613 if ( n
== wxNOT_FOUND
)
615 // create a new handler
616 if ( control
== wxINP_HANDLER_SCROLLBAR
)
617 handler
= new wxGTKScrollBarInputHandler(m_renderer
,
618 GetDefaultInputHandler());
620 else if ( control
== wxINP_HANDLER_BUTTON
)
621 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
622 #endif // wxUSE_CHECKBOX
624 else if ( control
== wxINP_HANDLER_CHECKBOX
)
625 handler
= new wxGTKCheckboxInputHandler(GetDefaultInputHandler());
626 #endif // wxUSE_CHECKBOX
628 else if ( control
== wxINP_HANDLER_COMBOBOX
)
629 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
630 #endif // wxUSE_COMBOBOX
632 else if ( control
== wxINP_HANDLER_LISTBOX
)
633 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
634 #endif // wxUSE_LISTBOX
635 #if wxUSE_CHECKLISTBOX
636 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
637 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
638 #endif // wxUSE_CHECKLISTBOX
640 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
641 handler
= new wxGTKTextCtrlInputHandler(GetDefaultInputHandler());
642 #endif // wxUSE_TEXTCTRL
644 else if ( control
== wxINP_HANDLER_SLIDER
)
645 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
646 #endif // wxUSE_SLIDER
648 else if ( control
== wxINP_HANDLER_SPINBTN
)
649 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
650 #endif // wxUSE_SPINBTN
652 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
653 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
654 #endif // wxUSE_NOTEBOOK
655 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
656 handler
= new wxStdFrameInputHandler(GetDefaultInputHandler());
658 handler
= GetDefaultInputHandler();
660 n
= m_handlerNames
.Add(control
);
661 m_handlers
.Insert(handler
, n
);
663 else // we already have it
665 handler
= m_handlers
[n
];
671 // ============================================================================
673 // ============================================================================
675 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
678 if ( win
->UseBgCol() )
680 // use the user specified colour
681 col
= win
->GetBackgroundColour();
684 if ( win
->IsContainerWindow() )
686 // doesn't depend on the state
694 int flags
= win
->GetStateFlags();
696 // the colour set by the user should be used for the normal state
697 // and for the states for which we don't have any specific colours
698 if ( !col
.Ok() || (flags
!= 0) )
700 if ( wxDynamicCast(win
, wxScrollBar
) )
701 col
= Get(SCROLLBAR
);
702 else if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
703 col
= Get(CONTROL_CURRENT
);
704 else if ( flags
& wxCONTROL_PRESSED
)
705 col
= Get(CONTROL_PRESSED
);
714 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
718 case WINDOW
: return *wxWHITE
;
720 case SHADOW_DARK
: return *wxBLACK
;
721 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
722 case SHADOW_IN
: return wxColour(0xd6d6d6);
723 case SHADOW_OUT
: return wxColour(0x969696);
725 case CONTROL
: return wxColour(0xd6d6d6);
726 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
727 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
729 case CONTROL_TEXT
: return *wxBLACK
;
730 case CONTROL_TEXT_DISABLED
:
731 return wxColour(0x757575);
732 case CONTROL_TEXT_DISABLED_SHADOW
:
736 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
738 case HIGHLIGHT
: return wxColour(0x9c0000);
739 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
743 wxFAIL_MSG(_T("invalid standard colour"));
748 // ============================================================================
750 // ============================================================================
752 // ----------------------------------------------------------------------------
754 // ----------------------------------------------------------------------------
756 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
760 m_sizeScrollbarArrow
= wxSize(15, 14);
763 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
764 m_penDarkGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_OUT
), 0, wxSOLID
);
765 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
), 0, wxSOLID
);
766 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
767 m_penHighlight
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
), 0, wxSOLID
);
770 // ----------------------------------------------------------------------------
772 // ----------------------------------------------------------------------------
774 void wxGTKRenderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
778 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
779 dc
.DrawRectangle(*rect
);
785 void wxGTKRenderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
787 // draw the bottom and right sides
789 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
790 rect
->GetRight() + 1, rect
->GetBottom());
791 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
792 rect
->GetRight(), rect
->GetBottom());
799 void wxGTKRenderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
800 const wxPen
& pen1
, const wxPen
& pen2
)
802 // draw the rectangle
804 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
805 rect
->GetLeft(), rect
->GetBottom());
806 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
807 rect
->GetRight(), rect
->GetTop());
809 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
810 rect
->GetRight(), rect
->GetBottom());
811 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
812 rect
->GetRight() + 1, rect
->GetBottom());
818 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
824 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
829 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
830 rect
.GetLeft(), rect
.GetBottom() + 1);
834 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
835 rect
.GetRight() + 1, rect
.GetTop());
839 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
840 rect
.GetRight(), rect
.GetBottom() + 1);
844 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
845 rect
.GetRight() + 1, rect
.GetBottom());
849 wxFAIL_MSG(_T("unknown rectangle side"));
853 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
854 const wxPen
& pen1
, const wxPen
& pen2
)
856 // draw the rectangle
858 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
859 rect
->GetLeft(), rect
->GetBottom() + 1);
860 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
861 rect
->GetRight() + 1, rect
->GetTop());
863 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
864 rect
->GetRight(), rect
->GetBottom());
865 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
866 rect
->GetRight() + 1, rect
->GetBottom());
872 void wxGTKRenderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
874 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
875 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
878 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
880 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
881 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
884 void wxGTKRenderer::DrawBorder(wxDC
& dc
,
886 const wxRect
& rectTotal
,
892 wxRect rect
= rectTotal
;
896 case wxBORDER_SUNKEN
:
897 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
899 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
900 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
904 case wxBORDER_STATIC
:
905 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
907 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
911 case wxBORDER_RAISED
:
912 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
914 DrawRaisedBorder(dc
, &rect
);
918 case wxBORDER_DOUBLE
:
919 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
921 DrawShadedRect(dc
, &rect
, m_penLightGrey
, m_penBlack
);
922 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penDarkGrey
);
923 DrawRect(dc
, &rect
, m_penLightGrey
);
927 case wxBORDER_SIMPLE
:
928 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
930 DrawRect(dc
, &rect
, m_penBlack
);
935 wxFAIL_MSG(_T("unknown border type"));
938 case wxBORDER_DEFAULT
:
947 wxRect
wxGTKRenderer::GetBorderDimensions(wxBorder border
) const
952 case wxBORDER_RAISED
:
953 case wxBORDER_SUNKEN
:
954 width
= 2*BORDER_THICKNESS
;
957 case wxBORDER_SIMPLE
:
958 case wxBORDER_STATIC
:
959 width
= BORDER_THICKNESS
;
962 case wxBORDER_DOUBLE
:
963 width
= 3*BORDER_THICKNESS
;
967 wxFAIL_MSG(_T("unknown border type"));
970 case wxBORDER_DEFAULT
:
985 bool wxGTKRenderer::AreScrollbarsInsideBorder() const
987 // no, the scrollbars are outside the border in GTK+
991 // ----------------------------------------------------------------------------
993 // ----------------------------------------------------------------------------
995 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
997 const wxRect
& rectOrig
,
1001 wxRect rect
= rectOrig
;
1003 if ( border
!= wxBORDER_NONE
)
1005 if ( flags
& wxCONTROL_FOCUSED
)
1007 DrawRect(dc
, &rect
, m_penBlack
);
1008 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1012 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1013 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penHighlight
);
1021 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
1022 const wxRect
& rectTotal
,
1026 wxRect rect
= rectTotal
;
1028 if ( flags
& wxCONTROL_PRESSED
)
1030 // button pressed: draw a black border around it and an inward shade
1031 DrawRect(dc
, &rect
, m_penBlack
);
1033 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1035 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1036 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penDarkGrey
);
1041 // button not pressed
1043 if ( flags
& wxCONTROL_ISDEFAULT
)
1048 if ( flags
& wxCONTROL_FOCUSED
)
1050 // button is currently default: add an extra border around it
1051 DrawRect(dc
, &rect
, m_penBlack
);
1054 // now draw a normal button
1055 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1057 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1058 DrawAntiShadedRect(dc
, &rect
,
1059 wxPen(GetBackgroundColour(flags
), 0, wxSOLID
),
1070 // ----------------------------------------------------------------------------
1072 // ----------------------------------------------------------------------------
1074 void wxGTKRenderer::DrawHorizontalLine(wxDC
& dc
,
1075 wxCoord y
, wxCoord x1
, wxCoord x2
)
1077 dc
.SetPen(m_penDarkGrey
);
1078 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1079 dc
.SetPen(m_penHighlight
);
1081 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1084 void wxGTKRenderer::DrawVerticalLine(wxDC
& dc
,
1085 wxCoord x
, wxCoord y1
, wxCoord y2
)
1087 dc
.SetPen(m_penDarkGrey
);
1088 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1089 dc
.SetPen(m_penHighlight
);
1091 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1094 void wxGTKRenderer::DrawFrame(wxDC
& dc
,
1095 const wxString
& label
,
1101 wxCoord height
= 0; // of the label
1102 wxRect rectFrame
= rect
;
1103 if ( !label
.empty() )
1105 // the text should touch the top border of the rect, so the frame
1106 // itself should be lower
1107 dc
.GetTextExtent(label
, NULL
, &height
);
1108 rectFrame
.y
+= height
/ 2;
1109 rectFrame
.height
-= height
/ 2;
1111 // TODO: the +4 should be customizable
1114 rectText
.x
= rectFrame
.x
+ 4;
1115 rectText
.y
= rect
.y
;
1116 rectText
.width
= rectFrame
.width
- 8;
1117 rectText
.height
= height
;
1120 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1122 rectLabel
.width
+= 2;
1124 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1126 // GTK+ does it like this
1127 dc
.SetPen(m_penHighlight
);
1128 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
1129 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
1133 // just draw the complete frame
1134 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1135 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1139 // ----------------------------------------------------------------------------
1141 // ----------------------------------------------------------------------------
1143 void wxGTKRenderer::DrawLabel(wxDC
& dc
,
1144 const wxString
& label
,
1151 DrawButtonLabel(dc
, label
, wxNullBitmap
, rect
, flags
,
1152 alignment
, indexAccel
, rectBounds
);
1155 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
1156 const wxString
& label
,
1157 const wxBitmap
& image
,
1164 if ( flags
& wxCONTROL_DISABLED
)
1166 // make the text grey and draw a shade for it
1167 dc
.SetTextForeground(*wxWHITE
); // FIXME hardcoded colour
1168 wxRect rectShadow
= rect
;
1171 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1172 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT_DISABLED
));
1175 dc
.DrawLabel(label
, image
, rect
, alignment
, indexAccel
, rectBounds
);
1178 void wxGTKRenderer::DrawItem(wxDC
& dc
,
1179 const wxString
& label
,
1183 wxLogTrace(_T("listbox"), _T("drawing item '%s' at (%d, %d)-(%d, %d)"),
1186 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1189 if ( flags
& wxCONTROL_SELECTED
)
1191 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
), wxSOLID
));
1192 dc
.SetPen(*wxTRANSPARENT_PEN
);
1193 dc
.DrawRectangle(rect
);
1195 colFg
= dc
.GetTextForeground();
1196 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
1199 if ( flags
& wxCONTROL_FOCUSED
)
1201 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1202 wxRect rectFocus
= rect
;
1203 DrawRect(dc
, &rectFocus
, m_penBlack
);
1206 wxRect rectText
= rect
;
1209 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
1211 if ( flags
& wxCONTROL_SELECTED
)
1213 dc
.SetBackgroundMode(wxTRANSPARENT
);
1216 // restore the text colour
1219 dc
.SetTextForeground(colFg
);
1223 void wxGTKRenderer::DrawCheckItem(wxDC
& dc
,
1224 const wxString
& label
,
1225 const wxBitmap
& bitmap
,
1229 wxRect rectBitmap
= rect
;
1231 rectBitmap
.width
= GetCheckBitmapSize().x
;
1232 // never draw the focus rect around the check indicators here
1233 DrawCheckButton(dc
, _T(""), bitmap
, rectBitmap
, flags
& ~wxCONTROL_FOCUSED
);
1235 wxRect rectLabel
= rect
;
1236 wxCoord shift
= rectBitmap
.width
+ 2*GetCheckItemMargin();
1237 rectLabel
.x
+= shift
;
1238 rectLabel
.width
-= shift
;
1239 DrawItem(dc
, label
, rectLabel
, flags
);
1242 // ----------------------------------------------------------------------------
1243 // check/radion buttons
1244 // ----------------------------------------------------------------------------
1246 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1247 const wxRect
& rectTotal
,
1250 wxRect rect
= rectTotal
;
1251 DrawAntiRaisedBorder(dc
, &rect
);
1253 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1254 dc
.SetPen(wxPen(col
, 0, wxSOLID
));
1255 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1258 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1259 //else: it is SHADOW_IN, leave as is
1261 dc
.SetPen(*wxTRANSPARENT_PEN
);
1262 dc
.SetBrush(wxBrush(col
, wxSOLID
));
1263 dc
.DrawRectangle(rect
);
1266 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1268 wxRect rect
= rectTotal
;
1269 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1270 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1272 dc
.SetPen(*wxTRANSPARENT_PEN
);
1273 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), wxSOLID
));
1274 dc
.DrawRectangle(rect
);
1277 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1283 xRight
= rect
.GetRight(),
1284 yBottom
= rect
.GetBottom();
1286 wxCoord yMid
= (y
+ yBottom
) / 2;
1288 // this looks ugly when the background colour of the control is not the
1289 // same ours - radiobox is not transparent as it should be
1291 // first fill the middle: as FloodFill() is not implemented on all
1292 // platforms, this is the only thing to do
1293 wxColour colBg
= flags
& wxCONTROL_CURRENT
1294 ? wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
)
1295 : wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1296 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
1297 dc
.SetPen(*wxTRANSPARENT_PEN
);
1298 dc
.DrawRectangle(rect
);
1301 // then draw the upper half
1302 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1303 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1304 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1307 if ( flags
& wxCONTROL_CHECKED
)
1308 dc
.SetPen(m_penBlack
);
1309 else if ( flags
& wxCONTROL_PRESSED
)
1310 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1311 else // unchecked and unpressed
1315 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1317 // and then the lower one
1318 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1319 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1320 if ( !(flags
& wxCONTROL_CHECKED
) )
1321 dc
.SetPen(m_penDarkGrey
);
1322 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1324 if ( !(flags
& wxCONTROL_CHECKED
) )
1325 drawIt
= TRUE
; // with the same pen
1326 else if ( flags
& wxCONTROL_PRESSED
)
1328 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1331 else // checked and unpressed
1335 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1338 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1344 wxCoord xMid
= (x1
+ x2
) / 2;
1345 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1346 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1349 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1355 wxCoord xMid
= (x1
+ x2
) / 2;
1356 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1357 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1360 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1362 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1364 // init the bitmaps once only
1366 wxSize size
= GetCheckBitmapSize();
1367 rect
.width
= size
.x
;
1368 rect
.height
= size
.y
;
1369 for ( int i
= 0; i
< 2; i
++ )
1371 for ( int j
= 0; j
< 2; j
++ )
1372 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1378 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1379 DrawCheckBitmap(dc
, rect
);
1382 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1383 DrawUncheckBitmap(dc
, rect
, FALSE
);
1386 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1388 // pressed unchecked
1389 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1390 DrawUncheckBitmap(dc
, rect
, TRUE
);
1393 int row
= flags
& wxCONTROL_PRESSED
? 1 : 0;
1394 int col
= flags
& wxCONTROL_CHECKED
? 0 : 1;
1396 return m_bitmapsCheckbox
[row
][col
];
1399 wxBitmap
wxGTKRenderer::GetLineWrapBitmap()
1401 if ( !m_bmpLineWrap
.Ok() )
1403 // the line wrap bitmap as used by GTK+
1404 #define line_wrap_width 6
1405 #define line_wrap_height 9
1406 static const char line_wrap_bits
[] =
1408 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1411 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1412 if ( !bmpLineWrap
.Ok() )
1414 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1418 m_bmpLineWrap
= bmpLineWrap
;
1422 return m_bmpLineWrap
;
1425 void wxGTKRenderer::DrawCheckButton(wxDC
& dc
,
1426 const wxString
& label
,
1427 const wxBitmap
& bitmapOrig
,
1428 const wxRect
& rectTotal
,
1434 if ( bitmapOrig
.Ok() )
1436 bitmap
= bitmapOrig
;
1440 bitmap
= GetCheckBitmap(flags
);
1443 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1444 flags
, align
, indexAccel
);
1447 void wxGTKRenderer::DoDrawCheckOrRadioBitmap(wxDC
& dc
,
1448 const wxString
& label
,
1449 const wxBitmap
& bitmap
,
1450 const wxRect
& rectTotal
,
1455 wxRect rect
= rectTotal
;
1457 if ( flags
& wxCONTROL_FOCUSED
)
1459 // draw the focus border around everything
1460 DrawRect(dc
, &rect
, m_penBlack
);
1464 // the border does not offset the string under GTK
1468 // calculate the position of the bitmap and of the label
1470 yBmp
= rect
.y
+ (rect
.height
- bitmap
.GetHeight()) / 2;
1473 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
1474 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
1476 if ( align
== wxALIGN_RIGHT
)
1478 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
1479 rectLabel
.x
= rect
.x
+ 2;
1480 rectLabel
.SetRight(xBmp
);
1482 else // normal (checkbox to the left of the text) case
1485 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 4;
1486 rectLabel
.SetRight(rect
.GetRight());
1489 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
1491 DrawLabel(dc
, label
, rectLabel
, flags
,
1492 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1495 void wxGTKRenderer::DrawRadioButton(wxDC
& dc
,
1496 const wxString
& label
,
1497 const wxBitmap
& bitmapOrig
,
1498 const wxRect
& rectTotal
,
1504 if ( bitmapOrig
.Ok() )
1506 bitmap
= bitmapOrig
;
1511 wxSize size
= GetRadioBitmapSize();
1512 rect
.width
= size
.x
;
1513 rect
.height
= size
.y
;
1514 bitmap
.Create(rect
.width
, rect
.height
);
1516 dc
.SelectObject(bitmap
);
1517 dc
.SetBackground(*wxLIGHT_GREY_BRUSH
);
1519 DrawRadioBitmap(dc
, rect
, flags
);
1520 bitmap
.SetMask(new wxMask(bitmap
, *wxLIGHT_GREY
));
1523 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1524 flags
, align
, indexAccel
);
1527 // ----------------------------------------------------------------------------
1529 // ----------------------------------------------------------------------------
1531 wxRect
wxGTKRenderer::GetTextTotalArea(const wxTextCtrl
*text
,
1534 wxRect rectTotal
= rect
;
1535 rectTotal
.Inflate(2*BORDER_THICKNESS
);
1539 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1541 wxCoord
*extraSpaceBeyond
)
1543 wxRect rectText
= rect
;
1544 rectText
.Inflate(-2*BORDER_THICKNESS
);
1546 if ( text
->WrapLines() )
1548 // leave enough for the line wrap bitmap indicator
1549 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1551 rectText
.width
-= widthMark
;
1553 if ( extraSpaceBeyond
)
1554 *extraSpaceBeyond
= widthMark
;
1560 void wxGTKRenderer::DrawTextLine(wxDC
& dc
,
1561 const wxString
& text
,
1567 // TODO: GTK+ draws selection even for unfocused controls, just with
1568 // different colours
1569 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
1572 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1574 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1576 // for a mono bitmap he colours it appears in depends on the current text
1577 // colours, so set them correctly
1579 if ( bmpLineWrap
.GetDepth() == 1 )
1581 colFgOld
= dc
.GetTextForeground();
1583 // FIXME: I wonder what should we do if the background is black too?
1584 dc
.SetTextForeground(*wxBLACK
);
1587 dc
.DrawBitmap(bmpLineWrap
,
1588 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1590 if ( colFgOld
.Ok() )
1592 // restore old colour
1593 dc
.SetTextForeground(colFgOld
);
1597 // ----------------------------------------------------------------------------
1599 // ----------------------------------------------------------------------------
1601 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1602 const wxRect
& rectOrig
,
1604 const wxString
& label
,
1605 const wxBitmap
& bitmap
,
1609 wxRect rect
= rectOrig
;
1611 // the current tab is drawn indented (to the top for default case) and
1612 // bigger than the other ones
1613 const wxSize indent
= GetTabIndent();
1614 if ( flags
& wxCONTROL_SELECTED
)
1619 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1623 rect
.Inflate(indent
.x
, 0);
1625 rect
.height
+= indent
.y
;
1629 rect
.Inflate(indent
.x
, 0);
1630 rect
.height
+= indent
.y
;
1635 wxFAIL_MSG(_T("TODO"));
1640 // selected tab has different colour
1641 wxColour col
= flags
& wxCONTROL_SELECTED
1642 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1643 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1644 DoDrawBackground(dc
, col
, rect
);
1646 if ( flags
& wxCONTROL_FOCUSED
)
1648 // draw the focus rect
1649 wxRect rectBorder
= rect
;
1650 rectBorder
.Deflate(4, 3);
1651 if ( dir
== wxBOTTOM
)
1652 rectBorder
.Offset(0, -1);
1654 DrawRect(dc
, &rectBorder
, m_penBlack
);
1657 // draw the text, image and the focus around them (if necessary)
1658 wxRect rectLabel
= rect
;
1659 rectLabel
.Deflate(1, 1);
1660 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1662 // now draw the tab itself
1665 x2
= rect
.GetRight(),
1666 y2
= rect
.GetBottom();
1671 dc
.SetPen(m_penHighlight
);
1672 dc
.DrawLine(x
, y2
, x
, y
);
1673 dc
.DrawLine(x
+ 1, y
, x2
, y
);
1675 dc
.SetPen(m_penBlack
);
1676 dc
.DrawLine(x2
, y2
, x2
, y
);
1678 dc
.SetPen(m_penDarkGrey
);
1679 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ 1);
1681 if ( flags
& wxCONTROL_SELECTED
)
1683 dc
.SetPen(m_penLightGrey
);
1685 // overwrite the part of the border below this tab
1686 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
1688 // and the shadow of the tab to the left of us
1689 dc
.DrawLine(x
+ 1, y
+ 2, x
+ 1, y2
+ 1);
1694 dc
.SetPen(m_penHighlight
);
1696 // we need to continue one pixel further to overwrite the corner of
1697 // the border for the selected tab
1698 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
1701 // it doesn't work like this (TODO: implement it properly)
1703 // erase the corner of the tab to the right
1704 dc
.SetPen(m_penLightGrey
);
1705 dc
.DrawPoint(x2
- 1, y
- 2);
1706 dc
.DrawPoint(x2
- 2, y
- 2);
1707 dc
.DrawPoint(x2
- 2, y
- 1);
1710 dc
.SetPen(m_penBlack
);
1711 dc
.DrawLine(x
+ 1, y2
, x2
, y2
);
1712 dc
.DrawLine(x2
, y
, x2
, y2
);
1714 dc
.SetPen(m_penDarkGrey
);
1715 dc
.DrawLine(x
+ 2, y2
- 1, x2
- 1, y2
- 1);
1716 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
);
1718 if ( flags
& wxCONTROL_SELECTED
)
1720 dc
.SetPen(m_penLightGrey
);
1722 // overwrite the part of the (double!) border above this tab
1723 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
1724 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
1726 // and the shadow of the tab to the left of us
1727 dc
.DrawLine(x
+ 1, y2
- 1, x
+ 1, y
- 1);
1733 wxFAIL_MSG(_T("TODO"));
1737 // ----------------------------------------------------------------------------
1739 // ----------------------------------------------------------------------------
1741 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1742 wxOrientation orient
) const
1744 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1748 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
1749 if ( orient
== wxHORIZONTAL
)
1751 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1752 size
.y
= rectShaft
.height
;
1756 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1757 size
.x
= rectShaft
.width
;
1763 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1764 wxOrientation
WXUNUSED(orient
)) const
1766 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
1769 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
1770 const wxRect
& rectOrig
,
1771 wxOrientation orient
,
1775 wxRect rect
= rectOrig
;
1777 // draw the border first
1778 if ( flags
& wxCONTROL_FOCUSED
)
1780 DrawRect(dc
, &rect
, m_penBlack
);
1781 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1783 else // not focused, normal
1785 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1786 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1789 // and the background
1790 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
1796 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
1797 const wxRect
& rectOrig
,
1798 wxOrientation orient
,
1801 // draw the thumb border
1802 wxRect rect
= rectOrig
;
1803 DrawAntiRaisedBorder(dc
, &rect
);
1805 // draw the handle in the middle
1806 if ( orient
== wxVERTICAL
)
1808 rect
.height
= 2*BORDER_THICKNESS
;
1809 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
1813 rect
.width
= 2*BORDER_THICKNESS
;
1814 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
1817 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1821 // ----------------------------------------------------------------------------
1823 // ----------------------------------------------------------------------------
1825 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
1827 const wxString
& label
,
1831 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE
, indexAccel
);
1834 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
1836 const wxMenuGeometryInfo
& geometryInfo
,
1837 const wxString
& label
,
1838 const wxString
& accel
,
1839 const wxBitmap
& bitmap
,
1843 wxFAIL_MSG(_T("TODO"));
1846 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
1848 const wxMenuGeometryInfo
& geomInfo
)
1850 wxFAIL_MSG(_T("TODO"));
1853 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
1858 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
1859 const wxMenu
& menu
) const
1861 wxFAIL_MSG(_T("TODO"));
1865 #endif // wxUSE_MENUS
1867 // ----------------------------------------------------------------------------
1869 // ----------------------------------------------------------------------------
1871 void wxGTKRenderer::InitComboBitmaps()
1873 wxSize sizeArrow
= m_sizeScrollbarArrow
;
1879 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1881 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
1884 static const int comboButtonFlags
[ComboState_Max
] =
1892 wxRect
rect(wxPoint(0, 0), sizeArrow
);
1895 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1897 int flags
= comboButtonFlags
[n
];
1899 dc
.SelectObject(m_bitmapsCombo
[n
]);
1900 DoDrawBackground(dc
, GetBackgroundColour(flags
), rect
);
1901 DrawArrow(dc
, wxDOWN
, rect
, flags
);
1905 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
1907 wxBitmap
*bmpPressed
,
1908 wxBitmap
*bmpDisabled
)
1910 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
1916 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
1918 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
1920 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
1922 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
1925 // ----------------------------------------------------------------------------
1927 // ----------------------------------------------------------------------------
1929 void wxGTKRenderer::DoDrawBackground(wxDC
& dc
,
1930 const wxColour
& col
,
1933 wxBrush
brush(col
, wxSOLID
);
1935 dc
.SetPen(*wxTRANSPARENT_PEN
);
1936 dc
.DrawRectangle(rect
);
1939 void wxGTKRenderer::DrawBackground(wxDC
& dc
,
1940 const wxColour
& col
,
1944 wxColour colBg
= col
.Ok() ? col
: GetBackgroundColour(flags
);
1945 DoDrawBackground(dc
, colBg
, rect
);
1948 // ----------------------------------------------------------------------------
1950 // ----------------------------------------------------------------------------
1952 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
1956 static const wxDirection sides
[] =
1958 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
1961 wxRect rect1
, rect2
, rectInner
;
1967 rectInner
.Inflate(-2);
1969 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
1971 // find the side not to draw and also adjust the rectangles to compensate
1973 wxDirection sideToOmit
;
1977 sideToOmit
= wxDOWN
;
1979 rectInner
.height
+= 1;
1987 rectInner
.height
+= 1;
1991 sideToOmit
= wxRIGHT
;
1993 rectInner
.width
+= 1;
1997 sideToOmit
= wxLEFT
;
2001 rectInner
.width
+= 1;
2005 wxFAIL_MSG(_T("unknown arrow direction"));
2009 // the outer rect first
2011 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2013 wxDirection side
= sides
[n
];
2014 if ( side
== sideToOmit
)
2017 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
2020 // and then the inner one
2021 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2023 wxDirection side
= sides
[n
];
2024 if ( side
== sideToOmit
)
2027 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
2033 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
2035 const wxRect
& rectArrow
,
2038 // first of all, draw the border around it - but we don't want the border
2039 // on the side opposite to the arrow point
2040 wxRect rect
= rectArrow
;
2041 DrawArrowBorder(dc
, &rect
, dir
);
2043 // then the arrow itself
2044 DrawArrow(dc
, dir
, rect
, flags
);
2047 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
2048 // these people are just crazy :-(
2049 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2062 wxPoint ptArrow
[Point_Max
];
2064 wxColour colInside
= GetBackgroundColour(flags
);
2066 if ( flags
& wxCONTROL_DISABLED
)
2068 penShadow
[0] = m_penDarkGrey
;
2069 penShadow
[1] = m_penDarkGrey
;
2070 penShadow
[2] = wxNullPen
;
2071 penShadow
[3] = wxNullPen
;
2073 else if ( flags
& wxCONTROL_PRESSED
)
2075 penShadow
[0] = m_penDarkGrey
;
2076 penShadow
[1] = m_penHighlight
;
2077 penShadow
[2] = wxNullPen
;
2078 penShadow
[3] = m_penBlack
;
2080 else // normal arrow
2082 penShadow
[0] = m_penHighlight
;
2083 penShadow
[1] = m_penBlack
;
2084 penShadow
[2] = m_penDarkGrey
;
2085 penShadow
[3] = wxNullPen
;
2089 if ( dir
== wxUP
|| dir
== wxDOWN
)
2092 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2096 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2099 // draw the arrow interior
2100 dc
.SetPen(*wxTRANSPARENT_PEN
);
2101 dc
.SetBrush(wxBrush(colInside
, wxSOLID
));
2106 ptArrow
[Point_First
].x
= rect
.GetLeft();
2107 ptArrow
[Point_First
].y
= rect
.GetBottom();
2108 ptArrow
[Point_Second
].x
= middle
;
2109 ptArrow
[Point_Second
].y
= rect
.GetTop();
2110 ptArrow
[Point_Third
].x
= rect
.GetRight();
2111 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2115 ptArrow
[Point_First
] = rect
.GetPosition();
2116 ptArrow
[Point_Second
].x
= middle
;
2117 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2118 ptArrow
[Point_Third
].x
= rect
.GetRight();
2119 ptArrow
[Point_Third
].y
= rect
.GetTop();
2123 ptArrow
[Point_First
].x
= rect
.GetRight();
2124 ptArrow
[Point_First
].y
= rect
.GetTop();
2125 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2126 ptArrow
[Point_Second
].y
= middle
;
2127 ptArrow
[Point_Third
].x
= rect
.GetRight();
2128 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2132 ptArrow
[Point_First
] = rect
.GetPosition();
2133 ptArrow
[Point_Second
].x
= rect
.GetRight();
2134 ptArrow
[Point_Second
].y
= middle
;
2135 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2136 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2140 wxFAIL_MSG(_T("unknown arrow direction"));
2143 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2145 // draw the arrow border
2146 dc
.SetPen(penShadow
[0]);
2150 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2151 dc
.DrawPoint(ptArrow
[Point_First
]);
2152 if ( penShadow
[3].Ok() )
2154 dc
.SetPen(penShadow
[3]);
2155 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2156 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2158 dc
.SetPen(penShadow
[1]);
2159 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2160 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2161 dc
.DrawPoint(ptArrow
[Point_Third
]);
2162 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2163 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2164 if ( penShadow
[2].Ok() )
2166 dc
.SetPen(penShadow
[2]);
2167 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2168 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2169 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2170 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2175 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2176 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2177 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2178 if ( penShadow
[2].Ok() )
2180 dc
.SetPen(penShadow
[2]);
2181 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2182 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2184 dc
.SetPen(penShadow
[1]);
2185 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2186 dc
.DrawPoint(ptArrow
[Point_Third
]);
2190 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2191 dc
.DrawPoint(ptArrow
[Point_First
]);
2192 if ( penShadow
[2].Ok() )
2194 dc
.SetPen(penShadow
[2]);
2195 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2196 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2197 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2198 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2200 dc
.SetPen(penShadow
[1]);
2201 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2202 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2203 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2204 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2208 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2209 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2210 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2211 dc
.SetPen(penShadow
[1]);
2212 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2213 dc
.DrawPoint(ptArrow
[Point_Third
]);
2217 wxFAIL_MSG(_T("unknown arrow direction"));
2222 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2224 wxOrientation orient
)
2226 if ( orient
== wxVERTICAL
)
2228 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2230 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2232 rect
->Inflate(-1, 0);
2234 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2236 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2238 rect
->Inflate(-1, 0);
2242 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2244 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2246 rect
->Inflate(0, -1);
2248 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2250 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2252 rect
->Inflate(0, -1);
2256 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2257 wxOrientation orient
,
2261 // the thumb is never pressed never has focus border under GTK and the
2262 // scrollbar background never changes at all
2263 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2265 // we don't want the border in the direction of the scrollbar movement
2266 wxRect rectThumb
= rect
;
2267 DrawThumbBorder(dc
, &rectThumb
, orient
);
2269 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2270 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2273 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2274 wxOrientation orient
,
2278 wxRect rectBar
= rect
;
2279 DrawThumbBorder(dc
, &rectBar
, orient
);
2280 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2283 void wxGTKRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2285 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2288 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2289 wxScrollBar::Element elem
,
2292 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2293 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2295 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2297 elem
= wxScrollBar::Element_Bar_2
;
2300 return StandardGetScrollbarRect(scrollbar
, elem
,
2302 GetScrollbarArrowSize(scrollbar
));
2305 wxCoord
wxGTKRenderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
2307 return StandardScrollBarSize(scrollbar
, GetScrollbarArrowSize(scrollbar
));
2310 wxHitTest
wxGTKRenderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
2311 const wxPoint
& pt
) const
2313 return StandardHitTestScrollbar(scrollbar
, pt
,
2314 GetScrollbarArrowSize(scrollbar
));
2317 wxCoord
wxGTKRenderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
2320 return StandardScrollbarToPixel(scrollbar
, thumbPos
,
2321 GetScrollbarArrowSize(scrollbar
));
2324 int wxGTKRenderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
2327 return StandardPixelToScrollbar(scrollbar
, coord
,
2328 GetScrollbarArrowSize(scrollbar
));
2331 // ----------------------------------------------------------------------------
2333 // ----------------------------------------------------------------------------
2335 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2338 if ( wxDynamicCast(window
, wxBitmapButton
) )
2343 #endif // wxUSE_BMPBUTTON
2345 if ( wxDynamicCast(window
, wxButton
) )
2347 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2349 // TODO: this is ad hoc...
2350 size
->x
+= 3*window
->GetCharWidth();
2351 wxCoord minBtnHeight
= 18;
2352 if ( size
->y
< minBtnHeight
)
2353 size
->y
= minBtnHeight
;
2355 // button border width
2360 if ( wxDynamicCast(window
, wxScrollBar
) )
2362 // we only set the width of vert scrollbars and height of the
2364 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2365 size
->y
= m_sizeScrollbarArrow
.x
;
2367 size
->x
= m_sizeScrollbarArrow
.x
;
2371 // take into account the border width
2372 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
2373 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
2374 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
2378 // ----------------------------------------------------------------------------
2379 // top level windows
2380 // ----------------------------------------------------------------------------
2382 void wxGTKRenderer::DrawFrameTitleBar(wxDC
& dc
,
2384 const wxString
& title
,
2388 int specialButtonFlag
)
2392 void wxGTKRenderer::DrawFrameBorder(wxDC
& dc
,
2398 void wxGTKRenderer::DrawFrameBackground(wxDC
& dc
,
2404 void wxGTKRenderer::DrawFrameTitle(wxDC
& dc
,
2406 const wxString
& title
,
2411 void wxGTKRenderer::DrawFrameIcon(wxDC
& dc
,
2418 void wxGTKRenderer::DrawFrameButton(wxDC
& dc
,
2419 wxCoord x
, wxCoord y
,
2425 wxRect
wxGTKRenderer::GetFrameClientArea(const wxRect
& rect
, int flags
) const
2430 wxSize
wxGTKRenderer::GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const
2435 wxSize
wxGTKRenderer::GetFrameIconSize() const
2437 return wxSize(-1, -1);
2440 int wxGTKRenderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
2442 return wxHT_TOPLEVEL_CLIENT_AREA
;
2447 // ============================================================================
2449 // ============================================================================
2451 // ----------------------------------------------------------------------------
2452 // wxGTKInputHandler
2453 // ----------------------------------------------------------------------------
2455 wxGTKInputHandler::wxGTKInputHandler(wxGTKRenderer
*renderer
)
2457 m_renderer
= renderer
;
2460 bool wxGTKInputHandler::HandleKey(wxInputConsumer
*control
,
2461 const wxKeyEvent
& event
,
2467 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
2468 const wxMouseEvent
& event
)
2470 // clicking on the control gives it focus
2471 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
2473 control
->GetInputWindow()->SetFocus();
2481 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
2482 const wxMouseEvent
& event
)
2484 if ( event
.Entering() )
2486 control
->GetInputWindow()->SetCurrent(TRUE
);
2488 else if ( event
.Leaving() )
2490 control
->GetInputWindow()->SetCurrent(FALSE
);
2500 // ----------------------------------------------------------------------------
2501 // wxGTKCheckboxInputHandler
2502 // ----------------------------------------------------------------------------
2504 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
2505 const wxKeyEvent
& event
,
2510 int keycode
= event
.GetKeyCode();
2511 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
2513 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
2522 // ----------------------------------------------------------------------------
2523 // wxGTKTextCtrlInputHandler
2524 // ----------------------------------------------------------------------------
2526 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
2527 const wxKeyEvent
& event
,
2530 // handle only GTK-specific text bindings here, the others are handled in
2534 wxControlAction action
;
2535 int keycode
= event
.GetKeyCode();
2536 if ( event
.ControlDown() )
2541 action
= wxACTION_TEXT_HOME
;
2545 action
= wxACTION_TEXT_LEFT
;
2549 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
2553 action
= wxACTION_TEXT_END
;
2557 action
= wxACTION_TEXT_RIGHT
;
2561 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
2565 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2569 action
= wxACTION_TEXT_DOWN
;
2573 action
= wxACTION_TEXT_UP
;
2577 //delete the entire line
2578 control
->PerformAction(wxACTION_TEXT_HOME
);
2579 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2583 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
2587 else if ( event
.AltDown() )
2592 action
= wxACTION_TEXT_WORD_LEFT
;
2596 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
2600 action
= wxACTION_TEXT_WORD_RIGHT
;
2605 if ( action
!= wxACTION_NONE
)
2607 control
->PerformAction(action
);
2613 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);