diff --git a/.cvsignore b/.cvsignore index 3d4238dc2c..b3cc5fe4c0 100644 --- a/.cvsignore +++ b/.cvsignore @@ -43,3 +43,4 @@ gtk-release motif-release win32-release *tags +log diff --git a/TODO b/TODO index 0a72e6bf81..79a04ec86a 100644 --- a/TODO +++ b/TODO @@ -11,6 +11,8 @@ All ! wxThemeSettings ! actions/wxInputHandler? +* wxCheckListBox: redraw only the bitmap when toggled + * problem with lbox horz scrolling: the focus rect isn't drawn entirely... * write sample testing all listbox styles/events * text ctrl wxTE_XXX styles support diff --git a/include/wx/gtk/region.h b/include/wx/gtk/region.h index f4ef0f25d8..1d894e54dc 100644 --- a/include/wx/gtk/region.h +++ b/include/wx/gtk/region.h @@ -45,9 +45,9 @@ enum wxRegionOp wxRGN_XOR // Creates the union of two combined regions except for any overlapping areas. }; -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // wxRegion -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- class wxRegion : public wxGDIObject { @@ -101,10 +101,17 @@ protected: // helper of Intersect() bool IntersectRegionOnly(const wxRegion& reg); + // call this before modifying the region + void Unshare(); + private: DECLARE_DYNAMIC_CLASS(wxRegion); }; +// ---------------------------------------------------------------------------- +// wxRegionIterator: decomposes a region into rectangles +// ---------------------------------------------------------------------------- + class wxRegionIterator: public wxObject { public: diff --git a/include/wx/gtk1/region.h b/include/wx/gtk1/region.h index f4ef0f25d8..1d894e54dc 100644 --- a/include/wx/gtk1/region.h +++ b/include/wx/gtk1/region.h @@ -45,9 +45,9 @@ enum wxRegionOp wxRGN_XOR // Creates the union of two combined regions except for any overlapping areas. }; -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // wxRegion -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- class wxRegion : public wxGDIObject { @@ -101,10 +101,17 @@ protected: // helper of Intersect() bool IntersectRegionOnly(const wxRegion& reg); + // call this before modifying the region + void Unshare(); + private: DECLARE_DYNAMIC_CLASS(wxRegion); }; +// ---------------------------------------------------------------------------- +// wxRegionIterator: decomposes a region into rectangles +// ---------------------------------------------------------------------------- + class wxRegionIterator: public wxObject { public: diff --git a/include/wx/univ/textctrl.h b/include/wx/univ/textctrl.h index c6342beb9b..83c7259fba 100644 --- a/include/wx/univ/textctrl.h +++ b/include/wx/univ/textctrl.h @@ -282,6 +282,13 @@ protected: // calculate the last visible position void UpdateLastVisible(); + // move caret to the given position unconditionally + // (SetInsertionPoint() does nothing if the position didn't change) + void DoSetInsertionPoint(long pos); + + // set the caret to its initial (default) position + void InitInsertionPoint(); + // event handlers void OnChar(wxKeyEvent& event); void OnSize(wxSizeEvent& event); @@ -305,7 +312,8 @@ private: // flags bool m_isModified:1, - m_isEditable:1; + m_isEditable:1, + m_hasCaret:1; // the rectangle (in client coordinates) to draw text inside wxRect m_rectText; diff --git a/samples/listbox/lboxtest.cpp b/samples/listbox/lboxtest.cpp index 94a1d0f2a6..755138b4f2 100644 --- a/samples/listbox/lboxtest.cpp +++ b/samples/listbox/lboxtest.cpp @@ -34,31 +34,21 @@ #include "wx/frame.h" #include "wx/dcclient.h" - #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" - #include "wx/scrolbar.h" - #include "wx/scrolwin.h" #include "wx/statbox.h" #include "wx/stattext.h" + #include "wx/textctrl.h" #endif #include "wx/sizer.h" #ifdef __WXUNIVERSAL__ - -#include "wx/univ/theme.h" - -// ---------------------------------------------------------------------------- -// resources -// ---------------------------------------------------------------------------- - -#include "bricks.xpm" - + #include "wx/univ/theme.h" #endif // __WXUNIVERSAL__ // ---------------------------------------------------------------------------- @@ -279,11 +269,11 @@ LboxTestFrame::LboxTestFrame(const wxString& title) wxSizer *sizerDown = new wxStaticBoxSizer(box2, wxVERTICAL); btn = new wxButton(this, LboxTest_Add, _T("&Add string...")); - sizerDown->Add(btn, 0, wxALL, 5); + sizerDown->Add(btn, 0, wxALL | wxGROW, 5); btn = new wxButton(this, LboxTest_AddSeveral, _T("Add a &few string")); - sizerDown->Add(btn, 0, wxALL, 5); + sizerDown->Add(btn, 0, wxALL | wxGROW, 5); btn = new wxButton(this, LboxTest_Clear, _T("&Clear")); - sizerDown->Add(btn, 0, wxALL, 5); + sizerDown->Add(btn, 0, wxALL | wxGROW, 5); sizerLeft->Add(sizerUp, 0, wxGROW | wxTOP | wxBOTTOM, 5); sizerLeft->Add(sizerDown, 0, wxGROW | wxTOP | wxBOTTOM, 5); diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 3943bb2296..9e75d96bdb 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -2223,19 +2223,19 @@ wxPaintDC::wxPaintDC( wxWindow *win ) : wxClientDC( win ) { #if USE_PAINT_REGION - if (!win->m_clipPaintRegion) - return; - - m_paintClippingRegion = win->GetUpdateRegion(); - GdkRegion *region = m_paintClippingRegion.GetRegion(); - if ( region ) + if ( win->m_clipPaintRegion ) { - m_currentClippingRegion.Union( m_paintClippingRegion ); + m_paintClippingRegion = win->GetUpdateRegion(); + GdkRegion *region = m_paintClippingRegion.GetRegion(); + if ( region ) + { + m_currentClippingRegion.Union( m_paintClippingRegion ); - gdk_gc_set_clip_region( m_penGC, region ); - gdk_gc_set_clip_region( m_brushGC, region ); - gdk_gc_set_clip_region( m_textGC, region ); - gdk_gc_set_clip_region( m_bgGC, region ); + gdk_gc_set_clip_region( m_penGC, region ); + gdk_gc_set_clip_region( m_brushGC, region ); + gdk_gc_set_clip_region( m_textGC, region ); + gdk_gc_set_clip_region( m_bgGC, region ); + } } #endif // USE_PAINT_REGION } diff --git a/src/gtk/region.cpp b/src/gtk/region.cpp index 687eadf05b..31137ceeed 100644 --- a/src/gtk/region.cpp +++ b/src/gtk/region.cpp @@ -2,40 +2,89 @@ // Name: gtk/region.cpp // Purpose: // Author: Robert Roebling +// Modified: VZ at 05.10.00: use Unshare(), comparison fixed // Id: $Id$ // Copyright: (c) 1998 Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + #ifdef __GNUG__ -#pragma implementation "region.h" + #pragma implementation "region.h" #endif +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #include "wx/region.h" #include #include +#include "wx/log.h" -//----------------------------------------------------------------------------- -// wxRegion -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// wxRegionRefData: private class containing the information about the region +// ---------------------------------------------------------------------------- -class wxRegionRefData: public wxObjectRefData +class wxRegionRefData : public wxObjectRefData { public: wxRegionRefData(); - ~wxRegionRefData(); + wxRegionRefData(const wxRegionRefData& refData); + virtual ~wxRegionRefData(); GdkRegion *m_region; wxList m_rects; }; +// ---------------------------------------------------------------------------- +// macros +// ---------------------------------------------------------------------------- + +#define M_REGIONDATA ((wxRegionRefData *)m_refData) +#define M_REGIONDATA_OF(rgn) ((wxRegionRefData *)(rgn.m_refData)) + +IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject); +IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator,wxObject); + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxRegionRefData +// ---------------------------------------------------------------------------- + wxRegionRefData::wxRegionRefData() { m_region = (GdkRegion *) NULL; } +wxRegionRefData::wxRegionRefData(const wxRegionRefData& refData) +{ +#ifdef __WXGTK20__ + m_region = gdk_region_copy(refData.m_region); +#else + m_region = gdk_region_new(); + GdkRegion *regCopy = gdk_regions_union(m_region, refData.m_region); + gdk_region_destroy(m_region); + m_region = regCopy; +#endif + + wxNode *node = refData.m_rects.First(); + while (node) + { + wxRect *r = (wxRect*)node->Data(); + m_rects.Append( (wxObject*) new wxRect(*r) ); + node = node->Next(); + } +} + wxRegionRefData::~wxRegionRefData() { if (m_region) gdk_region_destroy( m_region ); @@ -49,11 +98,13 @@ wxRegionRefData::~wxRegionRefData() } } -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// wxRegion construction +// ---------------------------------------------------------------------------- -#define M_REGIONDATA ((wxRegionRefData *)m_refData) - -IMPLEMENT_DYNAMIC_CLASS(wxRegion,wxGDIObject); +wxRegion::wxRegion() +{ +} wxRegion::wxRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) { @@ -112,24 +163,42 @@ wxRegion::wxRegion( const wxRect& rect ) M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(rect.x,rect.y,rect.width,rect.height) ); } -wxRegion::wxRegion() -{ -} - wxRegion::~wxRegion() { } -bool wxRegion::operator == ( const wxRegion& region ) +bool wxRegion::operator==( const wxRegion& region ) { - return m_refData == region.m_refData; + // VZ: compare the regions themselves, not the pointers to ref data! + return gdk_region_equal(M_REGIONDATA->m_region, + M_REGIONDATA_OF(region)->m_region); } bool wxRegion::operator != ( const wxRegion& region ) { - return m_refData != region.m_refData; + return !(*this == region); } +void wxRegion::Unshare() +{ + if ( !m_refData ) + { + m_refData = new wxRegionRefData; + M_REGIONDATA->m_region = gdk_region_new(); + } + else if ( m_refData->GetRefCount() > 1 ) + { + wxRegionRefData *refData = new wxRegionRefData(*M_REGIONDATA); + UnRef(); + m_refData = refData; + } + //else: we're not shared +} + +// ---------------------------------------------------------------------------- +// wxRegion operations +// ---------------------------------------------------------------------------- + void wxRegion::Clear() { UnRef(); @@ -156,6 +225,8 @@ bool wxRegion::Union( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) } else { + Unshare(); + #ifdef __WXGTK20__ gdk_region_union_with_rect( M_REGIONDATA->m_region, &rect ); #else @@ -180,11 +251,7 @@ bool wxRegion::Union( const wxRegion& region ) if (region.IsNull()) return FALSE; - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } + Unshare(); #ifdef __WXGTK20__ gdk_region_union( M_REGIONDATA->m_region, region.GetRegion() ); @@ -207,28 +274,15 @@ bool wxRegion::Union( const wxRegion& region ) bool wxRegion::Intersect( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } - wxRegion reg( x, y, width, height ); - Intersect( reg ); - return TRUE; + + return Intersect( reg ); } bool wxRegion::Intersect( const wxRect& rect ) { - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } - wxRegion reg( rect ); - Intersect( reg ); - return TRUE; + return Intersect( reg ); } // this helper function just computes the region intersection without updating @@ -237,6 +291,8 @@ bool wxRegion::Intersect( const wxRect& rect ) // if we called Intersect() itself recursively bool wxRegion::IntersectRegionOnly(const wxRegion& region) { + Unshare(); + #ifdef __WXGTK20__ gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() ); #else @@ -295,28 +351,14 @@ bool wxRegion::Intersect( const wxRegion& region ) bool wxRegion::Subtract( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } - wxRegion reg( x, y, width, height ); - Subtract( reg ); - return TRUE; + return Subtract( reg ); } bool wxRegion::Subtract( const wxRect& rect ) { - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } - wxRegion reg( rect ); - Subtract( reg ); - return TRUE; + return Subtract( reg ); } bool wxRegion::Subtract( const wxRegion& region ) @@ -330,6 +372,8 @@ bool wxRegion::Subtract( const wxRegion& region ) M_REGIONDATA->m_region = gdk_region_new(); } + Unshare(); + #ifdef __WXGTK20__ gdk_region_subtract( M_REGIONDATA->m_region, region.GetRegion() ); #else @@ -337,33 +381,20 @@ bool wxRegion::Subtract( const wxRegion& region ) gdk_region_destroy( M_REGIONDATA->m_region ); M_REGIONDATA->m_region = reg; #endif + return TRUE; } bool wxRegion::Xor( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } - wxRegion reg( x, y, width, height ); - Xor( reg ); - return TRUE; + return Xor( reg ); } bool wxRegion::Xor( const wxRect& rect ) { - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } - wxRegion reg( rect ); - Xor( reg ); - return TRUE; + return Xor( reg ); } bool wxRegion::Xor( const wxRegion& region ) @@ -376,6 +407,10 @@ bool wxRegion::Xor( const wxRegion& region ) m_refData = new wxRegionRefData(); M_REGIONDATA->m_region = gdk_region_new(); } + else + { + Unshare(); + } #ifdef __WXGTK20__ gdk_region_xor( M_REGIONDATA->m_region, region.GetRegion() ); @@ -396,29 +431,33 @@ bool wxRegion::Xor( const wxRegion& region ) return TRUE; } +// ---------------------------------------------------------------------------- +// wxRegion tests +// ---------------------------------------------------------------------------- + void wxRegion::GetBox( wxCoord &x, wxCoord &y, wxCoord &w, wxCoord &h ) const { - x = 0; - y = 0; - w = -1; - h = -1; - if (!m_refData) - return; - - GdkRectangle rect; - gdk_region_get_clipbox( M_REGIONDATA->m_region, &rect ); - x = rect.x; - y = rect.y; - w = rect.width; - h = rect.height; + if ( m_refData ) + { + GdkRectangle rect; + gdk_region_get_clipbox( M_REGIONDATA->m_region, &rect ); + x = rect.x; + y = rect.y; + w = rect.width; + h = rect.height; + } + else + { + x = 0; + y = 0; + w = -1; + h = -1; + } } wxRect wxRegion::GetBox() const { - wxCoord x = 0; - wxCoord y = 0; - wxCoord w = -1; - wxCoord h = -1; + wxCoord x, y, w, h; GetBox( x, y, w, h ); return wxRect( x, y, w, h ); } @@ -488,11 +527,9 @@ wxList *wxRegion::GetRectList() const return &(M_REGIONDATA->m_rects); } -//----------------------------------------------------------------------------- -// wxRegion -//----------------------------------------------------------------------------- - -IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator,wxObject); +// ---------------------------------------------------------------------------- +// wxRegionIterator +// ---------------------------------------------------------------------------- wxRegionIterator::wxRegionIterator() { diff --git a/src/gtk1/dcclient.cpp b/src/gtk1/dcclient.cpp index 3943bb2296..9e75d96bdb 100644 --- a/src/gtk1/dcclient.cpp +++ b/src/gtk1/dcclient.cpp @@ -2223,19 +2223,19 @@ wxPaintDC::wxPaintDC( wxWindow *win ) : wxClientDC( win ) { #if USE_PAINT_REGION - if (!win->m_clipPaintRegion) - return; - - m_paintClippingRegion = win->GetUpdateRegion(); - GdkRegion *region = m_paintClippingRegion.GetRegion(); - if ( region ) + if ( win->m_clipPaintRegion ) { - m_currentClippingRegion.Union( m_paintClippingRegion ); + m_paintClippingRegion = win->GetUpdateRegion(); + GdkRegion *region = m_paintClippingRegion.GetRegion(); + if ( region ) + { + m_currentClippingRegion.Union( m_paintClippingRegion ); - gdk_gc_set_clip_region( m_penGC, region ); - gdk_gc_set_clip_region( m_brushGC, region ); - gdk_gc_set_clip_region( m_textGC, region ); - gdk_gc_set_clip_region( m_bgGC, region ); + gdk_gc_set_clip_region( m_penGC, region ); + gdk_gc_set_clip_region( m_brushGC, region ); + gdk_gc_set_clip_region( m_textGC, region ); + gdk_gc_set_clip_region( m_bgGC, region ); + } } #endif // USE_PAINT_REGION } diff --git a/src/gtk1/region.cpp b/src/gtk1/region.cpp index 687eadf05b..31137ceeed 100644 --- a/src/gtk1/region.cpp +++ b/src/gtk1/region.cpp @@ -2,40 +2,89 @@ // Name: gtk/region.cpp // Purpose: // Author: Robert Roebling +// Modified: VZ at 05.10.00: use Unshare(), comparison fixed // Id: $Id$ // Copyright: (c) 1998 Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + #ifdef __GNUG__ -#pragma implementation "region.h" + #pragma implementation "region.h" #endif +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #include "wx/region.h" #include #include +#include "wx/log.h" -//----------------------------------------------------------------------------- -// wxRegion -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// wxRegionRefData: private class containing the information about the region +// ---------------------------------------------------------------------------- -class wxRegionRefData: public wxObjectRefData +class wxRegionRefData : public wxObjectRefData { public: wxRegionRefData(); - ~wxRegionRefData(); + wxRegionRefData(const wxRegionRefData& refData); + virtual ~wxRegionRefData(); GdkRegion *m_region; wxList m_rects; }; +// ---------------------------------------------------------------------------- +// macros +// ---------------------------------------------------------------------------- + +#define M_REGIONDATA ((wxRegionRefData *)m_refData) +#define M_REGIONDATA_OF(rgn) ((wxRegionRefData *)(rgn.m_refData)) + +IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject); +IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator,wxObject); + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxRegionRefData +// ---------------------------------------------------------------------------- + wxRegionRefData::wxRegionRefData() { m_region = (GdkRegion *) NULL; } +wxRegionRefData::wxRegionRefData(const wxRegionRefData& refData) +{ +#ifdef __WXGTK20__ + m_region = gdk_region_copy(refData.m_region); +#else + m_region = gdk_region_new(); + GdkRegion *regCopy = gdk_regions_union(m_region, refData.m_region); + gdk_region_destroy(m_region); + m_region = regCopy; +#endif + + wxNode *node = refData.m_rects.First(); + while (node) + { + wxRect *r = (wxRect*)node->Data(); + m_rects.Append( (wxObject*) new wxRect(*r) ); + node = node->Next(); + } +} + wxRegionRefData::~wxRegionRefData() { if (m_region) gdk_region_destroy( m_region ); @@ -49,11 +98,13 @@ wxRegionRefData::~wxRegionRefData() } } -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// wxRegion construction +// ---------------------------------------------------------------------------- -#define M_REGIONDATA ((wxRegionRefData *)m_refData) - -IMPLEMENT_DYNAMIC_CLASS(wxRegion,wxGDIObject); +wxRegion::wxRegion() +{ +} wxRegion::wxRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) { @@ -112,24 +163,42 @@ wxRegion::wxRegion( const wxRect& rect ) M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(rect.x,rect.y,rect.width,rect.height) ); } -wxRegion::wxRegion() -{ -} - wxRegion::~wxRegion() { } -bool wxRegion::operator == ( const wxRegion& region ) +bool wxRegion::operator==( const wxRegion& region ) { - return m_refData == region.m_refData; + // VZ: compare the regions themselves, not the pointers to ref data! + return gdk_region_equal(M_REGIONDATA->m_region, + M_REGIONDATA_OF(region)->m_region); } bool wxRegion::operator != ( const wxRegion& region ) { - return m_refData != region.m_refData; + return !(*this == region); } +void wxRegion::Unshare() +{ + if ( !m_refData ) + { + m_refData = new wxRegionRefData; + M_REGIONDATA->m_region = gdk_region_new(); + } + else if ( m_refData->GetRefCount() > 1 ) + { + wxRegionRefData *refData = new wxRegionRefData(*M_REGIONDATA); + UnRef(); + m_refData = refData; + } + //else: we're not shared +} + +// ---------------------------------------------------------------------------- +// wxRegion operations +// ---------------------------------------------------------------------------- + void wxRegion::Clear() { UnRef(); @@ -156,6 +225,8 @@ bool wxRegion::Union( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) } else { + Unshare(); + #ifdef __WXGTK20__ gdk_region_union_with_rect( M_REGIONDATA->m_region, &rect ); #else @@ -180,11 +251,7 @@ bool wxRegion::Union( const wxRegion& region ) if (region.IsNull()) return FALSE; - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } + Unshare(); #ifdef __WXGTK20__ gdk_region_union( M_REGIONDATA->m_region, region.GetRegion() ); @@ -207,28 +274,15 @@ bool wxRegion::Union( const wxRegion& region ) bool wxRegion::Intersect( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } - wxRegion reg( x, y, width, height ); - Intersect( reg ); - return TRUE; + + return Intersect( reg ); } bool wxRegion::Intersect( const wxRect& rect ) { - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } - wxRegion reg( rect ); - Intersect( reg ); - return TRUE; + return Intersect( reg ); } // this helper function just computes the region intersection without updating @@ -237,6 +291,8 @@ bool wxRegion::Intersect( const wxRect& rect ) // if we called Intersect() itself recursively bool wxRegion::IntersectRegionOnly(const wxRegion& region) { + Unshare(); + #ifdef __WXGTK20__ gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() ); #else @@ -295,28 +351,14 @@ bool wxRegion::Intersect( const wxRegion& region ) bool wxRegion::Subtract( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } - wxRegion reg( x, y, width, height ); - Subtract( reg ); - return TRUE; + return Subtract( reg ); } bool wxRegion::Subtract( const wxRect& rect ) { - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } - wxRegion reg( rect ); - Subtract( reg ); - return TRUE; + return Subtract( reg ); } bool wxRegion::Subtract( const wxRegion& region ) @@ -330,6 +372,8 @@ bool wxRegion::Subtract( const wxRegion& region ) M_REGIONDATA->m_region = gdk_region_new(); } + Unshare(); + #ifdef __WXGTK20__ gdk_region_subtract( M_REGIONDATA->m_region, region.GetRegion() ); #else @@ -337,33 +381,20 @@ bool wxRegion::Subtract( const wxRegion& region ) gdk_region_destroy( M_REGIONDATA->m_region ); M_REGIONDATA->m_region = reg; #endif + return TRUE; } bool wxRegion::Xor( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } - wxRegion reg( x, y, width, height ); - Xor( reg ); - return TRUE; + return Xor( reg ); } bool wxRegion::Xor( const wxRect& rect ) { - if (!m_refData) - { - m_refData = new wxRegionRefData(); - M_REGIONDATA->m_region = gdk_region_new(); - } - wxRegion reg( rect ); - Xor( reg ); - return TRUE; + return Xor( reg ); } bool wxRegion::Xor( const wxRegion& region ) @@ -376,6 +407,10 @@ bool wxRegion::Xor( const wxRegion& region ) m_refData = new wxRegionRefData(); M_REGIONDATA->m_region = gdk_region_new(); } + else + { + Unshare(); + } #ifdef __WXGTK20__ gdk_region_xor( M_REGIONDATA->m_region, region.GetRegion() ); @@ -396,29 +431,33 @@ bool wxRegion::Xor( const wxRegion& region ) return TRUE; } +// ---------------------------------------------------------------------------- +// wxRegion tests +// ---------------------------------------------------------------------------- + void wxRegion::GetBox( wxCoord &x, wxCoord &y, wxCoord &w, wxCoord &h ) const { - x = 0; - y = 0; - w = -1; - h = -1; - if (!m_refData) - return; - - GdkRectangle rect; - gdk_region_get_clipbox( M_REGIONDATA->m_region, &rect ); - x = rect.x; - y = rect.y; - w = rect.width; - h = rect.height; + if ( m_refData ) + { + GdkRectangle rect; + gdk_region_get_clipbox( M_REGIONDATA->m_region, &rect ); + x = rect.x; + y = rect.y; + w = rect.width; + h = rect.height; + } + else + { + x = 0; + y = 0; + w = -1; + h = -1; + } } wxRect wxRegion::GetBox() const { - wxCoord x = 0; - wxCoord y = 0; - wxCoord w = -1; - wxCoord h = -1; + wxCoord x, y, w, h; GetBox( x, y, w, h ); return wxRect( x, y, w, h ); } @@ -488,11 +527,9 @@ wxList *wxRegion::GetRectList() const return &(M_REGIONDATA->m_rects); } -//----------------------------------------------------------------------------- -// wxRegion -//----------------------------------------------------------------------------- - -IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator,wxObject); +// ---------------------------------------------------------------------------- +// wxRegionIterator +// ---------------------------------------------------------------------------- wxRegionIterator::wxRegionIterator() { diff --git a/src/univ/files.lst b/src/univ/files.lst index e897d14e98..20c255bfe9 100644 --- a/src/univ/files.lst +++ b/src/univ/files.lst @@ -15,13 +15,12 @@ UNIVOBJS = \ statbox.o \ statline.o \ stattext.o \ + textctrl.o \ theme.o \ gtk.o \ winuniv.o \ win32.o -# textctrl.o \ - UNIVDEPS = \ bmpbuttn.d \ button.d \ diff --git a/src/univ/textctrl.cpp b/src/univ/textctrl.cpp index 992a0c9a01..ca2c5b08fc 100644 --- a/src/univ/textctrl.cpp +++ b/src/univ/textctrl.cpp @@ -120,8 +120,14 @@ bool wxTextCtrl::Create(wxWindow *parent, SetCursor(wxCURSOR_IBEAM); SetValue(value); - SetBestSize(m_sizeInitial); + SetBestSize(size); + CreateCaret(); + InitInsertionPoint(); + + // we can't show caret right now as we're not shown yet and so it would + // result in garbage on the screen - we'll do it after first OnPaint() + m_hasCaret = FALSE; return TRUE; } @@ -135,7 +141,7 @@ bool wxTextCtrl::SetFont(const wxFont& font) CreateCaret(); // and refresh everything, of course - SetInsertionPoint(0); + InitInsertionPoint(); ClearSelection(); Refresh(); @@ -245,30 +251,42 @@ void wxTextCtrl::SetInsertionPoint(long pos) wxCHECK_RET( pos >= 0 && pos <= GetLastPosition(), _T("insertion point position out of range") ); + // don't do anything if it didn't change if ( pos != m_curPos ) { - HideCaret(); - - m_curPos = pos; - - if ( IsSingleLine() ) - { - m_curLine = 0; - m_curRow = m_curPos; - - // the current position should always be shown, scroll the window - // for this if necessary - ShowHorzPosition(GetCaretPosition()); - } - else // multi line - { - wxFAIL_MSG(_T("unimplemented for multi line")); - } - - ShowCaret(); + DoSetInsertionPoint(pos); } } +void wxTextCtrl::InitInsertionPoint() +{ + // so far always put it in the beginning + DoSetInsertionPoint(0); +} + +void wxTextCtrl::DoSetInsertionPoint(long pos) +{ + HideCaret(); + + m_curPos = pos; + + if ( IsSingleLine() ) + { + m_curLine = 0; + m_curRow = m_curPos; + + // the current position should always be shown, scroll the window + // for this if necessary + ShowHorzPosition(GetCaretPosition()); + } + else // multi line + { + wxFAIL_MSG(_T("unimplemented for multi line")); + } + + ShowCaret(); +} + void wxTextCtrl::SetInsertionPointEnd() { SetInsertionPoint(GetLastPosition()); @@ -852,6 +870,14 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTestLine(const wxString& line, // and this should give us much better approximation in such case dc.GetTextExtent(line[0], &width, NULL); col = x / width; + if ( col < 0 ) + { + col = 0; + } + else if ( (size_t)col > line.length() ) + { + col = line.length(); + } // matchDir is -1 if we must move left, +1 to move right and 0 when // we're exactly on the character we need @@ -1185,7 +1211,7 @@ void wxTextCtrl::RefreshTextRange(long start, long end) if ( !PositionToXY(end, &colEnd, &lineEnd) ) { // the range spans beyond the end of text, refresh to the end - colEnd = wxSTRING_MAXLEN; + colEnd = -1; lineEnd = GetNumberOfLines() - 1; } @@ -1197,7 +1223,7 @@ void wxTextCtrl::RefreshTextRange(long start, long end) // the end of the range long posStart = line == lineStart ? colStart : 0; long posCount; - if ( (line != lineEnd) || (colEnd == wxSTRING_MAXLEN) ) + if ( (line != lineEnd) || (colEnd == -1) ) { // intermediate line or the last one but we need to refresh it // until the end anyhow - do it @@ -1486,6 +1512,15 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer) DoDrawTextInRect(dc, r); } + + // show caret first time only + if ( !m_hasCaret ) + { + GetCaret()->Show(); + + m_hasCaret = TRUE; + } + } // ---------------------------------------------------------------------------- @@ -1502,8 +1537,6 @@ void wxTextCtrl::CreateCaret() // SetCaret() will delete the old caret if any SetCaret(caret); - - caret->Show(); } wxCoord wxTextCtrl::GetCaretPosition() const @@ -1689,7 +1722,16 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) if ( !event.HasModifiers() ) { int keycode = event.GetKeyCode(); - if ( keycode < 255 && keycode != WXK_DELETE && keycode != WXK_BACK ) + if ( keycode == WXK_RETURN ) + { + wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, GetId()); + InitCommandEvent(event); + event.SetString(GetValue()); + GetEventHandler()->ProcessEvent(event); + } + else if ( keycode < 255 && + keycode != WXK_DELETE && + keycode != WXK_BACK ) { PerformAction(wxACTION_TEXT_INSERT, -1, (wxChar)keycode); diff --git a/src/univ/themes/gtk.cpp b/src/univ/themes/gtk.cpp index 000aebccdc..88695e91b7 100644 --- a/src/univ/themes/gtk.cpp +++ b/src/univ/themes/gtk.cpp @@ -41,10 +41,10 @@ #include "wx/univ/theme.h" // ---------------------------------------------------------------------------- -// constants (to be removed) +// constants (to be removed, for testing only) // ---------------------------------------------------------------------------- -static const size_t BORDER_THICKNESS = 10; +static const size_t BORDER_THICKNESS = 1; // ---------------------------------------------------------------------------- // wxGTKRenderer: draw the GUI elements in GTK style @@ -734,7 +734,7 @@ wxRect wxGTKRenderer::GetBorderDimensions(wxBorder border) const { case wxBORDER_RAISED: case wxBORDER_SUNKEN: - width = 20; + width = 2*BORDER_THICKNESS; break; case wxBORDER_SIMPLE: diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index b92ad57829..fd2a4df6ea 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -423,7 +423,7 @@ void wxWindow::DoGetClientSize(int *width, int *height) const // if we don't have scrollbar or if it is outside the border (and not // blended into it), take account of the right border as well - if ( !m_scrollbarVert || inside ) + if ( !m_scrollbarVert || !inside ) w -= rectBorder.width; // and always account for the left border @@ -435,7 +435,7 @@ void wxWindow::DoGetClientSize(int *width, int *height) const if ( m_scrollbarHorz ) h -= m_scrollbarHorz->GetSize().y; - if ( !m_scrollbarHorz || inside ) + if ( !m_scrollbarHorz || !inside ) h -= rectBorder.height; *height = h - rectBorder.y;