1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: univ/themes/gtk.cpp
3 // Purpose: wxUniversal theme implementing GTK-like LNF
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
30 #include "wx/dcmemory.h"
31 #include "wx/window.h"
33 #include "wx/bmpbuttn.h"
34 #include "wx/button.h"
35 #include "wx/checkbox.h"
36 #include "wx/listbox.h"
37 #include "wx/checklst.h"
38 #include "wx/combobox.h"
39 #include "wx/scrolbar.h"
40 #include "wx/slider.h"
41 #include "wx/textctrl.h"
44 #include "wx/notebook.h"
45 #include "wx/spinbutt.h"
47 #include "wx/univ/renderer.h"
48 #include "wx/univ/inphand.h"
49 #include "wx/univ/colschem.h"
50 #include "wx/univ/theme.h"
52 // ----------------------------------------------------------------------------
53 // constants (to be removed, for testing only)
54 // ----------------------------------------------------------------------------
56 static const wxCoord BORDER_THICKNESS
= 1;
58 // ----------------------------------------------------------------------------
59 // wxGTKRenderer: draw the GUI elements in GTK style
60 // ----------------------------------------------------------------------------
62 class wxGTKRenderer
: public wxRenderer
65 wxGTKRenderer(const wxColourScheme
*scheme
);
67 // implement the base class pure virtuals
68 virtual void DrawBackground(wxDC
& dc
,
72 virtual void DrawLabel(wxDC
& dc
,
73 const wxString
& label
,
76 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
78 wxRect
*rectBounds
= NULL
);
79 virtual void DrawButtonLabel(wxDC
& dc
,
80 const wxString
& label
,
81 const wxBitmap
& image
,
84 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
86 wxRect
*rectBounds
= NULL
);
87 virtual void DrawBorder(wxDC
& dc
,
91 wxRect
*rectIn
= (wxRect
*)NULL
);
92 virtual void DrawHorizontalLine(wxDC
& dc
,
93 wxCoord y
, wxCoord x1
, wxCoord x2
);
94 virtual void DrawVerticalLine(wxDC
& dc
,
95 wxCoord x
, wxCoord y1
, wxCoord y2
);
96 virtual void DrawFrame(wxDC
& dc
,
97 const wxString
& label
,
100 int alignment
= wxALIGN_LEFT
,
101 int indexAccel
= -1);
102 virtual void DrawTextBorder(wxDC
& dc
,
106 wxRect
*rectIn
= (wxRect
*)NULL
);
107 virtual void DrawButtonBorder(wxDC
& dc
,
110 wxRect
*rectIn
= (wxRect
*)NULL
);
111 virtual void DrawArrow(wxDC
& dc
,
115 virtual void DrawScrollbarArrow(wxDC
& dc
,
119 virtual void DrawScrollbarThumb(wxDC
& dc
,
120 wxOrientation orient
,
123 virtual void DrawScrollbarShaft(wxDC
& dc
,
124 wxOrientation orient
,
127 virtual void DrawScrollCorner(wxDC
& dc
,
129 virtual void DrawItem(wxDC
& dc
,
130 const wxString
& label
,
133 virtual void DrawCheckItem(wxDC
& dc
,
134 const wxString
& label
,
135 const wxBitmap
& bitmap
,
138 virtual void DrawCheckButton(wxDC
& dc
,
139 const wxString
& label
,
140 const wxBitmap
& bitmap
,
143 wxAlignment align
= wxALIGN_LEFT
,
144 int indexAccel
= -1);
146 virtual void DrawRadioButton(wxDC
& dc
,
147 const wxString
& label
,
148 const wxBitmap
& bitmap
,
151 wxAlignment align
= wxALIGN_LEFT
,
152 int indexAccel
= -1);
154 virtual void DrawTextLine(wxDC
& dc
,
155 const wxString
& text
,
160 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
161 virtual void DrawTab(wxDC
& dc
,
164 const wxString
& label
,
165 const wxBitmap
& bitmap
= wxNullBitmap
,
167 int indexAccel
= -1);
169 virtual void DrawSliderShaft(wxDC
& dc
,
171 wxOrientation orient
,
173 wxRect
*rectShaft
= NULL
);
174 virtual void DrawSliderThumb(wxDC
& dc
,
176 wxOrientation orient
,
178 virtual void DrawSliderTicks(wxDC
& dc
,
180 const wxSize
& sizeThumb
,
181 wxOrientation orient
,
187 // we don't have the ticks in GTK version
191 virtual void DrawMenuBarItem(wxDC
& dc
,
193 const wxString
& label
,
195 int indexAccel
= -1);
196 virtual void DrawMenuItem(wxDC
& dc
,
198 const wxMenuGeometryInfo
& geometryInfo
,
199 const wxString
& label
,
200 const wxString
& accel
,
201 const wxBitmap
& bitmap
= wxNullBitmap
,
203 int indexAccel
= -1);
204 virtual void DrawMenuSeparator(wxDC
& dc
,
206 const wxMenuGeometryInfo
& geomInfo
);
209 virtual void DrawFrameTitleBar(wxDC
& dc
,
211 const wxString
& title
,
214 int pressedButtons
= 0);
215 virtual void DrawFrameBorder(wxDC
& dc
,
218 virtual void DrawFrameBackground(wxDC
& dc
,
221 virtual void DrawFrameTitle(wxDC
& dc
,
223 const wxString
& title
,
225 virtual void DrawFrameIcon(wxDC
& dc
,
229 virtual void DrawFrameButton(wxDC
& dc
,
230 wxCoord x
, wxCoord y
,
235 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
236 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
237 virtual wxSize
GetFrameIconSize() const;
239 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
241 wxBitmap
*bmpPressed
,
242 wxBitmap
*bmpDisabled
);
244 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
245 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
246 virtual bool AreScrollbarsInsideBorder() const;
248 // geometry and hit testing
249 virtual wxSize
GetScrollbarArrowSize() const
250 { return m_sizeScrollbarArrow
; }
251 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
252 wxScrollBar::Element elem
,
253 int thumbPos
= -1) const;
254 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
255 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
256 const wxPoint
& pt
) const;
257 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
259 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
260 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
261 { return fontHeight
+ 2; }
262 virtual wxSize
GetCheckBitmapSize() const
263 { return wxSize(10, 10); }
264 virtual wxSize
GetRadioBitmapSize() const
265 { return wxSize(11, 11); }
266 virtual wxCoord
GetCheckItemMargin() const
269 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
271 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
273 wxCoord
*extraSpaceBeyond
);
275 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
276 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
278 virtual wxCoord
GetSliderDim() const { return 15; }
279 virtual wxCoord
GetSliderTickLen() const { return 0; }
280 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
281 wxOrientation orient
) const;
282 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
283 wxOrientation orient
) const;
284 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
287 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
288 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
289 const wxMenu
& menu
) const;
291 // helpers for "wxBitmap wxColourScheme::Get()"
292 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
293 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
296 // DrawBackground() helpers
298 // get the colour to use for background
299 wxColour
GetBackgroundColour(int flags
) const
301 if ( flags
& wxCONTROL_PRESSED
)
302 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
303 else if ( flags
& wxCONTROL_CURRENT
)
304 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
306 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
309 // draw the background with any colour, not only the default one(s)
310 void DoDrawBackground(wxDC
& dc
,
314 // DrawBorder() helpers: all of them shift and clip the DC after drawing
317 // just draw a rectangle with the given pen
318 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
320 // draw the lower left part of rectangle
321 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
323 // draw the rectange using the first brush for the left and top sides and
324 // the second one for the bottom and right ones
325 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
326 const wxPen
& pen1
, const wxPen
& pen2
);
328 // as DrawShadedRect() but the pixels in the bottom left and upper right
329 // border are drawn with the pen1, not pen2
330 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
331 const wxPen
& pen1
, const wxPen
& pen2
);
333 // used for drawing opened rectangles - draws only one side of it at once
334 // (and doesn't adjust the rect)
335 void DrawAntiShadedRectSide(wxDC
& dc
,
341 // draw an opened rect for the arrow in given direction
342 void DrawArrowBorder(wxDC
& dc
,
346 // draw two sides of the rectangle
347 void DrawThumbBorder(wxDC
& dc
,
349 wxOrientation orient
);
351 // draw the normal 3D border
352 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
354 // just as DrawRaisedBorder() except that the bottom left and up right
355 // pixels of the interior rect are drawn in another colour (i.e. the inner
356 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
357 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
359 // returns the size of the arrow for the scrollbar (depends on
361 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
364 if ( scrollbar
->IsVertical() )
366 size
= m_sizeScrollbarArrow
;
370 size
.x
= m_sizeScrollbarArrow
.y
;
371 size
.y
= m_sizeScrollbarArrow
.x
;
377 // get the line wrap indicator bitmap
378 wxBitmap
GetLineWrapBitmap();
380 // DrawCheckBitmap and DrawRadioBitmap helpers
382 // draw the check bitmaps once and cache them for later use
383 wxBitmap
GetCheckBitmap(int flags
);
385 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
387 void DrawUpZag(wxDC
& dc
,
388 wxCoord x1
, wxCoord x2
,
389 wxCoord y1
, wxCoord y2
);
390 void DrawDownZag(wxDC
& dc
,
391 wxCoord x1
, wxCoord x2
,
392 wxCoord y1
, wxCoord y2
);
394 // draw the radio button bitmap for the given state
395 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
397 // draw check/radio - the bitmap must be a valid one by now
398 void DoDrawCheckOrRadioBitmap(wxDC
& dc
,
399 const wxString
& label
,
400 const wxBitmap
& bitmap
,
401 const wxRect
& rectTotal
,
406 // initialize the combo bitmaps
407 void InitComboBitmaps();
410 const wxColourScheme
*m_scheme
;
413 wxSize m_sizeScrollbarArrow
;
422 // the checkbox bitmaps: first row is for the normal, second for the
423 // pressed state and the columns are for checked and unchecked status
425 wxBitmap m_bitmapsCheckbox
[2][2];
427 // the line wrap bitmap (drawn at the end of wrapped lines)
428 wxBitmap m_bmpLineWrap
;
430 // the combobox bitmaps
440 wxBitmap m_bitmapsCombo
[ComboState_Max
];
443 // ----------------------------------------------------------------------------
444 // wxGTKInputHandler and derived classes: process the keyboard and mouse
445 // messages according to GTK standards
446 // ----------------------------------------------------------------------------
448 class wxGTKInputHandler
: public wxInputHandler
451 wxGTKInputHandler(wxGTKRenderer
*renderer
);
453 virtual bool HandleKey(wxInputConsumer
*control
,
454 const wxKeyEvent
& event
,
456 virtual bool HandleMouse(wxInputConsumer
*control
,
457 const wxMouseEvent
& event
);
458 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
461 wxGTKRenderer
*m_renderer
;
464 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
467 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
468 : wxStdScrollBarInputHandler(renderer
, handler
) { }
471 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
473 // only arrows and the thumb can be highlighted
474 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
477 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
480 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
482 // only arrows can be pressed
486 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
489 virtual bool IsAllowedButton(int WXUNUSED(button
)) { return TRUE
; }
493 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
494 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
498 class wxGTKCheckboxInputHandler
: public wxStdCheckboxInputHandler
501 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
502 : wxStdCheckboxInputHandler(handler
) { }
504 virtual bool HandleKey(wxInputConsumer
*control
,
505 const wxKeyEvent
& event
,
509 class wxGTKTextCtrlInputHandler
: public wxStdTextCtrlInputHandler
512 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
513 : wxStdTextCtrlInputHandler(handler
) { }
515 virtual bool HandleKey(wxInputConsumer
*control
,
516 const wxKeyEvent
& event
,
520 // ----------------------------------------------------------------------------
521 // wxGTKColourScheme: uses the standard GTK colours
522 // ----------------------------------------------------------------------------
524 class wxGTKColourScheme
: public wxColourScheme
527 virtual wxColour
Get(StdColour col
) const;
528 virtual wxColour
GetBackground(wxWindow
*win
) const;
531 // ----------------------------------------------------------------------------
533 // ----------------------------------------------------------------------------
535 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
537 class wxGTKTheme
: public wxTheme
541 virtual ~wxGTKTheme();
543 virtual wxRenderer
*GetRenderer() { return m_renderer
; }
544 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
545 virtual wxColourScheme
*GetColourScheme() { return m_scheme
; }
548 // get the default input handler
549 wxInputHandler
*GetDefaultInputHandler();
551 wxGTKRenderer
*m_renderer
;
553 // the names of the already created handlers and the handlers themselves
554 // (these arrays are synchronized)
555 wxSortedArrayString m_handlerNames
;
556 wxArrayHandlers m_handlers
;
558 wxGTKInputHandler
*m_handlerDefault
;
560 wxGTKColourScheme
*m_scheme
;
562 WX_DECLARE_THEME(gtk
)
565 // ============================================================================
567 // ============================================================================
569 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
571 // ----------------------------------------------------------------------------
573 // ----------------------------------------------------------------------------
575 wxGTKTheme::wxGTKTheme()
577 m_scheme
= new wxGTKColourScheme
;
578 m_renderer
= new wxGTKRenderer(m_scheme
);
579 m_handlerDefault
= NULL
;
582 wxGTKTheme::~wxGTKTheme()
584 size_t count
= m_handlers
.GetCount();
585 for ( size_t n
= 0; n
< count
; n
++ )
587 if ( m_handlers
[n
] != m_handlerDefault
)
588 delete m_handlers
[n
];
591 delete m_handlerDefault
;
596 wxInputHandler
*wxGTKTheme::GetDefaultInputHandler()
598 if ( !m_handlerDefault
)
600 m_handlerDefault
= new wxGTKInputHandler(m_renderer
);
603 return m_handlerDefault
;
606 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
)
608 wxInputHandler
*handler
;
609 int n
= m_handlerNames
.Index(control
);
610 if ( n
== wxNOT_FOUND
)
612 // create a new handler
613 if ( control
== wxINP_HANDLER_SCROLLBAR
)
614 handler
= new wxGTKScrollBarInputHandler(m_renderer
,
615 GetDefaultInputHandler());
617 else if ( control
== wxINP_HANDLER_BUTTON
)
618 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
619 #endif // wxUSE_CHECKBOX
621 else if ( control
== wxINP_HANDLER_CHECKBOX
)
622 handler
= new wxGTKCheckboxInputHandler(GetDefaultInputHandler());
623 #endif // wxUSE_CHECKBOX
625 else if ( control
== wxINP_HANDLER_COMBOBOX
)
626 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
627 #endif // wxUSE_COMBOBOX
629 else if ( control
== wxINP_HANDLER_LISTBOX
)
630 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
631 #endif // wxUSE_LISTBOX
632 #if wxUSE_CHECKLISTBOX
633 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
634 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
635 #endif // wxUSE_CHECKLISTBOX
637 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
638 handler
= new wxGTKTextCtrlInputHandler(GetDefaultInputHandler());
639 #endif // wxUSE_TEXTCTRL
641 else if ( control
== wxINP_HANDLER_SLIDER
)
642 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
643 #endif // wxUSE_SLIDER
645 else if ( control
== wxINP_HANDLER_SPINBTN
)
646 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
647 #endif // wxUSE_SPINBTN
649 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
650 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
651 #endif // wxUSE_NOTEBOOK
653 handler
= GetDefaultInputHandler();
655 n
= m_handlerNames
.Add(control
);
656 m_handlers
.Insert(handler
, n
);
658 else // we already have it
660 handler
= m_handlers
[n
];
666 // ============================================================================
668 // ============================================================================
670 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
673 if ( win
->UseBgCol() )
675 // use the user specified colour
676 col
= win
->GetBackgroundColour();
679 if ( win
->IsContainerWindow() )
681 // doesn't depend on the state
689 int flags
= win
->GetStateFlags();
691 // the colour set by the user should be used for the normal state
692 // and for the states for which we don't have any specific colours
693 if ( !col
.Ok() || (flags
!= 0) )
695 if ( wxDynamicCast(win
, wxScrollBar
) )
696 col
= Get(SCROLLBAR
);
697 else if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
698 col
= Get(CONTROL_CURRENT
);
699 else if ( flags
& wxCONTROL_PRESSED
)
700 col
= Get(CONTROL_PRESSED
);
709 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
713 case WINDOW
: return *wxWHITE
;
715 case SHADOW_DARK
: return *wxBLACK
;
716 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
717 case SHADOW_IN
: return wxColour(0xd6d6d6);
718 case SHADOW_OUT
: return wxColour(0x969696);
720 case CONTROL
: return wxColour(0xd6d6d6);
721 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
722 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
724 case CONTROL_TEXT
: return *wxBLACK
;
725 case CONTROL_TEXT_DISABLED
:
726 return wxColour(0x757575);
727 case CONTROL_TEXT_DISABLED_SHADOW
:
731 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
733 case HIGHLIGHT
: return wxColour(0x9c0000);
734 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
738 wxFAIL_MSG(_T("invalid standard colour"));
743 // ============================================================================
745 // ============================================================================
747 // ----------------------------------------------------------------------------
749 // ----------------------------------------------------------------------------
751 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
755 m_sizeScrollbarArrow
= wxSize(15, 14);
758 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
759 m_penDarkGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_OUT
), 0, wxSOLID
);
760 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
), 0, wxSOLID
);
761 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
762 m_penHighlight
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
), 0, wxSOLID
);
765 // ----------------------------------------------------------------------------
767 // ----------------------------------------------------------------------------
769 void wxGTKRenderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
773 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
774 dc
.DrawRectangle(*rect
);
780 void wxGTKRenderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
782 // draw the bottom and right sides
784 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
785 rect
->GetRight() + 1, rect
->GetBottom());
786 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
787 rect
->GetRight(), rect
->GetBottom());
794 void wxGTKRenderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
795 const wxPen
& pen1
, const wxPen
& pen2
)
797 // draw the rectangle
799 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
800 rect
->GetLeft(), rect
->GetBottom());
801 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
802 rect
->GetRight(), rect
->GetTop());
804 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
805 rect
->GetRight(), rect
->GetBottom());
806 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
807 rect
->GetRight() + 1, rect
->GetBottom());
813 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
819 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
824 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
825 rect
.GetLeft(), rect
.GetBottom() + 1);
829 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
830 rect
.GetRight() + 1, rect
.GetTop());
834 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
835 rect
.GetRight(), rect
.GetBottom() + 1);
839 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
840 rect
.GetRight() + 1, rect
.GetBottom());
844 wxFAIL_MSG(_T("unknown rectangle side"));
848 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
849 const wxPen
& pen1
, const wxPen
& pen2
)
851 // draw the rectangle
853 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
854 rect
->GetLeft(), rect
->GetBottom() + 1);
855 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
856 rect
->GetRight() + 1, rect
->GetTop());
858 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
859 rect
->GetRight(), rect
->GetBottom());
860 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
861 rect
->GetRight() + 1, rect
->GetBottom());
867 void wxGTKRenderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
869 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
870 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
873 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
875 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
876 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
879 void wxGTKRenderer::DrawBorder(wxDC
& dc
,
881 const wxRect
& rectTotal
,
887 wxRect rect
= rectTotal
;
891 case wxBORDER_SUNKEN
:
892 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
894 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
895 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
899 case wxBORDER_STATIC
:
900 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
902 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
906 case wxBORDER_RAISED
:
907 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
909 DrawRaisedBorder(dc
, &rect
);
913 case wxBORDER_DOUBLE
:
914 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
916 DrawShadedRect(dc
, &rect
, m_penLightGrey
, m_penBlack
);
917 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penDarkGrey
);
918 DrawRect(dc
, &rect
, m_penLightGrey
);
922 case wxBORDER_SIMPLE
:
923 for ( width
= 0; width
< BORDER_THICKNESS
; width
++ )
925 DrawRect(dc
, &rect
, m_penBlack
);
930 wxFAIL_MSG(_T("unknown border type"));
933 case wxBORDER_DEFAULT
:
942 wxRect
wxGTKRenderer::GetBorderDimensions(wxBorder border
) const
947 case wxBORDER_RAISED
:
948 case wxBORDER_SUNKEN
:
949 width
= 2*BORDER_THICKNESS
;
952 case wxBORDER_SIMPLE
:
953 case wxBORDER_STATIC
:
954 width
= BORDER_THICKNESS
;
957 case wxBORDER_DOUBLE
:
958 width
= 3*BORDER_THICKNESS
;
962 wxFAIL_MSG(_T("unknown border type"));
965 case wxBORDER_DEFAULT
:
980 bool wxGTKRenderer::AreScrollbarsInsideBorder() const
982 // no, the scrollbars are outside the border in GTK+
986 // ----------------------------------------------------------------------------
988 // ----------------------------------------------------------------------------
990 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
992 const wxRect
& rectOrig
,
996 wxRect rect
= rectOrig
;
998 if ( border
!= wxBORDER_NONE
)
1000 if ( flags
& wxCONTROL_FOCUSED
)
1002 DrawRect(dc
, &rect
, m_penBlack
);
1003 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1007 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1008 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penHighlight
);
1016 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
1017 const wxRect
& rectTotal
,
1021 wxRect rect
= rectTotal
;
1023 if ( flags
& wxCONTROL_PRESSED
)
1025 // button pressed: draw a black border around it and an inward shade
1026 DrawRect(dc
, &rect
, m_penBlack
);
1028 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1030 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1031 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penDarkGrey
);
1036 // button not pressed
1038 if ( flags
& wxCONTROL_ISDEFAULT
)
1043 if ( flags
& wxCONTROL_FOCUSED
)
1045 // button is currently default: add an extra border around it
1046 DrawRect(dc
, &rect
, m_penBlack
);
1049 // now draw a normal button
1050 for ( size_t width
= 0; width
< BORDER_THICKNESS
; width
++ )
1052 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1053 DrawAntiShadedRect(dc
, &rect
,
1054 wxPen(GetBackgroundColour(flags
), 0, wxSOLID
),
1065 // ----------------------------------------------------------------------------
1067 // ----------------------------------------------------------------------------
1069 void wxGTKRenderer::DrawHorizontalLine(wxDC
& dc
,
1070 wxCoord y
, wxCoord x1
, wxCoord x2
)
1072 dc
.SetPen(m_penDarkGrey
);
1073 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1074 dc
.SetPen(m_penHighlight
);
1076 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1079 void wxGTKRenderer::DrawVerticalLine(wxDC
& dc
,
1080 wxCoord x
, wxCoord y1
, wxCoord y2
)
1082 dc
.SetPen(m_penDarkGrey
);
1083 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1084 dc
.SetPen(m_penHighlight
);
1086 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1089 void wxGTKRenderer::DrawFrame(wxDC
& dc
,
1090 const wxString
& label
,
1096 wxCoord height
= 0; // of the label
1097 wxRect rectFrame
= rect
;
1098 if ( !label
.empty() )
1100 // the text should touch the top border of the rect, so the frame
1101 // itself should be lower
1102 dc
.GetTextExtent(label
, NULL
, &height
);
1103 rectFrame
.y
+= height
/ 2;
1104 rectFrame
.height
-= height
/ 2;
1106 // TODO: the +4 should be customizable
1109 rectText
.x
= rectFrame
.x
+ 4;
1110 rectText
.y
= rect
.y
;
1111 rectText
.width
= rectFrame
.width
- 8;
1112 rectText
.height
= height
;
1115 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1117 rectLabel
.width
+= 2;
1119 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1121 // GTK+ does it like this
1122 dc
.SetPen(m_penHighlight
);
1123 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
1124 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
1128 // just draw the complete frame
1129 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1130 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1134 // ----------------------------------------------------------------------------
1136 // ----------------------------------------------------------------------------
1138 void wxGTKRenderer::DrawLabel(wxDC
& dc
,
1139 const wxString
& label
,
1146 DrawButtonLabel(dc
, label
, wxNullBitmap
, rect
, flags
,
1147 alignment
, indexAccel
, rectBounds
);
1150 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
1151 const wxString
& label
,
1152 const wxBitmap
& image
,
1159 if ( flags
& wxCONTROL_DISABLED
)
1161 // make the text grey and draw a shade for it
1162 dc
.SetTextForeground(*wxWHITE
); // FIXME hardcoded colour
1163 wxRect rectShadow
= rect
;
1166 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1167 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, CONTROL_TEXT_DISABLED
));
1170 dc
.DrawLabel(label
, image
, rect
, alignment
, indexAccel
, rectBounds
);
1173 void wxGTKRenderer::DrawItem(wxDC
& dc
,
1174 const wxString
& label
,
1178 wxLogTrace(_T("listbox"), _T("drawing item '%s' at (%d, %d)-(%d, %d)"),
1181 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1184 if ( flags
& wxCONTROL_SELECTED
)
1186 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
), wxSOLID
));
1187 dc
.SetPen(*wxTRANSPARENT_PEN
);
1188 dc
.DrawRectangle(rect
);
1190 colFg
= dc
.GetTextForeground();
1191 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
1194 if ( flags
& wxCONTROL_FOCUSED
)
1196 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1197 wxRect rectFocus
= rect
;
1198 DrawRect(dc
, &rectFocus
, m_penBlack
);
1201 wxRect rectText
= rect
;
1204 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
1206 if ( flags
& wxCONTROL_SELECTED
)
1208 dc
.SetBackgroundMode(wxTRANSPARENT
);
1211 // restore the text colour
1214 dc
.SetTextForeground(colFg
);
1218 void wxGTKRenderer::DrawCheckItem(wxDC
& dc
,
1219 const wxString
& label
,
1220 const wxBitmap
& bitmap
,
1224 wxRect rectBitmap
= rect
;
1226 rectBitmap
.width
= GetCheckBitmapSize().x
;
1227 // never draw the focus rect around the check indicators here
1228 DrawCheckButton(dc
, _T(""), bitmap
, rectBitmap
, flags
& ~wxCONTROL_FOCUSED
);
1230 wxRect rectLabel
= rect
;
1231 wxCoord shift
= rectBitmap
.width
+ 2*GetCheckItemMargin();
1232 rectLabel
.x
+= shift
;
1233 rectLabel
.width
-= shift
;
1234 DrawItem(dc
, label
, rectLabel
, flags
);
1237 // ----------------------------------------------------------------------------
1238 // check/radion buttons
1239 // ----------------------------------------------------------------------------
1241 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1242 const wxRect
& rectTotal
,
1245 wxRect rect
= rectTotal
;
1246 DrawAntiRaisedBorder(dc
, &rect
);
1248 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1249 dc
.SetPen(wxPen(col
, 0, wxSOLID
));
1250 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1253 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1254 //else: it is SHADOW_IN, leave as is
1256 dc
.SetPen(*wxTRANSPARENT_PEN
);
1257 dc
.SetBrush(wxBrush(col
, wxSOLID
));
1258 dc
.DrawRectangle(rect
);
1261 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1263 wxRect rect
= rectTotal
;
1264 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1265 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1267 dc
.SetPen(*wxTRANSPARENT_PEN
);
1268 dc
.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), wxSOLID
));
1269 dc
.DrawRectangle(rect
);
1272 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1278 xRight
= rect
.GetRight(),
1279 yBottom
= rect
.GetBottom();
1281 wxCoord yMid
= (y
+ yBottom
) / 2;
1283 // this looks ugly when the background colour of the control is not the
1284 // same ours - radiobox is not transparent as it should be
1286 // first fill the middle: as FloodFill() is not implemented on all
1287 // platforms, this is the only thing to do
1288 wxColour colBg
= flags
& wxCONTROL_CURRENT
1289 ? wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
)
1290 : wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1291 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
1292 dc
.SetPen(*wxTRANSPARENT_PEN
);
1293 dc
.DrawRectangle(rect
);
1296 // then draw the upper half
1297 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1298 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1299 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1302 if ( flags
& wxCONTROL_CHECKED
)
1303 dc
.SetPen(m_penBlack
);
1304 else if ( flags
& wxCONTROL_PRESSED
)
1305 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1306 else // unchecked and unpressed
1310 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1312 // and then the lower one
1313 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1314 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1315 if ( !(flags
& wxCONTROL_CHECKED
) )
1316 dc
.SetPen(m_penDarkGrey
);
1317 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1319 if ( !(flags
& wxCONTROL_CHECKED
) )
1320 drawIt
= TRUE
; // with the same pen
1321 else if ( flags
& wxCONTROL_PRESSED
)
1323 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), 0, wxSOLID
));
1326 else // checked and unpressed
1330 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1333 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1339 wxCoord xMid
= (x1
+ x2
) / 2;
1340 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1341 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1344 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1350 wxCoord xMid
= (x1
+ x2
) / 2;
1351 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1352 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1355 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1357 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1359 // init the bitmaps once only
1361 wxSize size
= GetCheckBitmapSize();
1362 rect
.width
= size
.x
;
1363 rect
.height
= size
.y
;
1364 for ( int i
= 0; i
< 2; i
++ )
1366 for ( int j
= 0; j
< 2; j
++ )
1367 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1373 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1374 DrawCheckBitmap(dc
, rect
);
1377 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1378 DrawUncheckBitmap(dc
, rect
, FALSE
);
1381 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1383 // pressed unchecked
1384 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1385 DrawUncheckBitmap(dc
, rect
, TRUE
);
1388 int row
= flags
& wxCONTROL_PRESSED
? 1 : 0;
1389 int col
= flags
& wxCONTROL_CHECKED
? 0 : 1;
1391 return m_bitmapsCheckbox
[row
][col
];
1394 wxBitmap
wxGTKRenderer::GetLineWrapBitmap()
1396 if ( !m_bmpLineWrap
.Ok() )
1398 // the line wrap bitmap as used by GTK+
1399 #define line_wrap_width 6
1400 #define line_wrap_height 9
1401 static const char line_wrap_bits
[] =
1403 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1406 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1407 if ( !bmpLineWrap
.Ok() )
1409 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1413 m_bmpLineWrap
= bmpLineWrap
;
1417 return m_bmpLineWrap
;
1420 void wxGTKRenderer::DrawCheckButton(wxDC
& dc
,
1421 const wxString
& label
,
1422 const wxBitmap
& bitmapOrig
,
1423 const wxRect
& rectTotal
,
1429 if ( bitmapOrig
.Ok() )
1431 bitmap
= bitmapOrig
;
1435 bitmap
= GetCheckBitmap(flags
);
1438 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1439 flags
, align
, indexAccel
);
1442 void wxGTKRenderer::DoDrawCheckOrRadioBitmap(wxDC
& dc
,
1443 const wxString
& label
,
1444 const wxBitmap
& bitmap
,
1445 const wxRect
& rectTotal
,
1450 wxRect rect
= rectTotal
;
1452 if ( flags
& wxCONTROL_FOCUSED
)
1454 // draw the focus border around everything
1455 DrawRect(dc
, &rect
, m_penBlack
);
1459 // the border does not offset the string under GTK
1463 // calculate the position of the bitmap and of the label
1465 yBmp
= rect
.y
+ (rect
.height
- bitmap
.GetHeight()) / 2;
1468 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
1469 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
1471 if ( align
== wxALIGN_RIGHT
)
1473 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
1474 rectLabel
.x
= rect
.x
+ 2;
1475 rectLabel
.SetRight(xBmp
);
1477 else // normal (checkbox to the left of the text) case
1480 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 4;
1481 rectLabel
.SetRight(rect
.GetRight());
1484 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
1486 DrawLabel(dc
, label
, rectLabel
, flags
,
1487 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1490 void wxGTKRenderer::DrawRadioButton(wxDC
& dc
,
1491 const wxString
& label
,
1492 const wxBitmap
& bitmapOrig
,
1493 const wxRect
& rectTotal
,
1499 if ( bitmapOrig
.Ok() )
1501 bitmap
= bitmapOrig
;
1506 wxSize size
= GetRadioBitmapSize();
1507 rect
.width
= size
.x
;
1508 rect
.height
= size
.y
;
1509 bitmap
.Create(rect
.width
, rect
.height
);
1511 dc
.SelectObject(bitmap
);
1512 dc
.SetBackground(*wxLIGHT_GREY_BRUSH
);
1514 DrawRadioBitmap(dc
, rect
, flags
);
1515 bitmap
.SetMask(new wxMask(bitmap
, *wxLIGHT_GREY
));
1518 DoDrawCheckOrRadioBitmap(dc
, label
, bitmap
, rectTotal
,
1519 flags
, align
, indexAccel
);
1522 // ----------------------------------------------------------------------------
1524 // ----------------------------------------------------------------------------
1526 wxRect
wxGTKRenderer::GetTextTotalArea(const wxTextCtrl
*text
,
1529 wxRect rectTotal
= rect
;
1530 rectTotal
.Inflate(2*BORDER_THICKNESS
);
1534 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1536 wxCoord
*extraSpaceBeyond
)
1538 wxRect rectText
= rect
;
1539 rectText
.Inflate(-2*BORDER_THICKNESS
);
1541 if ( text
->WrapLines() )
1543 // leave enough for the line wrap bitmap indicator
1544 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1546 rectText
.width
-= widthMark
;
1548 if ( extraSpaceBeyond
)
1549 *extraSpaceBeyond
= widthMark
;
1555 void wxGTKRenderer::DrawTextLine(wxDC
& dc
,
1556 const wxString
& text
,
1562 // TODO: GTK+ draws selection even for unfocused controls, just with
1563 // different colours
1564 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
1567 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1569 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1571 // for a mono bitmap he colours it appears in depends on the current text
1572 // colours, so set them correctly
1574 if ( bmpLineWrap
.GetDepth() == 1 )
1576 colFgOld
= dc
.GetTextForeground();
1578 // FIXME: I wonder what should we do if the background is black too?
1579 dc
.SetTextForeground(*wxBLACK
);
1582 dc
.DrawBitmap(bmpLineWrap
,
1583 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1585 if ( colFgOld
.Ok() )
1587 // restore old colour
1588 dc
.SetTextForeground(colFgOld
);
1592 // ----------------------------------------------------------------------------
1594 // ----------------------------------------------------------------------------
1596 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1597 const wxRect
& rectOrig
,
1599 const wxString
& label
,
1600 const wxBitmap
& bitmap
,
1604 wxRect rect
= rectOrig
;
1606 // the current tab is drawn indented (to the top for default case) and
1607 // bigger than the other ones
1608 const wxSize indent
= GetTabIndent();
1609 if ( flags
& wxCONTROL_SELECTED
)
1614 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1618 rect
.Inflate(indent
.x
, 0);
1620 rect
.height
+= indent
.y
;
1624 rect
.Inflate(indent
.x
, 0);
1625 rect
.height
+= indent
.y
;
1630 wxFAIL_MSG(_T("TODO"));
1635 // selected tab has different colour
1636 wxColour col
= flags
& wxCONTROL_SELECTED
1637 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1638 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1639 DoDrawBackground(dc
, col
, rect
);
1641 if ( flags
& wxCONTROL_FOCUSED
)
1643 // draw the focus rect
1644 wxRect rectBorder
= rect
;
1645 rectBorder
.Deflate(4, 3);
1646 if ( dir
== wxBOTTOM
)
1647 rectBorder
.Offset(0, -1);
1649 DrawRect(dc
, &rectBorder
, m_penBlack
);
1652 // draw the text, image and the focus around them (if necessary)
1653 wxRect rectLabel
= rect
;
1654 rectLabel
.Deflate(1, 1);
1655 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1657 // now draw the tab itself
1660 x2
= rect
.GetRight(),
1661 y2
= rect
.GetBottom();
1666 dc
.SetPen(m_penHighlight
);
1667 dc
.DrawLine(x
, y2
, x
, y
);
1668 dc
.DrawLine(x
+ 1, y
, x2
, y
);
1670 dc
.SetPen(m_penBlack
);
1671 dc
.DrawLine(x2
, y2
, x2
, y
);
1673 dc
.SetPen(m_penDarkGrey
);
1674 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ 1);
1676 if ( flags
& wxCONTROL_SELECTED
)
1678 dc
.SetPen(m_penLightGrey
);
1680 // overwrite the part of the border below this tab
1681 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
1683 // and the shadow of the tab to the left of us
1684 dc
.DrawLine(x
+ 1, y
+ 2, x
+ 1, y2
+ 1);
1689 dc
.SetPen(m_penHighlight
);
1691 // we need to continue one pixel further to overwrite the corner of
1692 // the border for the selected tab
1693 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
1696 // it doesn't work like this (TODO: implement it properly)
1698 // erase the corner of the tab to the right
1699 dc
.SetPen(m_penLightGrey
);
1700 dc
.DrawPoint(x2
- 1, y
- 2);
1701 dc
.DrawPoint(x2
- 2, y
- 2);
1702 dc
.DrawPoint(x2
- 2, y
- 1);
1705 dc
.SetPen(m_penBlack
);
1706 dc
.DrawLine(x
+ 1, y2
, x2
, y2
);
1707 dc
.DrawLine(x2
, y
, x2
, y2
);
1709 dc
.SetPen(m_penDarkGrey
);
1710 dc
.DrawLine(x
+ 2, y2
- 1, x2
- 1, y2
- 1);
1711 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
);
1713 if ( flags
& wxCONTROL_SELECTED
)
1715 dc
.SetPen(m_penLightGrey
);
1717 // overwrite the part of the (double!) border above this tab
1718 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
1719 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
1721 // and the shadow of the tab to the left of us
1722 dc
.DrawLine(x
+ 1, y2
- 1, x
+ 1, y
- 1);
1728 wxFAIL_MSG(_T("TODO"));
1732 // ----------------------------------------------------------------------------
1734 // ----------------------------------------------------------------------------
1736 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1737 wxOrientation orient
) const
1739 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1743 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
1744 if ( orient
== wxHORIZONTAL
)
1746 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1747 size
.y
= rectShaft
.height
;
1751 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1752 size
.x
= rectShaft
.width
;
1758 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1759 wxOrientation
WXUNUSED(orient
)) const
1761 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
1764 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
1765 const wxRect
& rectOrig
,
1766 wxOrientation orient
,
1770 wxRect rect
= rectOrig
;
1772 // draw the border first
1773 if ( flags
& wxCONTROL_FOCUSED
)
1775 DrawRect(dc
, &rect
, m_penBlack
);
1776 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1778 else // not focused, normal
1780 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1781 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1784 // and the background
1785 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
1791 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
1792 const wxRect
& rectOrig
,
1793 wxOrientation orient
,
1796 // draw the thumb border
1797 wxRect rect
= rectOrig
;
1798 DrawAntiRaisedBorder(dc
, &rect
);
1800 // draw the handle in the middle
1801 if ( orient
== wxVERTICAL
)
1803 rect
.height
= 2*BORDER_THICKNESS
;
1804 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
1808 rect
.width
= 2*BORDER_THICKNESS
;
1809 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
1812 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1816 // ----------------------------------------------------------------------------
1818 // ----------------------------------------------------------------------------
1820 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
1822 const wxString
& label
,
1826 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE
, indexAccel
);
1829 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
1831 const wxMenuGeometryInfo
& geometryInfo
,
1832 const wxString
& label
,
1833 const wxString
& accel
,
1834 const wxBitmap
& bitmap
,
1838 wxFAIL_MSG(_T("TODO"));
1841 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
1843 const wxMenuGeometryInfo
& geomInfo
)
1845 wxFAIL_MSG(_T("TODO"));
1848 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
1853 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
1854 const wxMenu
& menu
) const
1856 wxFAIL_MSG(_T("TODO"));
1860 #endif // wxUSE_MENUS
1862 // ----------------------------------------------------------------------------
1864 // ----------------------------------------------------------------------------
1866 void wxGTKRenderer::InitComboBitmaps()
1868 wxSize sizeArrow
= m_sizeScrollbarArrow
;
1874 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1876 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
1879 static const int comboButtonFlags
[ComboState_Max
] =
1887 wxRect
rect(wxPoint(0, 0), sizeArrow
);
1890 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1892 int flags
= comboButtonFlags
[n
];
1894 dc
.SelectObject(m_bitmapsCombo
[n
]);
1895 DoDrawBackground(dc
, GetBackgroundColour(flags
), rect
);
1896 DrawArrow(dc
, wxDOWN
, rect
, flags
);
1900 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
1902 wxBitmap
*bmpPressed
,
1903 wxBitmap
*bmpDisabled
)
1905 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
1911 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
1913 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
1915 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
1917 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
1920 // ----------------------------------------------------------------------------
1922 // ----------------------------------------------------------------------------
1924 void wxGTKRenderer::DoDrawBackground(wxDC
& dc
,
1925 const wxColour
& col
,
1928 wxBrush
brush(col
, wxSOLID
);
1930 dc
.SetPen(*wxTRANSPARENT_PEN
);
1931 dc
.DrawRectangle(rect
);
1934 void wxGTKRenderer::DrawBackground(wxDC
& dc
,
1935 const wxColour
& col
,
1939 wxColour colBg
= col
.Ok() ? col
: GetBackgroundColour(flags
);
1940 DoDrawBackground(dc
, colBg
, rect
);
1943 // ----------------------------------------------------------------------------
1945 // ----------------------------------------------------------------------------
1947 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
1951 static const wxDirection sides
[] =
1953 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
1956 wxRect rect1
, rect2
, rectInner
;
1962 rectInner
.Inflate(-2);
1964 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
1966 // find the side not to draw and also adjust the rectangles to compensate
1968 wxDirection sideToOmit
;
1972 sideToOmit
= wxDOWN
;
1974 rectInner
.height
+= 1;
1982 rectInner
.height
+= 1;
1986 sideToOmit
= wxRIGHT
;
1988 rectInner
.width
+= 1;
1992 sideToOmit
= wxLEFT
;
1996 rectInner
.width
+= 1;
2000 wxFAIL_MSG(_T("unknown arrow direction"));
2004 // the outer rect first
2006 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2008 wxDirection side
= sides
[n
];
2009 if ( side
== sideToOmit
)
2012 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
2015 // and then the inner one
2016 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2018 wxDirection side
= sides
[n
];
2019 if ( side
== sideToOmit
)
2022 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
2028 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
2030 const wxRect
& rectArrow
,
2033 // first of all, draw the border around it - but we don't want the border
2034 // on the side opposite to the arrow point
2035 wxRect rect
= rectArrow
;
2036 DrawArrowBorder(dc
, &rect
, dir
);
2038 // then the arrow itself
2039 DrawArrow(dc
, dir
, rect
, flags
);
2042 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
2043 // these people are just crazy :-(
2044 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2057 wxPoint ptArrow
[Point_Max
];
2059 wxColour colInside
= GetBackgroundColour(flags
);
2061 if ( flags
& wxCONTROL_DISABLED
)
2063 penShadow
[0] = m_penDarkGrey
;
2064 penShadow
[1] = m_penDarkGrey
;
2065 penShadow
[2] = wxNullPen
;
2066 penShadow
[3] = wxNullPen
;
2068 else if ( flags
& wxCONTROL_PRESSED
)
2070 penShadow
[0] = m_penDarkGrey
;
2071 penShadow
[1] = m_penHighlight
;
2072 penShadow
[2] = wxNullPen
;
2073 penShadow
[3] = m_penBlack
;
2075 else // normal arrow
2077 penShadow
[0] = m_penHighlight
;
2078 penShadow
[1] = m_penBlack
;
2079 penShadow
[2] = m_penDarkGrey
;
2080 penShadow
[3] = wxNullPen
;
2084 if ( dir
== wxUP
|| dir
== wxDOWN
)
2087 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2091 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2094 // draw the arrow interior
2095 dc
.SetPen(*wxTRANSPARENT_PEN
);
2096 dc
.SetBrush(wxBrush(colInside
, wxSOLID
));
2101 ptArrow
[Point_First
].x
= rect
.GetLeft();
2102 ptArrow
[Point_First
].y
= rect
.GetBottom();
2103 ptArrow
[Point_Second
].x
= middle
;
2104 ptArrow
[Point_Second
].y
= rect
.GetTop();
2105 ptArrow
[Point_Third
].x
= rect
.GetRight();
2106 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2110 ptArrow
[Point_First
] = rect
.GetPosition();
2111 ptArrow
[Point_Second
].x
= middle
;
2112 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2113 ptArrow
[Point_Third
].x
= rect
.GetRight();
2114 ptArrow
[Point_Third
].y
= rect
.GetTop();
2118 ptArrow
[Point_First
].x
= rect
.GetRight();
2119 ptArrow
[Point_First
].y
= rect
.GetTop();
2120 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2121 ptArrow
[Point_Second
].y
= middle
;
2122 ptArrow
[Point_Third
].x
= rect
.GetRight();
2123 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2127 ptArrow
[Point_First
] = rect
.GetPosition();
2128 ptArrow
[Point_Second
].x
= rect
.GetRight();
2129 ptArrow
[Point_Second
].y
= middle
;
2130 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2131 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2135 wxFAIL_MSG(_T("unknown arrow direction"));
2138 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2140 // draw the arrow border
2141 dc
.SetPen(penShadow
[0]);
2145 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2146 dc
.DrawPoint(ptArrow
[Point_First
]);
2147 if ( penShadow
[3].Ok() )
2149 dc
.SetPen(penShadow
[3]);
2150 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2151 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2153 dc
.SetPen(penShadow
[1]);
2154 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2155 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2156 dc
.DrawPoint(ptArrow
[Point_Third
]);
2157 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2158 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2159 if ( penShadow
[2].Ok() )
2161 dc
.SetPen(penShadow
[2]);
2162 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2163 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2164 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2165 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2170 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2171 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2172 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2173 if ( penShadow
[2].Ok() )
2175 dc
.SetPen(penShadow
[2]);
2176 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2177 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2179 dc
.SetPen(penShadow
[1]);
2180 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2181 dc
.DrawPoint(ptArrow
[Point_Third
]);
2185 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2186 dc
.DrawPoint(ptArrow
[Point_First
]);
2187 if ( penShadow
[2].Ok() )
2189 dc
.SetPen(penShadow
[2]);
2190 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2191 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2192 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2193 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2195 dc
.SetPen(penShadow
[1]);
2196 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2197 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2198 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2199 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2203 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2204 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2205 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2206 dc
.SetPen(penShadow
[1]);
2207 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2208 dc
.DrawPoint(ptArrow
[Point_Third
]);
2212 wxFAIL_MSG(_T("unknown arrow direction"));
2217 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2219 wxOrientation orient
)
2221 if ( orient
== wxVERTICAL
)
2223 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2225 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2227 rect
->Inflate(-1, 0);
2229 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2231 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2233 rect
->Inflate(-1, 0);
2237 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2239 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2241 rect
->Inflate(0, -1);
2243 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2245 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2247 rect
->Inflate(0, -1);
2251 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2252 wxOrientation orient
,
2256 // the thumb is never pressed never has focus border under GTK and the
2257 // scrollbar background never changes at all
2258 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2260 // we don't want the border in the direction of the scrollbar movement
2261 wxRect rectThumb
= rect
;
2262 DrawThumbBorder(dc
, &rectThumb
, orient
);
2264 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2265 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2268 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2269 wxOrientation orient
,
2273 wxRect rectBar
= rect
;
2274 DrawThumbBorder(dc
, &rectBar
, orient
);
2275 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2278 void wxGTKRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2280 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2283 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2284 wxScrollBar::Element elem
,
2287 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2288 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2290 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2292 elem
= wxScrollBar::Element_Bar_2
;
2295 return StandardGetScrollbarRect(scrollbar
, elem
,
2297 GetScrollbarArrowSize(scrollbar
));
2300 wxCoord
wxGTKRenderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
2302 return StandardScrollBarSize(scrollbar
, GetScrollbarArrowSize(scrollbar
));
2305 wxHitTest
wxGTKRenderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
2306 const wxPoint
& pt
) const
2308 return StandardHitTestScrollbar(scrollbar
, pt
,
2309 GetScrollbarArrowSize(scrollbar
));
2312 wxCoord
wxGTKRenderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
2315 return StandardScrollbarToPixel(scrollbar
, thumbPos
,
2316 GetScrollbarArrowSize(scrollbar
));
2319 int wxGTKRenderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
2322 return StandardPixelToScrollbar(scrollbar
, coord
,
2323 GetScrollbarArrowSize(scrollbar
));
2326 // ----------------------------------------------------------------------------
2328 // ----------------------------------------------------------------------------
2330 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2333 if ( wxDynamicCast(window
, wxBitmapButton
) )
2338 #endif // wxUSE_BMPBUTTON
2340 if ( wxDynamicCast(window
, wxButton
) )
2342 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2344 // TODO: this is ad hoc...
2345 size
->x
+= 3*window
->GetCharWidth();
2346 wxCoord minBtnHeight
= 18;
2347 if ( size
->y
< minBtnHeight
)
2348 size
->y
= minBtnHeight
;
2350 // button border width
2355 if ( wxDynamicCast(window
, wxScrollBar
) )
2357 // we only set the width of vert scrollbars and height of the
2359 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2360 size
->y
= m_sizeScrollbarArrow
.x
;
2362 size
->x
= m_sizeScrollbarArrow
.x
;
2366 // take into account the border width
2367 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
2368 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
2369 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
2373 // ----------------------------------------------------------------------------
2374 // top level windows
2375 // ----------------------------------------------------------------------------
2377 void wxGTKRenderer::DrawFrameTitleBar(wxDC
& dc
,
2379 const wxString
& title
,
2386 void wxGTKRenderer::DrawFrameBorder(wxDC
& dc
,
2392 void wxGTKRenderer::DrawFrameBackground(wxDC
& dc
,
2398 void wxGTKRenderer::DrawFrameTitle(wxDC
& dc
,
2400 const wxString
& title
,
2405 void wxGTKRenderer::DrawFrameIcon(wxDC
& dc
,
2412 void wxGTKRenderer::DrawFrameButton(wxDC
& dc
,
2413 wxCoord x
, wxCoord y
,
2419 wxRect
wxGTKRenderer::GetFrameClientArea(const wxRect
& rect
, int flags
) const
2424 wxSize
wxGTKRenderer::GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const
2429 wxSize
wxGTKRenderer::GetFrameIconSize() const
2431 return wxSize(-1, -1);
2436 // ============================================================================
2438 // ============================================================================
2440 // ----------------------------------------------------------------------------
2441 // wxGTKInputHandler
2442 // ----------------------------------------------------------------------------
2444 wxGTKInputHandler::wxGTKInputHandler(wxGTKRenderer
*renderer
)
2446 m_renderer
= renderer
;
2449 bool wxGTKInputHandler::HandleKey(wxInputConsumer
*control
,
2450 const wxKeyEvent
& event
,
2456 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
2457 const wxMouseEvent
& event
)
2459 // clicking on the control gives it focus
2460 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
2462 control
->GetInputWindow()->SetFocus();
2470 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
2471 const wxMouseEvent
& event
)
2473 if ( event
.Entering() )
2475 control
->GetInputWindow()->SetCurrent(TRUE
);
2477 else if ( event
.Leaving() )
2479 control
->GetInputWindow()->SetCurrent(FALSE
);
2489 // ----------------------------------------------------------------------------
2490 // wxGTKCheckboxInputHandler
2491 // ----------------------------------------------------------------------------
2493 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
2494 const wxKeyEvent
& event
,
2499 int keycode
= event
.GetKeyCode();
2500 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
2502 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
2511 // ----------------------------------------------------------------------------
2512 // wxGTKTextCtrlInputHandler
2513 // ----------------------------------------------------------------------------
2515 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
2516 const wxKeyEvent
& event
,
2519 // handle only GTK-specific text bindings here, the others are handled in
2523 wxControlAction action
;
2524 int keycode
= event
.GetKeyCode();
2525 if ( event
.ControlDown() )
2530 action
= wxACTION_TEXT_HOME
;
2534 action
= wxACTION_TEXT_LEFT
;
2538 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
2542 action
= wxACTION_TEXT_END
;
2546 action
= wxACTION_TEXT_RIGHT
;
2550 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
2554 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2558 action
= wxACTION_TEXT_DOWN
;
2562 action
= wxACTION_TEXT_UP
;
2566 //delete the entire line
2567 control
->PerformAction(wxACTION_TEXT_HOME
);
2568 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2572 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
2576 else if ( event
.AltDown() )
2581 action
= wxACTION_TEXT_WORD_LEFT
;
2585 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
2589 action
= wxACTION_TEXT_WORD_RIGHT
;
2594 if ( action
!= wxACTION_NONE
)
2596 control
->PerformAction(action
);
2602 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);