diff --git a/include/wx/checkbox.h b/include/wx/checkbox.h index ac6e7e992b..7b59f05211 100644 --- a/include/wx/checkbox.h +++ b/include/wx/checkbox.h @@ -1,21 +1,56 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/checkbox.h +// Purpose: wxCheckBox class interface +// Author: Vadim Zeitlin +// Modified by: +// Created: 07.09.00 +// RCS-ID: $Id$ +// Copyright: (c) wxWindows team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + #ifndef _WX_CHECKBOX_H_BASE_ #define _WX_CHECKBOX_H_BASE_ -#if defined(__WXMSW__) -#include "wx/msw/checkbox.h" +#if wxUSE_CHECKBOX + +#include "wx/control.h" + +WXDLLEXPORT_DATA(extern const wxChar*) wxCheckBoxNameStr; + +// ---------------------------------------------------------------------------- +// wxCheckBox: a control which shows a label and a box which may be checked +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxCheckBoxBase : public wxControl +{ +public: + // set/get the checked status of the listbox + virtual void SetValue(bool value) = 0; + virtual bool GetValue() const = 0; + + bool IsChecked() const { return GetValue(); } +}; + +#if defined(__WXUNIVERSAL__) + #include "wx/univ/checkbox.h" +#elif defined(__WXMSW__) + #include "wx/msw/checkbox.h" #elif defined(__WXMOTIF__) -#include "wx/motif/checkbox.h" + #include "wx/motif/checkbox.h" #elif defined(__WXGTK__) -#include "wx/gtk/checkbox.h" + #include "wx/gtk/checkbox.h" #elif defined(__WXQT__) -#include "wx/qt/checkbox.h" + #include "wx/qt/checkbox.h" #elif defined(__WXMAC__) -#include "wx/mac/checkbox.h" + #include "wx/mac/checkbox.h" #elif defined(__WXPM__) -#include "wx/os2/checkbox.h" + #include "wx/os2/checkbox.h" #elif defined(__WXSTUBS__) -#include "wx/stubs/checkbox.h" + #include "wx/stubs/checkbox.h" #endif +#endif // wxUSE_CHECKBOX + #endif // _WX_CHECKBOX_H_BASE_ diff --git a/include/wx/dc.h b/include/wx/dc.h index 6104ec6f3c..e2d6eb554b 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -256,7 +256,7 @@ public: void DrawRotatedText(const wxString& text, const wxPoint& pt, double angle) { DoDrawRotatedText(text, pt.x, pt.y, angle); } - // this verson puts both optional bitmap and the text into the given + // this version puts both optional bitmap and the text into the given // rectangle and aligns is as specified by alignment parameter; it also // will emphasize the character with the given index if it is != -1 and // return the bounding rectangle if required diff --git a/include/wx/gtk/checkbox.h b/include/wx/gtk/checkbox.h index 562f783397..406787dbd5 100644 --- a/include/wx/gtk/checkbox.h +++ b/include/wx/gtk/checkbox.h @@ -14,31 +14,11 @@ #pragma interface #endif -#include "wx/defs.h" - -#if wxUSE_CHECKBOX - -#include "wx/object.h" -#include "wx/list.h" -#include "wx/control.h" - -//----------------------------------------------------------------------------- -// classes -//----------------------------------------------------------------------------- - -class wxCheckBox; - -//----------------------------------------------------------------------------- -// global data -//----------------------------------------------------------------------------- - -extern const char *wxCheckBoxNameStr; - -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // wxCheckBox -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- -class wxCheckBox: public wxControl +class wxCheckBox : public wxCheckBoxBase { public: wxCheckBox(); @@ -74,7 +54,7 @@ public: GtkWidget *m_widgetCheckbox; GtkWidget *m_widgetLabel; - + protected: virtual wxSize DoGetBestSize() const; diff --git a/include/wx/gtk1/checkbox.h b/include/wx/gtk1/checkbox.h index 562f783397..406787dbd5 100644 --- a/include/wx/gtk1/checkbox.h +++ b/include/wx/gtk1/checkbox.h @@ -14,31 +14,11 @@ #pragma interface #endif -#include "wx/defs.h" - -#if wxUSE_CHECKBOX - -#include "wx/object.h" -#include "wx/list.h" -#include "wx/control.h" - -//----------------------------------------------------------------------------- -// classes -//----------------------------------------------------------------------------- - -class wxCheckBox; - -//----------------------------------------------------------------------------- -// global data -//----------------------------------------------------------------------------- - -extern const char *wxCheckBoxNameStr; - -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // wxCheckBox -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- -class wxCheckBox: public wxControl +class wxCheckBox : public wxCheckBoxBase { public: wxCheckBox(); @@ -74,7 +54,7 @@ public: GtkWidget *m_widgetCheckbox; GtkWidget *m_widgetLabel; - + protected: virtual wxSize DoGetBestSize() const; diff --git a/include/wx/msw/checkbox.h b/include/wx/msw/checkbox.h index 48243f8bb1..97cf1d32b5 100644 --- a/include/wx/msw/checkbox.h +++ b/include/wx/msw/checkbox.h @@ -16,18 +16,10 @@ #pragma interface "checkbox.h" #endif -#if wxUSE_CHECKBOX - -#include "wx/control.h" - -WXDLLEXPORT_DATA(extern const wxChar*) wxCheckBoxNameStr; - // Checkbox item (single checkbox) class WXDLLEXPORT wxBitmap; -class WXDLLEXPORT wxCheckBox : public wxControl +class WXDLLEXPORT wxCheckBox : public wxCheckBoxBase { -DECLARE_DYNAMIC_CLASS(wxCheckBox) - public: wxCheckBox() { } wxCheckBox(wxWindow *parent, wxWindowID id, const wxString& label, @@ -54,6 +46,9 @@ public: protected: virtual wxSize DoGetBestSize() const; + +private: + DECLARE_DYNAMIC_CLASS(wxCheckBox) }; class WXDLLEXPORT wxBitmapCheckBox: public wxCheckBox @@ -83,7 +78,5 @@ public: virtual void SetLabel(const wxBitmap& bitmap); }; -#endif // wxUSE_CHECKBOX - #endif // _WX_CHECKBOX_H_ diff --git a/include/wx/univ/button.h b/include/wx/univ/button.h index b22305bcf5..eaacff1179 100644 --- a/include/wx/univ/button.h +++ b/include/wx/univ/button.h @@ -106,7 +106,7 @@ public: protected: virtual bool PerformAction(const wxControlAction& action, - long numArg = 0, + long numArg = -1, const wxString& strArg = wxEmptyString); virtual wxSize DoGetBestClientSize() const; virtual void DoDraw(wxControlRenderer *renderer); diff --git a/include/wx/univ/checkbox.h b/include/wx/univ/checkbox.h new file mode 100644 index 0000000000..7afd0341fc --- /dev/null +++ b/include/wx/univ/checkbox.h @@ -0,0 +1,113 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/univ/checkbox.h +// Purpose: wxCheckBox declaration +// Author: Vadim Zeitlin +// Modified by: +// Created: 07.09.00 +// RCS-ID: $Id$ +// Copyright: (c) 2000 Vadim Zeitlin +// Licence: wxWindows license +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_UNIV_CHECKBOX_H_ +#define _WX_UNIV_CHECKBOX_H_ + +#ifdef __GNUG__ + #pragma interface "univcheckbox.h" +#endif + +// ---------------------------------------------------------------------------- +// the actions supported by wxCheckBox +// ---------------------------------------------------------------------------- + +#define wxACTION_CHECKBOX_CHECK _T("check") // SetValue(TRUE) +#define wxACTION_CHECKBOX_CLEAR _T("clear") // SetValue(FALSE) +#define wxACTION_CHECKBOX_TOGGLE _T("toggle") // toggle the check state + +// ---------------------------------------------------------------------------- +// wxCheckBox +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxCheckBox : public wxCheckBoxBase +{ +public: + // checkbox constants + enum State + { + State_Normal, + State_Pressed, + State_Disabled, + State_Current, + State_Max + }; + + enum Status + { + Status_Checked, + Status_Unchecked, + Status_Unknown, + Status_Max + }; + + // constructors + wxCheckBox() { Init(); } + + wxCheckBox(wxWindow *parent, + wxWindowID id, + const wxString& label, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxCheckBoxNameStr) + { + Init(); + + Create(parent, id, label, pos, size, style, validator, name); + } + + bool Create(wxWindow *parent, + wxWindowID id, + const wxString& label, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxCheckBoxNameStr); + + // implement the checkbox interface + virtual void SetValue(bool value); + virtual bool GetValue() const; + + // set/get the margin between the checkbox bitmap and the label + void SetMargin(wxCoord margin) { m_checkMargin = margin; } + wxCoord GetMargin() const { return m_checkMargin; } + + // set/get the bitmaps to use for the checkbox indicator + void SetBitmap(const wxBitmap& bmp, State state, Status status); + wxBitmap GetBitmap(State state, Status status) const; + +protected: + virtual bool PerformAction(const wxControlAction& action, + long numArg = -1, + const wxString& strArg = wxEmptyString); + virtual void DoDraw(wxControlRenderer *renderer); + virtual wxSize DoGetBestClientSize() const; + + // common part of all ctors + void Init(); + +private: + // the current check status + Status m_status; + + // the bitmaps to use for the different states + wxBitmap m_bitmaps[State_Max][Status_Max]; + + // the distance between the checkbox and the label (-1 means default) + wxCoord m_checkMargin; + + DECLARE_DYNAMIC_CLASS(wxCheckBox) +}; + +#endif // _WX_UNIV_CHECKBOX_H_ diff --git a/include/wx/univ/colschem.h b/include/wx/univ/colschem.h index 916a28b5e6..be2caf76d3 100644 --- a/include/wx/univ/colschem.h +++ b/include/wx/univ/colschem.h @@ -19,6 +19,7 @@ class WXDLLEXPORT wxWindow; #include "wx/colour.h" +#include "wx/checkbox.h" // ---------------------------------------------------------------------------- // wxColourScheme @@ -63,6 +64,11 @@ public: // get a standard colour virtual wxColour Get(StdColour col) const = 0; +#if wxUSE_CHECKBOX + // get a standard bitmap + virtual wxBitmap Get(wxCheckBox::State state, wxCheckBox::Status status) = 0; +#endif // wxUSE_CHECKBOX + // get the background colour for the given window virtual wxColour GetBackground(wxWindow *win) const = 0; diff --git a/include/wx/univ/inphand.h b/include/wx/univ/inphand.h index a3f031fc54..75c0577c80 100644 --- a/include/wx/univ/inphand.h +++ b/include/wx/univ/inphand.h @@ -206,7 +206,12 @@ protected: class WXDLLEXPORT wxStdListboxInputHandler : public wxStdInputHandler { public: - wxStdListboxInputHandler(wxInputHandler *inphand); + // if pressing the mouse button in a multiselection listbox should toggle + // the item under mouse immediately, then specify TRUE as the second + // parameter (this is the standard behaviour, under GTK the item is toggles + // only when the mouse is released in the multi selection listbox) + wxStdListboxInputHandler(wxInputHandler *inphand, + bool toggleOnPressAlways = TRUE); virtual bool HandleKey(wxControl *control, const wxKeyEvent& event, @@ -224,6 +229,7 @@ protected: wxWindow *m_winCapture; int m_btnCapture; + bool m_toggleOnPressAlways; }; #endif // _WX_UNIV_INPHAND_H_ diff --git a/include/wx/univ/listbox.h b/include/wx/univ/listbox.h index 42cea9ea0a..c428f0a5e6 100644 --- a/include/wx/univ/listbox.h +++ b/include/wx/univ/listbox.h @@ -30,12 +30,15 @@ #define wxACTION_LISTBOX_PAGEUP _T("pageup") // go page up #define wxACTION_LISTBOX_START _T("start") // go to first item #define wxACTION_LISTBOX_END _T("end") // go to last item +#define wxACTION_LISTBOX_FIND _T("find") // find item by 1st letter // do something with the current item #define wxACTION_LISTBOX_ACTIVATE _T("activate") // activate (choose) #define wxACTION_LISTBOX_TOGGLE _T("toggle") // togglee selected state -#define wxACTION_LISTBOX_SELECT _T("select") // select/focus -#define wxACTION_LISTBOX_UNSELECT _T("unselect") // unselect/unfocus +#define wxACTION_LISTBOX_SELECT _T("select") // sel this, unsel others +#define wxACTION_LISTBOX_SELECTADD _T("selectadd") // add to selection +#define wxACTION_LISTBOX_UNSELECT _T("unselect") // unselect +#define wxACTION_LISTBOX_ANCHOR _T("selanchor") // anchor selection // do something with the selection globally (not for single selection ones) #define wxACTION_LISTBOX_SELECTALL _T("selectall") // select all items @@ -123,12 +126,27 @@ public: // select the item which is diff items below the current one void ChangeCurrent(int diff); - // actions - void Activate(int item); + // activate (i.e. send a LISTBOX_DOUBLECLICKED message) the specified or + // current (if -1) item + void Activate(int item = -1); + + // select or unselect the specified or current (if -1) item void Select(bool sel = TRUE, int item = -1); + + // ensure that the current item is visible by scrolling it into view void EnsureVisible(); - void ExtendSelection(int itemTo); + // find the first item after the current one which starts with the given + // string and make it the current one, return TRUE if the current item + // changed + bool FindItem(const wxString& prefix); + + // extend the selection to span the range from the anchor (see below) to + // the specified or current item + void ExtendSelection(int itemTo = -1); + + // make this item the new selection anchor: extending selection with + // ExtendSelection() will work with it void AnchorSelection(int itemFrom) { m_selAnchor = itemFrom; } // get, calculating it if necessary, the number of items per page, the diff --git a/include/wx/univ/renderer.h b/include/wx/univ/renderer.h index 870b8d9067..20bfe6c343 100644 --- a/include/wx/univ/renderer.h +++ b/include/wx/univ/renderer.h @@ -80,13 +80,22 @@ public: // and optionally emphasize the character with the given index virtual void DrawLabel(wxDC& dc, const wxString& label, - const wxBitmap& image, const wxRect& rect, int flags = 0, int alignment = wxALIGN_LEFT | wxALIGN_TOP, int indexAccel = -1, wxRect *rectBounds = NULL) = 0; + // same but also draw a bitmap if it is valid + virtual void DrawButtonLabel(wxDC& dc, + const wxString& label, + const wxBitmap& image, + const wxRect& rect, + int flags = 0, + int alignment = wxALIGN_LEFT | wxALIGN_TOP, + int indexAccel = -1, + wxRect *rectBounds = NULL) = 0; + // draw the border and optionally return the rectangle containing the // region inside the border virtual void DrawBorder(wxDC& dc, @@ -152,6 +161,14 @@ public: // the left/top side, width/heigh - of the right/bottom one virtual wxRect GetBorderDimensions(wxBorder border) const = 0; + // the scrollbar rectangle may need adjusting if the window has the border + // as the renderer might wish to combine the scrollbar border and the + // window one + virtual void AdjustScrollbar(wxOrientation orient, + wxBorder border, + bool hasOtherScrollbar, + wxRect* rect) const = 0; + // adjust the size of the control of the given class: for most controls, // this just takes into account the border, but for some (buttons, for // example) it is more complicated - the result being, in any case, that @@ -230,14 +247,23 @@ public: { m_renderer->DrawBackground(dc, col, rect, flags); } virtual void DrawLabel(wxDC& dc, const wxString& label, - const wxBitmap& image, const wxRect& rect, int flags = 0, int align = wxALIGN_LEFT | wxALIGN_TOP, int indexAccel = -1, wxRect *rectBounds = NULL) - { m_renderer->DrawLabel(dc, label, image, rect, + { m_renderer->DrawLabel(dc, label, rect, flags, align, indexAccel, rectBounds); } + virtual void DrawButtonLabel(wxDC& dc, + const wxString& label, + const wxBitmap& image, + const wxRect& rect, + int flags = 0, + int align = wxALIGN_LEFT | wxALIGN_TOP, + int indexAccel = -1, + wxRect *rectBounds = NULL) + { m_renderer->DrawButtonLabel(dc, label, image, rect, + flags, align, indexAccel, rectBounds); } virtual void DrawBorder(wxDC& dc, wxBorder border, const wxRect& rect, @@ -290,6 +316,11 @@ public: { m_renderer->AdjustSize(size, window); } virtual wxRect GetBorderDimensions(wxBorder border) const { return m_renderer->GetBorderDimensions(border); } + virtual void AdjustScrollbar(wxOrientation orient, + wxBorder border, + bool hasOtherScrollbar, + wxRect* rect) const + { m_renderer->AdjustScrollbar(orient, border, hasOtherScrollbar, rect); } virtual wxRect GetScrollbarRect(const wxScrollBar *scrollbar, wxScrollBar::Element elem, @@ -341,6 +372,7 @@ public: wxStretch stretch = wxSTRETCH_NOT); void DrawBackgroundBitmap(); void DrawScrollbar(const wxScrollBar *scrollbar, int thumbPosOld); + void DrawLabelBox(const wxBitmap& bitmap, wxCoord margin); // accessors wxWindow *GetWindow() const { return m_window; } diff --git a/include/wx/univ/setup.h b/include/wx/univ/setup.h index 99c2b0ac71..8d9551fe50 100644 --- a/include/wx/univ/setup.h +++ b/include/wx/univ/setup.h @@ -69,7 +69,7 @@ #define wxUSE_BUTTON 1 #define wxUSE_BMPBUTTON 1 #define wxUSE_CARET 0 -#define wxUSE_CHECKBOX 0 +#define wxUSE_CHECKBOX 1 #define wxUSE_CHECKLISTBOX 0 #define wxUSE_CHOICE 0 #define wxUSE_COMBOBOX 0 diff --git a/include/wx/univ/theme.h b/include/wx/univ/theme.h index b0a0ea2709..faa0befc0f 100644 --- a/include/wx/univ/theme.h +++ b/include/wx/univ/theme.h @@ -94,14 +94,34 @@ struct WXDLLEXPORT wxThemeInfo wxThemeInfo(Constructor ctor, const wxChar *name, const wxChar *desc); }; +// ---------------------------------------------------------------------------- +// macros +// ---------------------------------------------------------------------------- + +// to use a standard theme insert this macro into one of the application files: +// without it, an over optimizing linker may discard the object module +// containing the theme implementation entirely +#define WX_USE_THEME(themename) \ + extern bool wxThemeUse##themename; \ + static struct wxThemeUserFor##themename \ + { \ + wxThemeUserFor##themename() { wxThemeUse##themename = TRUE; } \ + } wxThemeDoUse##themename + // to declare a new theme, this macro must be used in the class declaration -#define WX_DECLARE_THEME() static wxThemeInfo ms_info +#define WX_DECLARE_THEME(themename) \ + private: \ + static wxThemeInfo ms_info##themename; \ + public: \ + const wxThemeInfo *GetThemeInfo() const \ + { return &ms_info##themename; } // and this one must be inserted in the source file #define WX_IMPLEMENT_THEME(classname, themename, themedesc) \ + extern bool wxThemeUse##themename = TRUE; \ wxTheme *wxCtorFor##themename() { return new classname; } \ - wxThemeInfo classname::ms_info(wxCtorFor##themename, \ - #themename, themedesc) + wxThemeInfo classname::ms_info##themename(wxCtorFor##themename, \ + #themename, themedesc) #endif // _WX_UNIV_THEME_H_ diff --git a/include/wx/wxchar.h b/include/wx/wxchar.h index 6e6e875c54..3d6648cc86 100644 --- a/include/wx/wxchar.h +++ b/include/wx/wxchar.h @@ -165,6 +165,7 @@ typedef _TUCHAR wxUChar; # define wxStrcspn _tcscspn # define wxStrftime _tcsftime # define wxStricmp _tcsicmp +# define wxStrnicmp _tcsnicmp # define wxStrlen_ _tcslen // used in wxStrlen inline function # define wxStrncat _tcsncat # define wxStrncmp _tcsncmp diff --git a/samples/univ/univ.cpp b/samples/univ/univ.cpp index 4b5fb96da0..bac9da5e04 100644 --- a/samples/univ/univ.cpp +++ b/samples/univ/univ.cpp @@ -36,6 +36,7 @@ #include "wx/bmpbuttn.h" #include "wx/button.h" + #include "wx/checkbox.h" #include "wx/listbox.h" #include "wx/scrolbar.h" #include "wx/scrolwin.h" @@ -133,11 +134,18 @@ private: }; // ---------------------------------------------------------------------------- -// event tables +// misc macros // ---------------------------------------------------------------------------- IMPLEMENT_APP(MyUnivApp) +WX_USE_THEME(win32); +WX_USE_THEME(gtk); + +// ---------------------------------------------------------------------------- +// event tables +// ---------------------------------------------------------------------------- + BEGIN_EVENT_TABLE(MyUnivFrame, wxFrame) EVT_BUTTON(-1, MyUnivFrame::OnButton) EVT_LISTBOX(-1, MyUnivFrame::OnListBox) @@ -325,6 +333,8 @@ MyUnivFrame::MyUnivFrame(const wxString& title) lbox->Append(wxString::Format(_T("%sentry %d"), i % 10 ? _T("") : _T("very very long "), i)); } + + new wxCheckBox(this, -1, _T("Check me"), wxPoint(10, 520)); } void MyUnivFrame::OnButton(wxCommandEvent& event) diff --git a/src/msw/app.cpp b/src/msw/app.cpp index 70311095b4..59d1e67109 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -640,8 +640,7 @@ int WXDLLEXPORT wxEntryStart( int WXUNUSED(argc), char** WXUNUSED(argv) ) int WXDLLEXPORT wxEntryInitGui() { - wxTheApp->OnInitGui(); - return 0; + return wxTheApp->OnInitGui(); } void WXDLLEXPORT wxEntryCleanup() @@ -711,10 +710,6 @@ int wxEntry(WXHINSTANCE hInstance, wxTheApp->ConvertToStandardCommandArgs(lpCmdLine); wxTheApp->m_nCmdShow = nCmdShow; - // GUI-specific initialisation. In fact on Windows we don't have any, - // but this call is provided for compatibility across platforms. - wxEntryInitGui(); - // We really don't want timestamps by default, because it means // we can't simply double-click on the error message and get to that // line in the source. So VC++ at least, let's have a sensible default. @@ -724,7 +719,8 @@ int wxEntry(WXHINSTANCE hInstance, int retValue = 0; - if ( wxTheApp->OnInit() ) + // do GUI-specific initialisation and app-specific initialization + if ( wxEntryInitGui() && wxTheApp->OnInit() ) { if ( enterLoop ) { diff --git a/src/univ/checkbox.cpp b/src/univ/checkbox.cpp new file mode 100644 index 0000000000..4f339eafb1 --- /dev/null +++ b/src/univ/checkbox.cpp @@ -0,0 +1,172 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: univ/checkbox.cpp +// Purpose: wxCheckBox implementation +// Author: Vadim Zeitlin +// Modified by: +// Created: 25.08.00 +// RCS-ID: $Id$ +// Copyright: (c) 2000 Vadim Zeitlin +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "univcheckbox.h" +#endif + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_CHECKBOX + +#ifndef WX_PRECOMP + #include "wx/dc.h" + #include "wx/checkbox.h" + #include "wx/validate.h" +#endif + +#include "wx/univ/theme.h" +#include "wx/univ/renderer.h" +#include "wx/univ/colschem.h" + +// ============================================================================ +// implementation +// ============================================================================ + +IMPLEMENT_DYNAMIC_CLASS(wxCheckBox, wxControl) + +// ---------------------------------------------------------------------------- +// wxCheckBox +// ---------------------------------------------------------------------------- + +void wxCheckBox::Init() +{ + m_checkMargin = -1; + m_status = Status_Unchecked; +} + +bool wxCheckBox::Create(wxWindow *parent, + wxWindowID id, + const wxString &label, + const wxPoint &pos, + const wxSize &size, + long style, + const wxValidator& validator, + const wxString &name) +{ + if ( !wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name) ) + return FALSE; + + SetLabel(label); + SetBestSize(size); + + return TRUE; +} + +// ---------------------------------------------------------------------------- +// checkbox interface +// ---------------------------------------------------------------------------- + +bool wxCheckBox::GetValue() const +{ + return m_status == Status_Checked; +} + +void wxCheckBox::SetValue(bool value) +{ + Status status = value ? Status_Checked : Status_Unchecked; + if ( status != m_status ) + { + m_status = status; + + Refresh(); + } +} + +// ---------------------------------------------------------------------------- +// indicator bitmaps +// ---------------------------------------------------------------------------- + +wxBitmap wxCheckBox::GetBitmap(State state, Status status) const +{ + wxBitmap bmp = m_bitmaps[state][m_status]; + if ( !bmp.Ok() ) + bmp = m_bitmaps[State_Normal][m_status]; + if ( !bmp.Ok() ) + bmp = wxTheme::Get()->GetColourScheme()->Get(state, m_status); + + return bmp; +} + +// ---------------------------------------------------------------------------- +// drawing +// ---------------------------------------------------------------------------- + +void wxCheckBox::DoDraw(wxControlRenderer *renderer) +{ + State state; + int flags = GetStateFlags(); + if ( flags & wxCONTROL_DISABLED ) + state = State_Disabled; + else if ( flags & wxCONTROL_PRESSED ) + state = State_Pressed; + else if ( flags & wxCONTROL_CURRENT ) + state = State_Current; + else + state = State_Normal; + + renderer->DrawLabelBox(GetBitmap(state, m_status), m_checkMargin); +} + +// ---------------------------------------------------------------------------- +// geometry calculations +// ---------------------------------------------------------------------------- + +wxSize wxCheckBox::DoGetBestClientSize() const +{ + wxClientDC dc(wxConstCast(this, wxButton)); + wxCoord width, height; + dc.GetMultiLineTextExtent(GetLabel(), &width, &height); + + wxBitmap bmp = GetBitmap(State_Normal, Status_Checked); + if ( height < bmp.GetHeight() ) + height = bmp.GetHeight(); + height += GetCharHeight(); + + width += bmp.GetWidth() + 2*GetCharWidth(); + + return wxSize(width, height); +} + +// ---------------------------------------------------------------------------- +// input handling +// ---------------------------------------------------------------------------- + +bool wxCheckBox::PerformAction(const wxControlAction& action, + long numArg, + const wxString& strArg) +{ + if ( action == wxACTION_CHECKBOX_CHECK ) + SetValue(TRUE); + else if ( action == wxACTION_CHECKBOX_CLEAR ) + SetValue(FALSE); + else if ( action == wxACTION_CHECKBOX_TOGGLE ) + SetValue(!GetValue()); + else + return wxControl::PerformAction(action, numArg, strArg); + + return TRUE; +} + +#endif // wxUSE_CHECKBOX + diff --git a/src/univ/listbox.cpp b/src/univ/listbox.cpp index 8e9b912ac9..000669344e 100644 --- a/src/univ/listbox.cpp +++ b/src/univ/listbox.cpp @@ -94,6 +94,11 @@ bool wxListBox::Create(wxWindow *parent, if ( style & wxLB_ALWAYS_SB ) style |= wxALWAYS_SHOW_SB; + // if we don't have neither multiple nor extended flag, we must have the + // single selection listbox + if ( !(style & (wxLB_MULTIPLE | wxLB_EXTENDED)) ) + style |= wxLB_SINGLE; + if ( !wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name) ) return FALSE; @@ -708,29 +713,50 @@ void wxListBox::SetCurrentItem(int n) if ( m_current != -1 ) { - if ( GetWindowStyle() & wxLB_EXTENDED ) - { - // if we hadn't had any selection before, make the freshly - // selected item the new selection anchor - if ( m_selections.IsEmpty() ) - m_selAnchor = m_current; - } - - if ( !(GetWindowStyle() & wxLB_MULTIPLE) ) - { - // for a single selection listbox, the current item is always - // the one selected - Select(TRUE); - } - m_currentChanged = TRUE; - RefreshItem(n); + RefreshItem(m_current); } } //else: nothing to do } +bool wxListBox::FindItem(const wxString& prefix) +{ + size_t len = prefix.length(); + int count = GetCount(); + for ( int item = m_current + 1; item != m_current; item++ ) + { + if ( item == count ) + { + // wrap + item = 0; + + if ( m_current == -1 ) + break; + } + + if ( wxStrnicmp(m_strings[item], prefix, len) == 0 ) + { + SetCurrentItem(item); + + if ( !(GetWindowStyle() & wxLB_MULTIPLE) ) + { + DeselectAll(item); + Select(TRUE, item); + + if ( GetWindowStyle() & wxLB_EXTENDED ) + AnchorSelection(item); + } + + return TRUE; + } + } + + // nothing found + return FALSE; +} + void wxListBox::EnsureVisible() { if ( !m_showScrollbarY ) @@ -816,11 +842,6 @@ void wxListBox::ExtendSelection(int itemTo) void wxListBox::Select(bool sel, int item) { - if ( sel && !(GetWindowStyle() & wxLB_MULTIPLE) ) - { - DeselectAll(item); - } - if ( item != -1 ) SetCurrentItem(item); @@ -854,16 +875,23 @@ bool wxListBox::PerformAction(const wxControlAction& action, const wxString& strArg) { int item = (int)numArg; - if ( item == -1 ) - item = m_current; if ( action == wxACTION_LISTBOX_SETFOCUS ) SetCurrentItem(item); else if ( action == wxACTION_LISTBOX_ACTIVATE ) Activate(item); else if ( action == wxACTION_LISTBOX_TOGGLE ) + { + if ( item == -1 ) + item = m_current; Select(!IsSelected(item), item); + } else if ( action == wxACTION_LISTBOX_SELECT ) + { + DeselectAll(item); + Select(TRUE, item); + } + else if ( action == wxACTION_LISTBOX_SELECTADD ) Select(TRUE, item); else if ( action == wxACTION_LISTBOX_UNSELECT ) Select(FALSE, item); @@ -883,6 +911,10 @@ bool wxListBox::PerformAction(const wxControlAction& action, DeselectAll(item); else if ( action == wxACTION_LISTBOX_EXTENDSEL ) ExtendSelection(item); + else if ( action == wxACTION_LISTBOX_FIND ) + FindItem(strArg); + else if ( action == wxACTION_LISTBOX_ANCHOR ) + AnchorSelection(item == -1 ? m_current : item); else if ( action == wxACTION_LISTBOX_SELECTALL || action == wxACTION_LISTBOX_SELTOGGLE ) wxFAIL_MSG(_T("unimplemented yet")); @@ -896,11 +928,13 @@ bool wxListBox::PerformAction(const wxControlAction& action, // implementation of wxStdListboxInputHandler // ============================================================================ -wxStdListboxInputHandler::wxStdListboxInputHandler(wxInputHandler *handler) +wxStdListboxInputHandler::wxStdListboxInputHandler(wxInputHandler *handler, + bool toggleOnPressAlways) : wxStdInputHandler(handler) { m_winCapture = NULL; m_btnCapture = 0; + m_toggleOnPressAlways = toggleOnPressAlways; } int wxStdListboxInputHandler::HitTest(const wxListBox *lbox, @@ -910,7 +944,7 @@ int wxStdListboxInputHandler::HitTest(const wxListBox *lbox, lbox->CalcUnscrolledPosition(0, event.GetPosition().y, NULL, &y); int item = y / lbox->GetLineHeight(); - return item < lbox->GetCount() ? item : -1; + return (item >= 0) && (item < lbox->GetCount()) ? item : -1; } bool wxStdListboxInputHandler::HandleKey(wxControl *control, @@ -920,8 +954,14 @@ bool wxStdListboxInputHandler::HandleKey(wxControl *control, // we're only interested in the key press events if ( pressed && !event.AltDown() ) { + bool isMoveCmd = TRUE; + int style = control->GetWindowStyle(); + wxControlAction action; - switch ( event.GetKeyCode() ) + wxString strArg; + + int keycode = event.GetKeyCode(); + switch ( keycode ) { // movement case WXK_UP: action = wxACTION_LISTBOX_MOVEUP; break; @@ -932,18 +972,50 @@ bool wxStdListboxInputHandler::HandleKey(wxControl *control, case WXK_END: action = wxACTION_LISTBOX_END; break; // selection - case WXK_SPACE: action = wxACTION_LISTBOX_TOGGLE; break; - case WXK_RETURN:action = wxACTION_LISTBOX_ACTIVATE; break; + case WXK_SPACE: + if ( style & wxLB_MULTIPLE ) + { + action = wxACTION_LISTBOX_TOGGLE; + isMoveCmd = FALSE; + } + break; + + case WXK_RETURN: + action = wxACTION_LISTBOX_ACTIVATE; + isMoveCmd = FALSE; + break; + + default: + if ( (keycode < 255) && wxIsalnum(keycode) ) + { + action = wxACTION_LISTBOX_FIND; + strArg = (wxChar)keycode; + } } if ( !!action ) { - control->PerformAction(action); + control->PerformAction(action, -1, strArg); - if ( event.ShiftDown() && - (control->GetWindowStyle() & wxLB_EXTENDED) ) + if ( isMoveCmd ) { - control->PerformAction(wxACTION_LISTBOX_EXTENDSEL); + if ( style & wxLB_SINGLE ) + { + // the current item is always the one selected + control->PerformAction(wxACTION_LISTBOX_SELECT); + } + else if ( style & wxLB_EXTENDED ) + { + if ( event.ShiftDown() ) + control->PerformAction(wxACTION_LISTBOX_EXTENDSEL); + else + { + // select the item and make it the new selection anchor + control->PerformAction(wxACTION_LISTBOX_SELECT); + control->PerformAction(wxACTION_LISTBOX_ANCHOR); + } + } + //else: nothing to do for multiple selection listboxes } return TRUE; @@ -987,7 +1059,12 @@ bool wxStdListboxInputHandler::HandleMouse(wxControl *control, wxFAIL_MSG(_T("logic error in listbox mosue handling")); } - action = wxACTION_LISTBOX_TOGGLE; + if ( !m_toggleOnPressAlways ) + { + // in this mode we toggle the item state when the button is + // released, i.e. now + action = wxACTION_LISTBOX_TOGGLE; + } } else if ( event.ButtonDown() ) { @@ -1003,6 +1080,12 @@ bool wxStdListboxInputHandler::HandleMouse(wxControl *control, : event.RightDown() ? 3 : 2; + + if ( m_toggleOnPressAlways ) + { + // toggle the item right now + action = wxACTION_LISTBOX_TOGGLE; + } } else // wxLB_EXTENDED listbox { @@ -1011,7 +1094,8 @@ bool wxStdListboxInputHandler::HandleMouse(wxControl *control, // shift-click adds a range if ( event.ControlDown() ) { - lbox->AnchorSelection(item); + control->PerformAction(wxACTION_LISTBOX_ANCHOR, + item); action = wxACTION_LISTBOX_TOGGLE; } @@ -1021,9 +1105,8 @@ bool wxStdListboxInputHandler::HandleMouse(wxControl *control, } else // simple click { - lbox->AnchorSelection(item); - lbox->PerformAction(wxACTION_LISTBOX_UNSELECTALL, - item); + control->PerformAction(wxACTION_LISTBOX_ANCHOR, + item); action = wxACTION_LISTBOX_SELECT; } diff --git a/src/univ/renderer.cpp b/src/univ/renderer.cpp index 056e21a8d3..f26d4ff9eb 100644 --- a/src/univ/renderer.cpp +++ b/src/univ/renderer.cpp @@ -346,13 +346,13 @@ void wxControlRenderer::DrawLabel(const wxBitmap& bitmap, wxControl *ctrl = wxStaticCast(m_window, wxControl); - m_renderer->DrawLabel(m_dc, - label, - bitmap, - rectLabel, - m_window->GetStateFlags(), - ctrl->GetAlignment(), - ctrl->GetAccelIndex()); + m_renderer->DrawButtonLabel(m_dc, + label, + bitmap, + rectLabel, + m_window->GetStateFlags(), + ctrl->GetAlignment(), + ctrl->GetAccelIndex()); } } @@ -621,3 +621,47 @@ void wxControlRenderer::DrawItems(const wxListBox *lbox, rect.y += lineHeight; } } + +void wxControlRenderer::DrawLabelBox(const wxBitmap& bitmap, wxCoord margin) +{ + m_dc.SetFont(m_window->GetFont()); + m_dc.SetTextForeground(m_window->GetForegroundColour()); + + if ( margin == -1 ) + margin = 4; + + // calculate the position of the bitmap and of the label + wxRect rectBmp; + rectBmp.width = bitmap.GetWidth(); + rectBmp.height = bitmap.GetHeight(); + rectBmp.y = m_rect.y + (m_rect.height - rectBmp.height + 1) / 2; + + wxRect rectLabel; + wxString label = m_window->GetLabel(); + m_dc.GetMultiLineTextExtent(label, NULL, &rectLabel.height); + rectLabel.y = m_rect.y + (m_rect.height - rectLabel.height) / 2; + + if ( m_window->GetWindowStyle() & wxALIGN_RIGHT ) + { + rectBmp.SetRight(m_rect.GetRight()); + rectLabel.SetRight(rectBmp.GetLeft() - margin); + rectLabel.SetLeft(m_rect.GetLeft()); + } + else // normal (checkbox to the left of the text) case + { + rectBmp.SetLeft(m_rect.GetLeft()); + rectLabel.SetLeft(rectBmp.GetRight() + margin); + rectLabel.SetRight(m_rect.GetRight()); + } + + DrawBitmap(bitmap, rectBmp); + + wxControl *ctrl = wxStaticCast(m_window, wxControl); + + m_renderer->DrawLabel(m_dc, + label, + rectLabel, + m_window->GetStateFlags(), + wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, + ctrl->GetAccelIndex()); +} diff --git a/src/univ/theme.cpp b/src/univ/theme.cpp index 71d37bec50..25a873fb50 100644 --- a/src/univ/theme.cpp +++ b/src/univ/theme.cpp @@ -48,7 +48,7 @@ wxTheme *wxTheme::ms_theme = (wxTheme *)NULL; // "dynamic" theme creation // ---------------------------------------------------------------------------- -wxThemeInfo::wxThemeInfo(wxThemeInfo::Constructor c, +wxThemeInfo::wxThemeInfo(Constructor c, const wxChar *n, const wxChar *d) : name(n), desc(d), ctor(c) diff --git a/src/univ/themes/gtk.cpp b/src/univ/themes/gtk.cpp index fb93e54625..c6c50b7d8c 100644 --- a/src/univ/themes/gtk.cpp +++ b/src/univ/themes/gtk.cpp @@ -58,12 +58,19 @@ public: int flags = 0); virtual void DrawLabel(wxDC& dc, const wxString& label, - const wxBitmap& image, const wxRect& rect, int flags = 0, int alignment = wxALIGN_LEFT | wxALIGN_TOP, int indexAccel = -1, wxRect *rectBounds = NULL); + virtual void DrawButtonLabel(wxDC& dc, + const wxString& label, + const wxBitmap& image, + const wxRect& rect, + int flags = 0, + int alignment = wxALIGN_LEFT | wxALIGN_TOP, + int indexAccel = -1, + wxRect *rectBounds = NULL); virtual void DrawBorder(wxDC& dc, wxBorder border, const wxRect& rect, @@ -104,6 +111,10 @@ public: virtual void AdjustSize(wxSize *size, const wxWindow *window); virtual wxRect GetBorderDimensions(wxBorder border) const; + virtual void AdjustScrollbar(wxOrientation orient, + wxBorder border, + bool hasOtherScrollbar, + wxRect* rect) const; // hit testing for the input handlers virtual wxRect GetScrollbarRect(const wxScrollBar *scrollbar, @@ -273,6 +284,9 @@ class wxGTKColourScheme : public wxColourScheme public: virtual wxColour Get(StdColour col) const; virtual wxColour GetBackground(wxWindow *win) const; +#if wxUSE_CHECKBOX + virtual wxBitmap Get(wxCheckBox::State state, wxCheckBox::Status status); +#endif // wxUSE_CHECKBOX }; // ---------------------------------------------------------------------------- @@ -301,7 +315,7 @@ private: wxGTKColourScheme *m_scheme; - WX_DECLARE_THEME(); + WX_DECLARE_THEME(gtk) }; // ============================================================================ @@ -338,7 +352,7 @@ wxInputHandler *wxGTKTheme::GetInputHandler(const wxString& control) handler = new wxGTKScrollBarInputHandler(m_renderer, GetInputHandler(_T("wxControl"))); else if ( control == _T("wxListBox") ) - handler = new wxStdListboxInputHandler(GetInputHandler(_T("wxControl"))); + handler = new wxStdListboxInputHandler(GetInputHandler(_T("wxControl")), FALSE); else handler = new wxGTKInputHandler(m_renderer); @@ -430,6 +444,16 @@ wxColour wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col) const } } +#if wxUSE_CHECKBOX + +wxBitmap wxGTKColourScheme::Get(wxCheckBox::State state, + wxCheckBox::Status status) +{ + return wxNullBitmap; +} + +#endif // wxUSE_CHECKBOX + // ============================================================================ // wxGTKRenderer // ============================================================================ @@ -644,6 +668,34 @@ wxRect wxGTKRenderer::GetBorderDimensions(wxBorder border) const return rect; } +void wxGTKRenderer::AdjustScrollbar(wxOrientation orient, + wxBorder border, + bool hasOtherScrollbar, + wxRect* rect) const +{ + wxRect rectBorder = GetBorderDimensions(border); + + if ( orient == wxVERTICAL ) + { + // blend the top and right scrollbar borders into the window border + rect->y -= rectBorder.y; + rect->x += rectBorder.width; + + // if there is no horz scrollbar, also do it with the bottom one + if ( !hasOtherScrollbar ) + rect->height += rectBorder.height; + } + else // wxHORIZONTAL + { + // the logic is the same as above + rect->x -= rectBorder.x; + rect->y += rectBorder.height; + + if ( !hasOtherScrollbar ) + rect->width += rectBorder.width; + } +} + // ---------------------------------------------------------------------------- // button border // ---------------------------------------------------------------------------- @@ -740,8 +792,7 @@ void wxGTKRenderer::DrawFrame(wxDC& dc, rectText.height = height; wxRect rectLabel; - DrawLabel(dc, label, wxNullBitmap, - rectText, flags, alignment, indexAccel, &rectLabel); + DrawLabel(dc, label, rectText, flags, alignment, indexAccel, &rectLabel); rectLabel.x -= 1; rectLabel.width += 2; @@ -766,12 +817,24 @@ void wxGTKRenderer::DrawFrame(wxDC& dc, void wxGTKRenderer::DrawLabel(wxDC& dc, const wxString& label, - const wxBitmap& image, const wxRect& rect, int flags, int alignment, int indexAccel, wxRect *rectBounds) +{ + DrawButtonLabel(dc, label, wxNullBitmap, rect, flags, + alignment, indexAccel, rectBounds); +} + +void wxGTKRenderer::DrawButtonLabel(wxDC& dc, + const wxString& label, + const wxBitmap& image, + const wxRect& rect, + int flags, + int alignment, + int indexAccel, + wxRect *rectBounds) { if ( flags & wxCONTROL_DISABLED ) { diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index ed5e7ad331..4cf5f31fab 100644 --- a/src/univ/themes/win32.cpp +++ b/src/univ/themes/win32.cpp @@ -24,6 +24,20 @@ #pragma hdrstop #endif +extern int foo = 0; + +static struct Foo +{ + Foo(); +} s_foo; + +Foo::Foo() +{ + int x; + x = 1; + x++; +} + #ifndef WX_PRECOMP #include "wx/timer.h" #include "wx/intl.h" @@ -76,12 +90,19 @@ public: int flags = 0); virtual void DrawLabel(wxDC& dc, const wxString& label, - const wxBitmap& image, const wxRect& rect, int flags = 0, int alignment = wxALIGN_LEFT | wxALIGN_TOP, int indexAccel = -1, wxRect *rectBounds = NULL); + virtual void DrawButtonLabel(wxDC& dc, + const wxString& label, + const wxBitmap& image, + const wxRect& rect, + int flags = 0, + int alignment = wxALIGN_LEFT | wxALIGN_TOP, + int indexAccel = -1, + wxRect *rectBounds = NULL); virtual void DrawBorder(wxDC& dc, wxBorder border, const wxRect& rect, @@ -122,6 +143,10 @@ public: virtual void AdjustSize(wxSize *size, const wxWindow *window); virtual wxRect GetBorderDimensions(wxBorder border) const; + virtual void AdjustScrollbar(wxOrientation orient, + wxBorder border, + bool hasOtherScrollbar, + wxRect* rect) const; virtual wxRect GetScrollbarRect(const wxScrollBar *scrollbar, wxScrollBar::Element elem, @@ -139,6 +164,13 @@ protected: // common part of DrawLabel() and DrawItem() void DrawFocusRect(wxDC& dc, const wxRect& rect); + // DrawLabel() and DrawButtonLabel() helper + void DrawLabelShadow(wxDC& dc, + const wxString& label, + const wxRect& rect, + int alignment, + int indexAccel); + // DrawButtonBorder() helper void DoDrawBackground(wxDC& dc, const wxColour& col, @@ -250,8 +282,11 @@ protected: class wxWin32ColourScheme : public wxColourScheme { public: - virtual wxColour Get(StdColour col, int flags = 0) const; - virtual wxColour GetBackground(wxWindow *win); + virtual wxColour Get(StdColour col) const; + virtual wxColour GetBackground(wxWindow *win) const; +#if wxUSE_CHECKBOX + virtual wxBitmap Get(wxCheckBox::State state, wxCheckBox::Status status); +#endif // wxUSE_CHECKBOX }; // ---------------------------------------------------------------------------- @@ -268,7 +303,7 @@ public: virtual wxRenderer *GetRenderer() { return m_renderer; } virtual wxInputHandler *GetInputHandler(const wxString& control); - virtual wxColourScheme *GetColourScheme(const wxString& control); + virtual wxColourScheme *GetColourScheme(); private: wxWin32Renderer *m_renderer; @@ -280,7 +315,7 @@ private: wxWin32ColourScheme *m_scheme; - WX_DECLARE_THEME(); + WX_DECLARE_THEME(win32) }; // ============================================================================ @@ -335,9 +370,8 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control) return handler; } -wxColourScheme *wxWin32Theme::GetColourScheme(const wxString& control) +wxColourScheme *wxWin32Theme::GetColourScheme() { - // Win32 has only one colour scheme for all controls return m_scheme; } @@ -345,31 +379,68 @@ wxColourScheme *wxWin32Theme::GetColourScheme(const wxString& control) // wxWin32ColourScheme // ============================================================================ -wxColour wxWin32ColourScheme::GetBackground(wxWindow *win) +wxColour wxWin32ColourScheme::GetBackground(wxWindow *win) const { - return win->GetBackgroundColour(); + wxColour col; + if ( win->UseBgCol() ) + { + // use the user specified colour + col = win->GetBackgroundColour(); + } + + if ( win->IsContainerWindow() ) + { + // doesn't depend on the state + if ( !col.Ok() ) + { + col = Get(WINDOW); + } + } + else + { + int flags = win->GetStateFlags(); + + // the colour set by the user should be used for the normal state + // and for the states for which we don't have any specific colours + if ( !col.Ok() || (flags != 0) ) + { + if ( wxDynamicCast(win, wxScrollBar) ) + col = Get(flags & wxCONTROL_PRESSED ? SCROLLBAR_PRESSED + : SCROLLBAR); + else + col = Get(CONTROL); + } + } + + return col; } -wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col, - int flags) const +wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col) const { switch ( col ) { case WINDOW: return *wxWHITE; + case CONTROL_PRESSED: + case CONTROL_CURRENT: case CONTROL: return wxColour(0xc0c0c0); + case CONTROL_TEXT: return *wxBLACK; - case SCROLLBAR: if ( flags & wxCONTROL_PRESSED ) - return *wxBLACK; - else - return wxColour(0xe0e0e0); + + case SCROLLBAR: return wxColour(0xe0e0e0); + case SCROLLBAR_PRESSED: return *wxBLACK; case HIGHLIGHT: return wxColour(0x800000); case HIGHLIGHT_TEXT: return wxColour(0xffffff); case SHADOW_DARK: return *wxBLACK; + + case CONTROL_TEXT_DISABLED: case SHADOW_HIGHLIGHT: return wxColour(0xe0e0e0); + case SHADOW_IN: return wxColour(0xc0c0c0); + + case CONTROL_TEXT_DISABLED_SHADOW: case SHADOW_OUT: return wxColour(0x7f7f7f); case MAX: @@ -379,6 +450,18 @@ wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col, } } +#if wxUSE_CHECKBOX + +wxBitmap wxWin32ColourScheme::Get(wxCheckBox::State state, + wxCheckBox::Status status) +{ + return wxBitmap(status == wxCheckBox::Status_Checked ? _T("check.bmp") + : _T("uncheck.bmp"), + wxBITMAP_TYPE_BMP); +} + +#endif // wxUSE_CHECKBOX + // ============================================================================ // wxWin32Renderer // ============================================================================ @@ -394,14 +477,14 @@ wxWin32Renderer::wxWin32Renderer(const wxColourScheme *scheme) m_sizeScrollbarArrow = wxSize(16, 16); // init colours and pens - m_penBlack = wxPen(scheme->Get(wxColourScheme::SHADOW_DARK), 0, wxSOLID); + m_penBlack = wxPen(wxSCHEME_COLOUR(scheme, SHADOW_DARK), 0, wxSOLID); - m_colDarkGrey = scheme->Get(wxColourScheme::SHADOW_OUT); + m_colDarkGrey = wxSCHEME_COLOUR(scheme, SHADOW_OUT); m_penDarkGrey = wxPen(m_colDarkGrey, 0, wxSOLID); - m_penLightGrey = wxPen(scheme->Get(wxColourScheme::SHADOW_IN), 0, wxSOLID); + m_penLightGrey = wxPen(wxSCHEME_COLOUR(scheme, SHADOW_IN), 0, wxSOLID); - m_colHighlight = scheme->Get(wxColourScheme::SHADOW_HIGHLIGHT); + m_colHighlight = wxSCHEME_COLOUR(scheme, SHADOW_HIGHLIGHT); m_penHighlight = wxPen(m_colHighlight, 0, wxSOLID); // init the arrow bitmaps @@ -771,6 +854,14 @@ wxRect wxWin32Renderer::GetBorderDimensions(wxBorder border) const return rect; } +void wxWin32Renderer::AdjustScrollbar(wxOrientation orient, + wxBorder border, + bool hasOtherScrollbar, + wxRect* rect) const +{ + // don't do anything - we don't blend scrollbars into borders +} + // ---------------------------------------------------------------------------- // button border // ---------------------------------------------------------------------------- @@ -872,8 +963,7 @@ void wxWin32Renderer::DrawFrame(wxDC& dc, } wxRect rectLabel; - DrawLabel(dc, label2, wxNullBitmap, - rectText, flags, alignment, indexAccel, &rectLabel); + DrawLabel(dc, label2, rectText, flags, alignment, indexAccel, &rectLabel); StandardDrawFrame(dc, rectFrame, rectLabel); } @@ -928,14 +1018,54 @@ void wxWin32Renderer::DrawFocusRect(wxDC& dc, const wxRect& rect) #endif // 0/1 } +void wxWin32Renderer::DrawLabelShadow(wxDC& dc, + const wxString& label, + const wxRect& rect, + int alignment, + int indexAccel) +{ + // make the text grey and draw a shadow of it + dc.SetTextForeground(m_colHighlight); + wxRect rectShadow = rect; + rectShadow.x++; + rectShadow.y++; + dc.DrawLabel(label, rectShadow, alignment, indexAccel); + dc.SetTextForeground(m_colDarkGrey); +} + void wxWin32Renderer::DrawLabel(wxDC& dc, const wxString& label, - const wxBitmap& image, const wxRect& rect, int flags, int alignment, int indexAccel, wxRect *rectBounds) +{ + if ( flags & wxCONTROL_DISABLED ) + { + DrawLabelShadow(dc, label, rect, alignment, indexAccel); + } + + wxRect rectLabel; + dc.DrawLabel(label, wxNullBitmap, rect, alignment, indexAccel, &rectLabel); + + if ( flags & wxCONTROL_FOCUSED ) + { + DrawFocusRect(dc, rectLabel); + } + + if ( rectBounds ) + *rectBounds = rectLabel; +} + +void wxWin32Renderer::DrawButtonLabel(wxDC& dc, + const wxString& label, + const wxBitmap& image, + const wxRect& rect, + int flags, + int alignment, + int indexAccel, + wxRect *rectBounds) { // shift the label if a button is pressed wxRect rectLabel = rect; @@ -947,13 +1077,7 @@ void wxWin32Renderer::DrawLabel(wxDC& dc, if ( flags & wxCONTROL_DISABLED ) { - // make the text grey and draw a shadow of it - dc.SetTextForeground(m_colHighlight); - wxRect rectShadow = rectLabel; - rectShadow.x++; - rectShadow.y++; - dc.DrawLabel(label, rectShadow, alignment, indexAccel); - dc.SetTextForeground(m_colDarkGrey); + DrawLabelShadow(dc, label, rectLabel, alignment, indexAccel); } // leave enough space for the focus rectangle @@ -989,9 +1113,9 @@ void wxWin32Renderer::DrawItem(wxDC& dc, wxColour colFg; if ( flags & wxCONTROL_SELECTED ) { - wxColour colBg = m_scheme->Get(wxColourScheme::HIGHLIGHT); + wxColour colBg = wxSCHEME_COLOUR(m_scheme, HIGHLIGHT); colFg = dc.GetTextForeground(); - dc.SetTextForeground(m_scheme->Get(wxColourScheme::HIGHLIGHT_TEXT)); + dc.SetTextForeground(wxSCHEME_COLOUR(m_scheme, HIGHLIGHT_TEXT)); dc.SetBrush(wxBrush(colBg, wxSOLID)); dc.SetPen(wxPen(colBg, 0, wxSOLID)); dc.DrawRectangle(rect); @@ -1033,11 +1157,9 @@ void wxWin32Renderer::DrawBackground(wxDC& dc, const wxRect& rect, int flags) { - // just fill it with the default bg colour - DoDrawBackground(dc, - col.Ok() ? col - : m_scheme->Get(wxColourScheme::CONTROL, flags), - rect); + // just fill it with the given or default bg colour + wxColour colBg = col.Ok() ? col : wxSCHEME_COLOUR(m_scheme, CONTROL); + DoDrawBackground(dc, colBg, rect); } // ---------------------------------------------------------------------------- @@ -1103,7 +1225,7 @@ void wxWin32Renderer::DrawArrowButton(wxDC& dc, wxArrowStyle arrowStyle) { wxRect rect = rectAll; - DoDrawBackground(dc, m_scheme->Get(wxColourScheme::CONTROL), rect); + DoDrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), rect); DrawArrowBorder(dc, &rect, arrowStyle == Arrow_Pressed); DrawArrow(dc, rect, arrowDir, arrowStyle); } @@ -1124,13 +1246,15 @@ void wxWin32Renderer::DrawScrollbarShaft(wxDC& dc, const wxRect& rectBar, int flags) { - DoDrawBackground(dc, m_scheme->Get(wxColourScheme::SCROLLBAR, flags), - rectBar); + wxColourScheme::StdColour col = flags & wxCONTROL_PRESSED + ? wxColourScheme::SCROLLBAR_PRESSED + : wxColourScheme::SCROLLBAR; + DoDrawBackground(dc, m_scheme->Get(col), rectBar); } void wxWin32Renderer::DrawScrollCorner(wxDC& dc, const wxRect& rect) { - DoDrawBackground(dc, m_scheme->Get(wxColourScheme::CONTROL), rect); + DoDrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), rect); } wxRect wxWin32Renderer::GetScrollbarRect(const wxScrollBar *scrollbar, diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index 2d67e4d688..21485b1e27 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -139,6 +139,13 @@ const wxBitmap& wxWindow::GetBackgroundBitmap(int *alignment, // the event handler executed when the window background must be painted void wxWindow::OnErase(wxEraseEvent& event) { + if ( !m_renderer ) + { + event.Skip(); + + return; + } + wxControlRenderer renderer(this, *event.GetDC(), m_renderer); DoDrawBackground(&renderer); @@ -147,11 +154,16 @@ void wxWindow::OnErase(wxEraseEvent& event) // them which we must paint if ( m_scrollbarVert && m_scrollbarHorz ) { + wxSize size = GetSize(); + wxRect rectClient = GetClientRect(), + rectBorder = m_renderer->GetBorderDimensions(GetBorder()); + wxRect rectCorner; - rectCorner.x = m_scrollbarHorz->GetSize().x; - rectCorner.y = m_scrollbarVert->GetSize().y; - rectCorner.width = m_scrollbarVert->GetSize().x; - rectCorner.height = m_scrollbarHorz->GetSize().y; + rectCorner.x = rectClient.GetRight() + 1; + rectCorner.y = rectClient.GetBottom() + 1; + rectCorner.SetRight(size.x - rectBorder.width); + rectCorner.SetBottom(size.y - rectBorder.height); + m_renderer->DrawScrollCorner(*event.GetDC(), rectCorner); } } @@ -309,27 +321,25 @@ void wxWindow::DoGetClientSize(int *width, int *height) const if ( m_renderer ) rectBorder = m_renderer->GetBorderDimensions(GetBorder()); - // TODO these calculations suppose that we position the scrollbars in such - // way that they overwrite some borders - when this is changed (see - // the next todo item below) this code must be updated too + // TODO we should be smarter about combining the scrollbar borders with + // the window ones - so far we just blend the right and bottom + // borders of the vertical scrollbar (and left/bottom of the + // horizontal one) into the window border, but this risks to look + // ugly with other renderers/border styles if ( width ) { if ( m_scrollbarVert ) *width -= m_scrollbarVert->GetSize().x; - else - *width -= rectBorder.width; - *width -= rectBorder.x; + *width -= rectBorder.x + rectBorder.width; } if ( height ) { if ( m_scrollbarHorz ) *height -= m_scrollbarHorz->GetSize().y; - else - *height -= rectBorder.height; - *height -= rectBorder.y; + *height -= rectBorder.y + rectBorder.height; } } @@ -342,29 +352,30 @@ void wxWindow::DoGetClientSize(int *width, int *height) const void wxWindow::PositionScrollbars() { wxRect rectClient = GetClientRect(), - rectTotal = wxRect(wxPoint(0, 0), GetSize()); + rectBar; - // TODO we should be smarter about combining the scrollbar borders with - // the window ones - so far we just blend the right and bottom - // borders of the vertical scrollbar (and left/bottom of the - // horizontal one) into the window border, but this risks to look - // ugly with other renderers/border styles if ( m_scrollbarVert ) { - m_scrollbarVert->SetSize(rectClient.GetRight() + 1, - rectTotal.GetTop(), - m_scrollbarVert->GetSize().x, - m_scrollbarHorz ? rectClient.GetBottom() + 1 - : rectTotal.GetBottom() + 1); + rectBar.x = rectClient.GetRight() + 1; + rectBar.y = rectClient.GetTop(); + rectBar.width = m_scrollbarVert->GetSize().x; + rectBar.height = rectClient.GetHeight(); + m_renderer->AdjustScrollbar(wxVERTICAL, GetBorder(), + m_scrollbarHorz != NULL, &rectBar); + + m_scrollbarVert->SetSize(rectBar, wxSIZE_NO_ADJUSTMENTS); } if ( m_scrollbarHorz ) { - m_scrollbarHorz->SetSize(rectTotal.GetLeft(), - rectClient.GetBottom() + 1, - m_scrollbarVert ? rectClient.GetRight() + 1 - : rectTotal.GetRight() + 1, - m_scrollbarHorz->GetSize().y); + rectBar.x = rectClient.GetLeft(); + rectBar.y = rectClient.GetBottom() + 1; + rectBar.width = rectClient.GetWidth(); + rectBar.height = m_scrollbarHorz->GetSize().y; + m_renderer->AdjustScrollbar(wxHORIZONTAL, GetBorder(), + m_scrollbarVert != NULL, &rectBar); + + m_scrollbarHorz->SetSize(rectBar, wxSIZE_NO_ADJUSTMENTS); } }