From 0ddd59282bbc8d4f2679a6c823fc22fe01e94d72 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 12 Sep 2000 17:30:09 +0000 Subject: [PATCH] 1. now clip wxPaintDC in its ctor 2. added wxCheckListBox git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8345 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/checklst.h | 47 ++++++++++-- include/wx/chkconf.h | 11 +++ include/wx/gtk/checklst.h | 17 ----- include/wx/gtk1/checklst.h | 17 ----- include/wx/univ/checklst.h | 74 ++++++++++++++++++ include/wx/univ/listbox.h | 9 ++- include/wx/univ/renderer.h | 8 ++ samples/univ/univ.cpp | 7 ++ src/generic/scrolwin.cpp | 2 +- src/gtk/dcclient.cpp | 4 +- src/gtk1/dcclient.cpp | 4 +- src/univ/checklst.cpp | 152 +++++++++++++++++++++++++++++++++++++ src/univ/files.lst | 2 + src/univ/listbox.cpp | 23 ++---- src/univ/renderer.cpp | 30 +++++++- 15 files changed, 342 insertions(+), 65 deletions(-) create mode 100644 include/wx/univ/checklst.h create mode 100644 src/univ/checklst.cpp diff --git a/include/wx/checklst.h b/include/wx/checklst.h index 4528bb8f84..955c533445 100644 --- a/include/wx/checklst.h +++ b/include/wx/checklst.h @@ -1,21 +1,52 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/checklst.h +// Purpose: wxCheckListBox class interface +// Author: Vadim Zeitlin +// Modified by: +// Created: 12.09.00 +// RCS-ID: $Id$ +// Copyright: (c) Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + #ifndef _WX_CHECKLST_H_BASE_ #define _WX_CHECKLST_H_BASE_ -#if defined(__WXMSW__) -#include "wx/msw/checklst.h" +#if wxUSE_CHECKLISTBOX + +#include "wx/listbox.h" + +// ---------------------------------------------------------------------------- +// wxCheckListBox: a listbox whose items may be checked +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxCheckListBoxBase : public wxListBox +{ +public: + // check list box specific methods + virtual bool IsChecked(size_t item) const = 0; + virtual void Check(size_t item, bool check = TRUE) = 0; +}; + +#if defined(__WXUNIVERSAL__) + #include "wx/univ/checklst.h" +#elif defined(__WXMSW__) + #include "wx/msw/checklst.h" #elif defined(__WXMOTIF__) -#include "wx/motif/checklst.h" + #include "wx/motif/checklst.h" #elif defined(__WXGTK__) -#include "wx/gtk/checklst.h" + #include "wx/gtk/checklst.h" #elif defined(__WXQT__) -#include "wx/qt/checklst.h" + #include "wx/qt/checklst.h" #elif defined(__WXMAC__) -#include "wx/mac/checklst.h" + #include "wx/mac/checklst.h" #elif defined(__WXPM__) -#include "wx/os2/checklst.h" + #include "wx/os2/checklst.h" #elif defined(__WXSTUBS__) -#include "wx/stubs/checklst.h" + #include "wx/stubs/checklst.h" #endif +#endif // wxUSE_CHECKLISTBOX + #endif // _WX_CHECKLST_H_BASE_ diff --git a/include/wx/chkconf.h b/include/wx/chkconf.h index 8d055d7758..9ffdd73089 100644 --- a/include/wx/chkconf.h +++ b/include/wx/chkconf.h @@ -57,6 +57,17 @@ # endif #endif /* controls */ +#if wxUSE_CHECKLISTBOX +# if !wxUSE_LISTBOX +# ifdef wxABORT_ON_CONFIG_ERROR +# error "wxCheckListBox requires wxListBox" +# else +# undef wxUSE_LISTBOX +# define wxUSE_LISTBOX 1 +# endif +# endif +#endif /* wxUSE_RADIOBTN */ + #if wxUSE_RADIOBTN # if defined(__WXUNIVERSAL__) && !wxUSE_CHECKBOX # ifdef wxABORT_ON_CONFIG_ERROR diff --git a/include/wx/gtk/checklst.h b/include/wx/gtk/checklst.h index 3290184e06..37347791f1 100644 --- a/include/wx/gtk/checklst.h +++ b/include/wx/gtk/checklst.h @@ -15,21 +15,6 @@ #pragma interface #endif -#include "wx/defs.h" - -#if wxUSE_CHECKLISTBOX - -#include "wx/object.h" -#include "wx/list.h" -#include "wx/control.h" -#include "wx/listbox.h" - -//----------------------------------------------------------------------------- -// classes -//----------------------------------------------------------------------------- - -class wxCheckListBox; - //----------------------------------------------------------------------------- // wxCheckListBox //----------------------------------------------------------------------------- @@ -56,6 +41,4 @@ private: DECLARE_DYNAMIC_CLASS(wxCheckListBox) }; -#endif - #endif //__GTKCHECKLISTH__ diff --git a/include/wx/gtk1/checklst.h b/include/wx/gtk1/checklst.h index 3290184e06..37347791f1 100644 --- a/include/wx/gtk1/checklst.h +++ b/include/wx/gtk1/checklst.h @@ -15,21 +15,6 @@ #pragma interface #endif -#include "wx/defs.h" - -#if wxUSE_CHECKLISTBOX - -#include "wx/object.h" -#include "wx/list.h" -#include "wx/control.h" -#include "wx/listbox.h" - -//----------------------------------------------------------------------------- -// classes -//----------------------------------------------------------------------------- - -class wxCheckListBox; - //----------------------------------------------------------------------------- // wxCheckListBox //----------------------------------------------------------------------------- @@ -56,6 +41,4 @@ private: DECLARE_DYNAMIC_CLASS(wxCheckListBox) }; -#endif - #endif //__GTKCHECKLISTH__ diff --git a/include/wx/univ/checklst.h b/include/wx/univ/checklst.h new file mode 100644 index 0000000000..5435127cdc --- /dev/null +++ b/include/wx/univ/checklst.h @@ -0,0 +1,74 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/univ/checklst.h +// Purpose: wxCheckListBox class for wxUniversal +// Author: Vadim Zeitlin +// Modified by: +// Created: 12.09.00 +// RCS-ID: $Id$ +// Copyright: (c) Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_UNIV_CHECKLST_H_ +#define _WX_UNIV_CHECKLST_H_ + +#ifdef __GNUG__ + #pragma interface "univchecklst.h" +#endif + +class WXDLLEXPORT wxCheckListBox : public wxCheckListBoxBase +{ +public: + // ctors + wxCheckListBox() { Init(); } + + wxCheckListBox(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + int nStrings = 0, + const wxString *choices = NULL, + long style = 0, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxListBoxNameStr) + { + Init(); + + Create(parent, id, pos, size, nStrings, choices, style, validator, name); + } + + // no Create(): the base class does everything + + // implement check list box methods + virtual bool IsChecked(size_t item) const; + virtual void Check(size_t item, bool check = TRUE); + + // override all methods which add/delete items to update m_checks array as + // well + virtual void Delete(int n); + +protected: + virtual int DoAppend(const wxString& item); + virtual void DoInsertItems(const wxArrayString& items, int pos); + virtual void DoSetItems(const wxArrayString& items, void **clientData); + virtual void DoClear(); + + // draw the check items instead of the usual ones + virtual void DoDrawRange(wxControlRenderer *renderer, + int itemFirst, int itemLast); + + // take them also into account for size calculation + virtual wxSize DoGetBestClientSize() const; + + // common part of all ctors + void Init(); + +private: + // the array containing the checked status of the items + wxArrayInt m_checks; + + DECLARE_DYNAMIC_CLASS(wxCheckListBox) +}; + +#endif // _WX_UNIV_CHECKLST_H_ + diff --git a/include/wx/univ/listbox.h b/include/wx/univ/listbox.h index 87c86aaaba..d35e8f8321 100644 --- a/include/wx/univ/listbox.h +++ b/include/wx/univ/listbox.h @@ -115,7 +115,8 @@ public: virtual void Refresh( bool eraseBackground = TRUE, const wxRect *rect = (const wxRect *) NULL ); - // the wxUniversal-specific additions + // the wxUniversal-specific methods + // -------------------------------- // the current item is the same as the selected one for wxLB_SINGLE // listboxes but for the other ones it is just the focused item which may @@ -178,7 +179,7 @@ protected: void OnSize(wxSizeEvent& event); // common part of Clear() and DoSetItems(): clears everything - void DoClear(); + virtual void DoClear(); // refresh the given item(s) or everything void RefreshItems(int from, int count); @@ -195,6 +196,10 @@ protected: bool HasHorzScrollbar() const { return (m_windowStyle & wxLB_HSCROLL) != 0; } + // redraw the items in the given range only: called from DoDraw() + virtual void DoDrawRange(wxControlRenderer *renderer, + int itemFirst, int itemLast); + // the array containing all items (it is sorted if the listbox has // wxLB_SORT style) wxArrayString m_strings; diff --git a/include/wx/univ/renderer.h b/include/wx/univ/renderer.h index 4f78749419..ec7066031b 100644 --- a/include/wx/univ/renderer.h +++ b/include/wx/univ/renderer.h @@ -29,6 +29,7 @@ #define _WX_UNIV_RENDERER_H_ class WXDLLEXPORT wxDC; +class WXDLLEXPORT wxCheckListBox; class WXDLLEXPORT wxListBox; class WXDLLEXPORT wxScrollBar; class WXDLLEXPORT wxWindow; @@ -397,6 +398,8 @@ public: wxCoord marginX = 0, wxCoord marginY = 0); void DrawItems(const wxListBox *listbox, size_t itemFirst, size_t itemLast); + void DrawCheckItems(const wxCheckListBox *listbox, + size_t itemFirst, size_t itemLast); void DrawBorder(); void DrawButtonBorder(); // the line must be either horizontal or vertical @@ -420,6 +423,11 @@ public: wxRect& GetRect() { return m_rect; } private: + // common part of DrawItems() and DrawCheckItems() + void DoDrawItems(const wxListBox *listbox, + size_t itemFirst, size_t itemLast, + bool isCheckLbox = FALSE); + wxWindow *m_window; wxRenderer *m_renderer; wxDC& m_dc; diff --git a/samples/univ/univ.cpp b/samples/univ/univ.cpp index 4a5e9a0477..0814b1f161 100644 --- a/samples/univ/univ.cpp +++ b/samples/univ/univ.cpp @@ -37,6 +37,7 @@ #include "wx/bmpbuttn.h" #include "wx/button.h" #include "wx/checkbox.h" + #include "wx/checklst.h" #include "wx/listbox.h" #include "wx/radiobox.h" #include "wx/radiobut.h" @@ -357,6 +358,12 @@ MyUnivFrame::MyUnivFrame(const wxString& title) WXSIZEOF(choices), choices, WXSIZEOF(choices), wxRA_SPECIFY_ROWS); + + wxCheckListBox *checkLbox = new wxCheckListBox(this, -1, + wxPoint(500, 550), + wxDefaultSize, + WXSIZEOF(choices), choices); + checkLbox->Check(2); } void MyUnivFrame::OnButton(wxCommandEvent& event) diff --git a/src/generic/scrolwin.cpp b/src/generic/scrolwin.cpp index 8cb0777556..1f8754f048 100644 --- a/src/generic/scrolwin.cpp +++ b/src/generic/scrolwin.cpp @@ -486,7 +486,7 @@ void wxScrollHelper::DoPrepareDC(wxDC& dc) // for wxUniversal we need to set the clipping region to avoid overwriting // the scrollbars with the user drawing -#ifdef __WXUNIVERSAL__ +#if 0 //def __WXUNIVERSAL__ wxSize size = m_win->GetClientSize(); dc.SetClippingRegion(m_xScrollPosition * m_xScrollPixelsPerLine, m_yScrollPosition * m_yScrollPixelsPerLine, diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 2ce555fa16..6962d32423 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -2231,7 +2231,9 @@ wxPaintDC::wxPaintDC( wxWindow *win ) #endif // USE_PAINT_REGION #ifdef __WXUNIVERSAL__ - SetClippingRegion(win->GetClientRect()); + wxPoint ptOrigin = win->GetClientAreaOrigin(); + SetDeviceOrigin(ptOrigin.x, ptOrigin.y); + SetClippingRegion(ptOrigin, win->GetClientSize()); #endif // __WXUNIVERSAL__ } diff --git a/src/gtk1/dcclient.cpp b/src/gtk1/dcclient.cpp index 2ce555fa16..6962d32423 100644 --- a/src/gtk1/dcclient.cpp +++ b/src/gtk1/dcclient.cpp @@ -2231,7 +2231,9 @@ wxPaintDC::wxPaintDC( wxWindow *win ) #endif // USE_PAINT_REGION #ifdef __WXUNIVERSAL__ - SetClippingRegion(win->GetClientRect()); + wxPoint ptOrigin = win->GetClientAreaOrigin(); + SetDeviceOrigin(ptOrigin.x, ptOrigin.y); + SetClippingRegion(ptOrigin, win->GetClientSize()); #endif // __WXUNIVERSAL__ } diff --git a/src/univ/checklst.cpp b/src/univ/checklst.cpp new file mode 100644 index 0000000000..e6c988253e --- /dev/null +++ b/src/univ/checklst.cpp @@ -0,0 +1,152 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: univ/checklst.cpp +// Purpose: wxCheckListBox implementation +// Author: Vadim Zeitlin +// Modified by: +// Created: 12.09.00 +// RCS-ID: $Id$ +// Copyright: (c) 2000 Vadim Zeitlin +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "univchecklst.h" +#endif + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_CHECKLISTBOX + +#ifndef WX_PRECOMP + #include "wx/log.h" + + #include "wx/dcclient.h" + #include "wx/checklst.h" + #include "wx/validate.h" +#endif + +#include "wx/univ/renderer.h" +#include "wx/univ/inphand.h" +#include "wx/univ/theme.h" + +// ============================================================================ +// implementation of wxCheckListBox +// ============================================================================ + +IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox, wxListBox) + +// ---------------------------------------------------------------------------- +// creation +// ---------------------------------------------------------------------------- + +void wxCheckListBox::Init() +{ +} + +// ---------------------------------------------------------------------------- +// wxCheckListBox functions +// ---------------------------------------------------------------------------- + +bool wxCheckListBox::IsChecked(size_t item) const +{ + wxCHECK_MSG( item < m_checks.GetCount(), FALSE, + _T("invalid index in wxCheckListBox::IsChecked") ); + + return m_checks[item] != 0; +} + +void wxCheckListBox::Check(size_t item, bool check) +{ + wxCHECK_RET( item < m_checks.GetCount(), + _T("invalid index in wxCheckListBox::Check") ); + + if ( check != m_checks[item] ) + { + m_checks[item] = check; + + RefreshItem(item); + } +} + +// ---------------------------------------------------------------------------- +// methods forwarded to wxListBox +// ---------------------------------------------------------------------------- + +void wxCheckListBox::Delete(int n) +{ + wxCHECK_RET( n < GetCount(), _T("invalid index in wxListBox::Delete") ); + + wxListBox::Delete(n); + + m_checks.RemoveAt(n); +} + +int wxCheckListBox::DoAppend(const wxString& item) +{ + int pos = wxListBox::DoAppend(item); + + // the item is initially unchecked + m_checks.Insert(FALSE, pos); + + return pos; +} + +void wxCheckListBox::DoInsertItems(const wxArrayString& items, int pos) +{ + wxListBox::DoInsertItems(items, pos); + + size_t count = items.GetCount(); + for ( size_t n = 0; n < count; n++ ) + { + m_checks.Insert(FALSE, pos + n); + } +} + +void wxCheckListBox::DoSetItems(const wxArrayString& items, void **clientData) +{ + // call it first as it does DoClear() + wxListBox::DoSetItems(items, clientData); + + size_t count = items.GetCount(); + for ( size_t n = 0; n < count; n++ ) + { + m_checks.Add(FALSE); + } +} + +void wxCheckListBox::DoClear() +{ + m_checks.Empty(); +} + +// ---------------------------------------------------------------------------- +// drawing +// ---------------------------------------------------------------------------- + +wxSize wxCheckListBox::DoGetBestClientSize() const +{ + wxSize size = wxListBox::DoGetBestClientSize(); + size.x += GetRenderer()->GetCheckBitmapSize().x; + + return size; +} + +void wxCheckListBox::DoDrawRange(wxControlRenderer *renderer, + int itemFirst, int itemLast) +{ + renderer->DrawCheckItems(this, itemFirst, itemLast); +} + +#endif // wxUSE_CHECKLISTBOX diff --git a/src/univ/files.lst b/src/univ/files.lst index 13a021e31a..40c1612f26 100644 --- a/src/univ/files.lst +++ b/src/univ/files.lst @@ -2,6 +2,7 @@ UNIVOBJS = \ bmpbuttn.o \ button.o \ checkbox.o \ + checklst.o \ colschem.o \ control.o \ inphand.o \ @@ -23,6 +24,7 @@ UNIVDEPS = \ bmpbuttn.d \ button.d \ checkbox.d \ + checklst.d \ colschem.d \ control.d \ inphand.d \ diff --git a/src/univ/listbox.cpp b/src/univ/listbox.cpp index 19b40949b3..bc72bf2c12 100644 --- a/src/univ/listbox.cpp +++ b/src/univ/listbox.cpp @@ -520,24 +520,11 @@ wxBorder wxListBox::GetDefaultBorder() const void wxListBox::DoDraw(wxControlRenderer *renderer) { -#if 0 - // draw the border first - if ( m_showScrollbarY ) - { - // we need to draw a border around the client area - renderer->GetRect().width -= GetScrollbar(wxVERTICAL)->GetSize().x; - } - - // the base class version does it for us - wxControl::DoDraw(renderer); -#endif - // adjust the DC to account for scrolling wxDC& dc = renderer->GetDC(); PrepareDC(dc); // get the items which must be redrawn -#if 1 wxCoord lineHeight = GetLineHeight(); wxRegion rgnUpdate = GetUpdateRegion(); rgnUpdate.Intersect(GetClientRect()); @@ -556,15 +543,17 @@ void wxListBox::DoDraw(wxControlRenderer *renderer) if ( itemLast > itemMax ) itemLast = itemMax; -#else - size_t itemFirst = 0, - itemLast = m_strings.GetCount(); -#endif // do draw them wxLogTrace(_T("listbox"), _T("Repainting items %d..%d"), itemFirst, itemLast); + DoDrawRange(renderer, itemFirst, itemLast); +} + +void wxListBox::DoDrawRange(wxControlRenderer *renderer, + int itemFirst, int itemLast) +{ renderer->DrawItems(this, itemFirst, itemLast); } diff --git a/src/univ/renderer.cpp b/src/univ/renderer.cpp index 7f4db879a7..7985c9ddec 100644 --- a/src/univ/renderer.cpp +++ b/src/univ/renderer.cpp @@ -31,6 +31,7 @@ #ifndef WX_PRECOMP #include "wx/app.h" #include "wx/control.h" + #include "wx/checklst.h" #include "wx/listbox.h" #include "wx/scrolbar.h" #include "wx/dc.h" @@ -591,6 +592,19 @@ void wxControlRenderer::DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) void wxControlRenderer::DrawItems(const wxListBox *lbox, size_t itemFirst, size_t itemLast) +{ + DoDrawItems(lbox, itemFirst, itemLast); +} + +void wxControlRenderer::DrawCheckItems(const wxCheckListBox *lbox, + size_t itemFirst, size_t itemLast) +{ + DoDrawItems(lbox, itemFirst, itemLast, TRUE); +} + +void wxControlRenderer::DoDrawItems(const wxListBox *lbox, + size_t itemFirst, size_t itemLast, + bool isCheckLbox) { // prepare for the drawing: calc the initial position wxCoord lineHeight = lbox->GetLineHeight(); @@ -630,7 +644,21 @@ void wxControlRenderer::DrawItems(const wxListBox *lbox, if ( lbox->IsSelected(n) ) flags |= wxCONTROL_SELECTED; - m_renderer->DrawItem(m_dc, lbox->GetString(n), rect, flags); + if ( isCheckLbox ) + { + wxCheckListBox *checklstbox = wxStaticCast(lbox, wxCheckListBox); + if ( checklstbox->IsChecked(n) ) + flags |= wxCONTROL_CHECKED; + + m_renderer->DrawCheckButton(m_dc, lbox->GetString(n), + wxNullBitmap, + rect, + flags); + } + else + { + m_renderer->DrawItem(m_dc, lbox->GetString(n), rect, flags); + } rect.y += lineHeight; }