1. fixed client size calculations for GTK

2. fixed wxGTK region code
3. fixed bug with out of bounds coords in wxTextCtrl::HitTest()
4. tried to (but failed) fix the initial caret appearance


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8480 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-10-05 19:10:37 +00:00
parent b28342f733
commit ea8259f286
14 changed files with 389 additions and 259 deletions

View File

@@ -43,3 +43,4 @@ gtk-release
motif-release motif-release
win32-release win32-release
*tags *tags
log

2
TODO
View File

@@ -11,6 +11,8 @@ All
! wxThemeSettings ! wxThemeSettings
! actions/wxInputHandler? ! actions/wxInputHandler?
* wxCheckListBox: redraw only the bitmap when toggled
* problem with lbox horz scrolling: the focus rect isn't drawn entirely... * problem with lbox horz scrolling: the focus rect isn't drawn entirely...
* write sample testing all listbox styles/events * write sample testing all listbox styles/events
* text ctrl wxTE_XXX styles support * text ctrl wxTE_XXX styles support

View File

@@ -45,9 +45,9 @@ enum wxRegionOp
wxRGN_XOR // Creates the union of two combined regions except for any overlapping areas. wxRGN_XOR // Creates the union of two combined regions except for any overlapping areas.
}; };
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxRegion // wxRegion
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class wxRegion : public wxGDIObject class wxRegion : public wxGDIObject
{ {
@@ -101,10 +101,17 @@ protected:
// helper of Intersect() // helper of Intersect()
bool IntersectRegionOnly(const wxRegion& reg); bool IntersectRegionOnly(const wxRegion& reg);
// call this before modifying the region
void Unshare();
private: private:
DECLARE_DYNAMIC_CLASS(wxRegion); DECLARE_DYNAMIC_CLASS(wxRegion);
}; };
// ----------------------------------------------------------------------------
// wxRegionIterator: decomposes a region into rectangles
// ----------------------------------------------------------------------------
class wxRegionIterator: public wxObject class wxRegionIterator: public wxObject
{ {
public: public:

View File

@@ -45,9 +45,9 @@ enum wxRegionOp
wxRGN_XOR // Creates the union of two combined regions except for any overlapping areas. wxRGN_XOR // Creates the union of two combined regions except for any overlapping areas.
}; };
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxRegion // wxRegion
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class wxRegion : public wxGDIObject class wxRegion : public wxGDIObject
{ {
@@ -101,10 +101,17 @@ protected:
// helper of Intersect() // helper of Intersect()
bool IntersectRegionOnly(const wxRegion& reg); bool IntersectRegionOnly(const wxRegion& reg);
// call this before modifying the region
void Unshare();
private: private:
DECLARE_DYNAMIC_CLASS(wxRegion); DECLARE_DYNAMIC_CLASS(wxRegion);
}; };
// ----------------------------------------------------------------------------
// wxRegionIterator: decomposes a region into rectangles
// ----------------------------------------------------------------------------
class wxRegionIterator: public wxObject class wxRegionIterator: public wxObject
{ {
public: public:

View File

@@ -282,6 +282,13 @@ protected:
// calculate the last visible position // calculate the last visible position
void UpdateLastVisible(); 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 // event handlers
void OnChar(wxKeyEvent& event); void OnChar(wxKeyEvent& event);
void OnSize(wxSizeEvent& event); void OnSize(wxSizeEvent& event);
@@ -305,7 +312,8 @@ private:
// flags // flags
bool m_isModified:1, bool m_isModified:1,
m_isEditable:1; m_isEditable:1,
m_hasCaret:1;
// the rectangle (in client coordinates) to draw text inside // the rectangle (in client coordinates) to draw text inside
wxRect m_rectText; wxRect m_rectText;

View File

@@ -34,31 +34,21 @@
#include "wx/frame.h" #include "wx/frame.h"
#include "wx/dcclient.h" #include "wx/dcclient.h"
#include "wx/bmpbuttn.h"
#include "wx/button.h" #include "wx/button.h"
#include "wx/checkbox.h" #include "wx/checkbox.h"
#include "wx/checklst.h" #include "wx/checklst.h"
#include "wx/listbox.h" #include "wx/listbox.h"
#include "wx/radiobox.h" #include "wx/radiobox.h"
#include "wx/radiobut.h" #include "wx/radiobut.h"
#include "wx/scrolbar.h"
#include "wx/scrolwin.h"
#include "wx/statbox.h" #include "wx/statbox.h"
#include "wx/stattext.h" #include "wx/stattext.h"
#include "wx/textctrl.h"
#endif #endif
#include "wx/sizer.h" #include "wx/sizer.h"
#ifdef __WXUNIVERSAL__ #ifdef __WXUNIVERSAL__
#include "wx/univ/theme.h"
#include "wx/univ/theme.h"
// ----------------------------------------------------------------------------
// resources
// ----------------------------------------------------------------------------
#include "bricks.xpm"
#endif // __WXUNIVERSAL__ #endif // __WXUNIVERSAL__
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -279,11 +269,11 @@ LboxTestFrame::LboxTestFrame(const wxString& title)
wxSizer *sizerDown = new wxStaticBoxSizer(box2, wxVERTICAL); wxSizer *sizerDown = new wxStaticBoxSizer(box2, wxVERTICAL);
btn = new wxButton(this, LboxTest_Add, _T("&Add string...")); 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")); 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")); 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(sizerUp, 0, wxGROW | wxTOP | wxBOTTOM, 5);
sizerLeft->Add(sizerDown, 0, wxGROW | wxTOP | wxBOTTOM, 5); sizerLeft->Add(sizerDown, 0, wxGROW | wxTOP | wxBOTTOM, 5);

View File

@@ -2223,19 +2223,19 @@ wxPaintDC::wxPaintDC( wxWindow *win )
: wxClientDC( win ) : wxClientDC( win )
{ {
#if USE_PAINT_REGION #if USE_PAINT_REGION
if (!win->m_clipPaintRegion) if ( win->m_clipPaintRegion )
return;
m_paintClippingRegion = win->GetUpdateRegion();
GdkRegion *region = m_paintClippingRegion.GetRegion();
if ( region )
{ {
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_penGC, region );
gdk_gc_set_clip_region( m_brushGC, region ); gdk_gc_set_clip_region( m_brushGC, region );
gdk_gc_set_clip_region( m_textGC, region ); gdk_gc_set_clip_region( m_textGC, region );
gdk_gc_set_clip_region( m_bgGC, region ); gdk_gc_set_clip_region( m_bgGC, region );
}
} }
#endif // USE_PAINT_REGION #endif // USE_PAINT_REGION
} }

View File

@@ -2,40 +2,89 @@
// Name: gtk/region.cpp // Name: gtk/region.cpp
// Purpose: // Purpose:
// Author: Robert Roebling // Author: Robert Roebling
// Modified: VZ at 05.10.00: use Unshare(), comparison fixed
// Id: $Id$ // Id: $Id$
// Copyright: (c) 1998 Robert Roebling // Copyright: (c) 1998 Robert Roebling
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation "region.h" #pragma implementation "region.h"
#endif #endif
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "wx/region.h" #include "wx/region.h"
#include <gdk/gdk.h> #include <gdk/gdk.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "wx/log.h"
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxRegion // wxRegionRefData: private class containing the information about the region
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class wxRegionRefData: public wxObjectRefData class wxRegionRefData : public wxObjectRefData
{ {
public: public:
wxRegionRefData(); wxRegionRefData();
~wxRegionRefData(); wxRegionRefData(const wxRegionRefData& refData);
virtual ~wxRegionRefData();
GdkRegion *m_region; GdkRegion *m_region;
wxList m_rects; 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() wxRegionRefData::wxRegionRefData()
{ {
m_region = (GdkRegion *) NULL; 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() wxRegionRefData::~wxRegionRefData()
{ {
if (m_region) gdk_region_destroy( m_region ); if (m_region) gdk_region_destroy( m_region );
@@ -49,11 +98,13 @@ wxRegionRefData::~wxRegionRefData()
} }
} }
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxRegion construction
// ----------------------------------------------------------------------------
#define M_REGIONDATA ((wxRegionRefData *)m_refData) wxRegion::wxRegion()
{
IMPLEMENT_DYNAMIC_CLASS(wxRegion,wxGDIObject); }
wxRegion::wxRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) 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) ); M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(rect.x,rect.y,rect.width,rect.height) );
} }
wxRegion::wxRegion()
{
}
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 ) 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() void wxRegion::Clear()
{ {
UnRef(); UnRef();
@@ -156,6 +225,8 @@ bool wxRegion::Union( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
} }
else else
{ {
Unshare();
#ifdef __WXGTK20__ #ifdef __WXGTK20__
gdk_region_union_with_rect( M_REGIONDATA->m_region, &rect ); gdk_region_union_with_rect( M_REGIONDATA->m_region, &rect );
#else #else
@@ -180,11 +251,7 @@ bool wxRegion::Union( const wxRegion& region )
if (region.IsNull()) if (region.IsNull())
return FALSE; return FALSE;
if (!m_refData) Unshare();
{
m_refData = new wxRegionRefData();
M_REGIONDATA->m_region = gdk_region_new();
}
#ifdef __WXGTK20__ #ifdef __WXGTK20__
gdk_region_union( M_REGIONDATA->m_region, region.GetRegion() ); 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 ) 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 ); wxRegion reg( x, y, width, height );
Intersect( reg );
return TRUE; return Intersect( reg );
} }
bool wxRegion::Intersect( const wxRect& rect ) bool wxRegion::Intersect( const wxRect& rect )
{ {
if (!m_refData)
{
m_refData = new wxRegionRefData();
M_REGIONDATA->m_region = gdk_region_new();
}
wxRegion reg( rect ); wxRegion reg( rect );
Intersect( reg ); return Intersect( reg );
return TRUE;
} }
// this helper function just computes the region intersection without updating // 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 // if we called Intersect() itself recursively
bool wxRegion::IntersectRegionOnly(const wxRegion& region) bool wxRegion::IntersectRegionOnly(const wxRegion& region)
{ {
Unshare();
#ifdef __WXGTK20__ #ifdef __WXGTK20__
gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() ); gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() );
#else #else
@@ -295,28 +351,14 @@ bool wxRegion::Intersect( const wxRegion& region )
bool wxRegion::Subtract( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) 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 ); wxRegion reg( x, y, width, height );
Subtract( reg ); return Subtract( reg );
return TRUE;
} }
bool wxRegion::Subtract( const wxRect& rect ) bool wxRegion::Subtract( const wxRect& rect )
{ {
if (!m_refData)
{
m_refData = new wxRegionRefData();
M_REGIONDATA->m_region = gdk_region_new();
}
wxRegion reg( rect ); wxRegion reg( rect );
Subtract( reg ); return Subtract( reg );
return TRUE;
} }
bool wxRegion::Subtract( const wxRegion& region ) bool wxRegion::Subtract( const wxRegion& region )
@@ -330,6 +372,8 @@ bool wxRegion::Subtract( const wxRegion& region )
M_REGIONDATA->m_region = gdk_region_new(); M_REGIONDATA->m_region = gdk_region_new();
} }
Unshare();
#ifdef __WXGTK20__ #ifdef __WXGTK20__
gdk_region_subtract( M_REGIONDATA->m_region, region.GetRegion() ); gdk_region_subtract( M_REGIONDATA->m_region, region.GetRegion() );
#else #else
@@ -337,33 +381,20 @@ bool wxRegion::Subtract( const wxRegion& region )
gdk_region_destroy( M_REGIONDATA->m_region ); gdk_region_destroy( M_REGIONDATA->m_region );
M_REGIONDATA->m_region = reg; M_REGIONDATA->m_region = reg;
#endif #endif
return TRUE; return TRUE;
} }
bool wxRegion::Xor( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) 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 ); wxRegion reg( x, y, width, height );
Xor( reg ); return Xor( reg );
return TRUE;
} }
bool wxRegion::Xor( const wxRect& rect ) bool wxRegion::Xor( const wxRect& rect )
{ {
if (!m_refData)
{
m_refData = new wxRegionRefData();
M_REGIONDATA->m_region = gdk_region_new();
}
wxRegion reg( rect ); wxRegion reg( rect );
Xor( reg ); return Xor( reg );
return TRUE;
} }
bool wxRegion::Xor( const wxRegion& region ) bool wxRegion::Xor( const wxRegion& region )
@@ -376,6 +407,10 @@ bool wxRegion::Xor( const wxRegion& region )
m_refData = new wxRegionRefData(); m_refData = new wxRegionRefData();
M_REGIONDATA->m_region = gdk_region_new(); M_REGIONDATA->m_region = gdk_region_new();
} }
else
{
Unshare();
}
#ifdef __WXGTK20__ #ifdef __WXGTK20__
gdk_region_xor( M_REGIONDATA->m_region, region.GetRegion() ); gdk_region_xor( M_REGIONDATA->m_region, region.GetRegion() );
@@ -396,29 +431,33 @@ bool wxRegion::Xor( const wxRegion& region )
return TRUE; return TRUE;
} }
// ----------------------------------------------------------------------------
// wxRegion tests
// ----------------------------------------------------------------------------
void wxRegion::GetBox( wxCoord &x, wxCoord &y, wxCoord &w, wxCoord &h ) const void wxRegion::GetBox( wxCoord &x, wxCoord &y, wxCoord &w, wxCoord &h ) const
{ {
x = 0; if ( m_refData )
y = 0; {
w = -1; GdkRectangle rect;
h = -1; gdk_region_get_clipbox( M_REGIONDATA->m_region, &rect );
if (!m_refData) x = rect.x;
return; y = rect.y;
w = rect.width;
GdkRectangle rect; h = rect.height;
gdk_region_get_clipbox( M_REGIONDATA->m_region, &rect ); }
x = rect.x; else
y = rect.y; {
w = rect.width; x = 0;
h = rect.height; y = 0;
w = -1;
h = -1;
}
} }
wxRect wxRegion::GetBox() const wxRect wxRegion::GetBox() const
{ {
wxCoord x = 0; wxCoord x, y, w, h;
wxCoord y = 0;
wxCoord w = -1;
wxCoord h = -1;
GetBox( x, y, w, h ); GetBox( x, y, w, h );
return wxRect( x, y, w, h ); return wxRect( x, y, w, h );
} }
@@ -488,11 +527,9 @@ wxList *wxRegion::GetRectList() const
return &(M_REGIONDATA->m_rects); return &(M_REGIONDATA->m_rects);
} }
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxRegion // wxRegionIterator
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator,wxObject);
wxRegionIterator::wxRegionIterator() wxRegionIterator::wxRegionIterator()
{ {

View File

@@ -2223,19 +2223,19 @@ wxPaintDC::wxPaintDC( wxWindow *win )
: wxClientDC( win ) : wxClientDC( win )
{ {
#if USE_PAINT_REGION #if USE_PAINT_REGION
if (!win->m_clipPaintRegion) if ( win->m_clipPaintRegion )
return;
m_paintClippingRegion = win->GetUpdateRegion();
GdkRegion *region = m_paintClippingRegion.GetRegion();
if ( region )
{ {
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_penGC, region );
gdk_gc_set_clip_region( m_brushGC, region ); gdk_gc_set_clip_region( m_brushGC, region );
gdk_gc_set_clip_region( m_textGC, region ); gdk_gc_set_clip_region( m_textGC, region );
gdk_gc_set_clip_region( m_bgGC, region ); gdk_gc_set_clip_region( m_bgGC, region );
}
} }
#endif // USE_PAINT_REGION #endif // USE_PAINT_REGION
} }

View File

@@ -2,40 +2,89 @@
// Name: gtk/region.cpp // Name: gtk/region.cpp
// Purpose: // Purpose:
// Author: Robert Roebling // Author: Robert Roebling
// Modified: VZ at 05.10.00: use Unshare(), comparison fixed
// Id: $Id$ // Id: $Id$
// Copyright: (c) 1998 Robert Roebling // Copyright: (c) 1998 Robert Roebling
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation "region.h" #pragma implementation "region.h"
#endif #endif
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "wx/region.h" #include "wx/region.h"
#include <gdk/gdk.h> #include <gdk/gdk.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "wx/log.h"
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxRegion // wxRegionRefData: private class containing the information about the region
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class wxRegionRefData: public wxObjectRefData class wxRegionRefData : public wxObjectRefData
{ {
public: public:
wxRegionRefData(); wxRegionRefData();
~wxRegionRefData(); wxRegionRefData(const wxRegionRefData& refData);
virtual ~wxRegionRefData();
GdkRegion *m_region; GdkRegion *m_region;
wxList m_rects; 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() wxRegionRefData::wxRegionRefData()
{ {
m_region = (GdkRegion *) NULL; 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() wxRegionRefData::~wxRegionRefData()
{ {
if (m_region) gdk_region_destroy( m_region ); if (m_region) gdk_region_destroy( m_region );
@@ -49,11 +98,13 @@ wxRegionRefData::~wxRegionRefData()
} }
} }
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxRegion construction
// ----------------------------------------------------------------------------
#define M_REGIONDATA ((wxRegionRefData *)m_refData) wxRegion::wxRegion()
{
IMPLEMENT_DYNAMIC_CLASS(wxRegion,wxGDIObject); }
wxRegion::wxRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) 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) ); M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(rect.x,rect.y,rect.width,rect.height) );
} }
wxRegion::wxRegion()
{
}
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 ) 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() void wxRegion::Clear()
{ {
UnRef(); UnRef();
@@ -156,6 +225,8 @@ bool wxRegion::Union( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
} }
else else
{ {
Unshare();
#ifdef __WXGTK20__ #ifdef __WXGTK20__
gdk_region_union_with_rect( M_REGIONDATA->m_region, &rect ); gdk_region_union_with_rect( M_REGIONDATA->m_region, &rect );
#else #else
@@ -180,11 +251,7 @@ bool wxRegion::Union( const wxRegion& region )
if (region.IsNull()) if (region.IsNull())
return FALSE; return FALSE;
if (!m_refData) Unshare();
{
m_refData = new wxRegionRefData();
M_REGIONDATA->m_region = gdk_region_new();
}
#ifdef __WXGTK20__ #ifdef __WXGTK20__
gdk_region_union( M_REGIONDATA->m_region, region.GetRegion() ); 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 ) 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 ); wxRegion reg( x, y, width, height );
Intersect( reg );
return TRUE; return Intersect( reg );
} }
bool wxRegion::Intersect( const wxRect& rect ) bool wxRegion::Intersect( const wxRect& rect )
{ {
if (!m_refData)
{
m_refData = new wxRegionRefData();
M_REGIONDATA->m_region = gdk_region_new();
}
wxRegion reg( rect ); wxRegion reg( rect );
Intersect( reg ); return Intersect( reg );
return TRUE;
} }
// this helper function just computes the region intersection without updating // 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 // if we called Intersect() itself recursively
bool wxRegion::IntersectRegionOnly(const wxRegion& region) bool wxRegion::IntersectRegionOnly(const wxRegion& region)
{ {
Unshare();
#ifdef __WXGTK20__ #ifdef __WXGTK20__
gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() ); gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() );
#else #else
@@ -295,28 +351,14 @@ bool wxRegion::Intersect( const wxRegion& region )
bool wxRegion::Subtract( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) 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 ); wxRegion reg( x, y, width, height );
Subtract( reg ); return Subtract( reg );
return TRUE;
} }
bool wxRegion::Subtract( const wxRect& rect ) bool wxRegion::Subtract( const wxRect& rect )
{ {
if (!m_refData)
{
m_refData = new wxRegionRefData();
M_REGIONDATA->m_region = gdk_region_new();
}
wxRegion reg( rect ); wxRegion reg( rect );
Subtract( reg ); return Subtract( reg );
return TRUE;
} }
bool wxRegion::Subtract( const wxRegion& region ) bool wxRegion::Subtract( const wxRegion& region )
@@ -330,6 +372,8 @@ bool wxRegion::Subtract( const wxRegion& region )
M_REGIONDATA->m_region = gdk_region_new(); M_REGIONDATA->m_region = gdk_region_new();
} }
Unshare();
#ifdef __WXGTK20__ #ifdef __WXGTK20__
gdk_region_subtract( M_REGIONDATA->m_region, region.GetRegion() ); gdk_region_subtract( M_REGIONDATA->m_region, region.GetRegion() );
#else #else
@@ -337,33 +381,20 @@ bool wxRegion::Subtract( const wxRegion& region )
gdk_region_destroy( M_REGIONDATA->m_region ); gdk_region_destroy( M_REGIONDATA->m_region );
M_REGIONDATA->m_region = reg; M_REGIONDATA->m_region = reg;
#endif #endif
return TRUE; return TRUE;
} }
bool wxRegion::Xor( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) 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 ); wxRegion reg( x, y, width, height );
Xor( reg ); return Xor( reg );
return TRUE;
} }
bool wxRegion::Xor( const wxRect& rect ) bool wxRegion::Xor( const wxRect& rect )
{ {
if (!m_refData)
{
m_refData = new wxRegionRefData();
M_REGIONDATA->m_region = gdk_region_new();
}
wxRegion reg( rect ); wxRegion reg( rect );
Xor( reg ); return Xor( reg );
return TRUE;
} }
bool wxRegion::Xor( const wxRegion& region ) bool wxRegion::Xor( const wxRegion& region )
@@ -376,6 +407,10 @@ bool wxRegion::Xor( const wxRegion& region )
m_refData = new wxRegionRefData(); m_refData = new wxRegionRefData();
M_REGIONDATA->m_region = gdk_region_new(); M_REGIONDATA->m_region = gdk_region_new();
} }
else
{
Unshare();
}
#ifdef __WXGTK20__ #ifdef __WXGTK20__
gdk_region_xor( M_REGIONDATA->m_region, region.GetRegion() ); gdk_region_xor( M_REGIONDATA->m_region, region.GetRegion() );
@@ -396,29 +431,33 @@ bool wxRegion::Xor( const wxRegion& region )
return TRUE; return TRUE;
} }
// ----------------------------------------------------------------------------
// wxRegion tests
// ----------------------------------------------------------------------------
void wxRegion::GetBox( wxCoord &x, wxCoord &y, wxCoord &w, wxCoord &h ) const void wxRegion::GetBox( wxCoord &x, wxCoord &y, wxCoord &w, wxCoord &h ) const
{ {
x = 0; if ( m_refData )
y = 0; {
w = -1; GdkRectangle rect;
h = -1; gdk_region_get_clipbox( M_REGIONDATA->m_region, &rect );
if (!m_refData) x = rect.x;
return; y = rect.y;
w = rect.width;
GdkRectangle rect; h = rect.height;
gdk_region_get_clipbox( M_REGIONDATA->m_region, &rect ); }
x = rect.x; else
y = rect.y; {
w = rect.width; x = 0;
h = rect.height; y = 0;
w = -1;
h = -1;
}
} }
wxRect wxRegion::GetBox() const wxRect wxRegion::GetBox() const
{ {
wxCoord x = 0; wxCoord x, y, w, h;
wxCoord y = 0;
wxCoord w = -1;
wxCoord h = -1;
GetBox( x, y, w, h ); GetBox( x, y, w, h );
return wxRect( x, y, w, h ); return wxRect( x, y, w, h );
} }
@@ -488,11 +527,9 @@ wxList *wxRegion::GetRectList() const
return &(M_REGIONDATA->m_rects); return &(M_REGIONDATA->m_rects);
} }
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxRegion // wxRegionIterator
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator,wxObject);
wxRegionIterator::wxRegionIterator() wxRegionIterator::wxRegionIterator()
{ {

View File

@@ -15,13 +15,12 @@ UNIVOBJS = \
statbox.o \ statbox.o \
statline.o \ statline.o \
stattext.o \ stattext.o \
textctrl.o \
theme.o \ theme.o \
gtk.o \ gtk.o \
winuniv.o \ winuniv.o \
win32.o win32.o
# textctrl.o \
UNIVDEPS = \ UNIVDEPS = \
bmpbuttn.d \ bmpbuttn.d \
button.d \ button.d \

View File

@@ -120,8 +120,14 @@ bool wxTextCtrl::Create(wxWindow *parent,
SetCursor(wxCURSOR_IBEAM); SetCursor(wxCURSOR_IBEAM);
SetValue(value); SetValue(value);
SetBestSize(m_sizeInitial); SetBestSize(size);
CreateCaret(); 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; return TRUE;
} }
@@ -135,7 +141,7 @@ bool wxTextCtrl::SetFont(const wxFont& font)
CreateCaret(); CreateCaret();
// and refresh everything, of course // and refresh everything, of course
SetInsertionPoint(0); InitInsertionPoint();
ClearSelection(); ClearSelection();
Refresh(); Refresh();
@@ -245,30 +251,42 @@ void wxTextCtrl::SetInsertionPoint(long pos)
wxCHECK_RET( pos >= 0 && pos <= GetLastPosition(), wxCHECK_RET( pos >= 0 && pos <= GetLastPosition(),
_T("insertion point position out of range") ); _T("insertion point position out of range") );
// don't do anything if it didn't change
if ( pos != m_curPos ) if ( pos != m_curPos )
{ {
HideCaret(); DoSetInsertionPoint(pos);
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::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() void wxTextCtrl::SetInsertionPointEnd()
{ {
SetInsertionPoint(GetLastPosition()); SetInsertionPoint(GetLastPosition());
@@ -852,6 +870,14 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTestLine(const wxString& line,
// and this should give us much better approximation in such case // and this should give us much better approximation in such case
dc.GetTextExtent(line[0], &width, NULL); dc.GetTextExtent(line[0], &width, NULL);
col = x / width; 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 // matchDir is -1 if we must move left, +1 to move right and 0 when
// we're exactly on the character we need // we're exactly on the character we need
@@ -1185,7 +1211,7 @@ void wxTextCtrl::RefreshTextRange(long start, long end)
if ( !PositionToXY(end, &colEnd, &lineEnd) ) if ( !PositionToXY(end, &colEnd, &lineEnd) )
{ {
// the range spans beyond the end of text, refresh to the end // the range spans beyond the end of text, refresh to the end
colEnd = wxSTRING_MAXLEN; colEnd = -1;
lineEnd = GetNumberOfLines() - 1; lineEnd = GetNumberOfLines() - 1;
} }
@@ -1197,7 +1223,7 @@ void wxTextCtrl::RefreshTextRange(long start, long end)
// the end of the range // the end of the range
long posStart = line == lineStart ? colStart : 0; long posStart = line == lineStart ? colStart : 0;
long posCount; 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 // intermediate line or the last one but we need to refresh it
// until the end anyhow - do it // until the end anyhow - do it
@@ -1486,6 +1512,15 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
DoDrawTextInRect(dc, r); 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() will delete the old caret if any
SetCaret(caret); SetCaret(caret);
caret->Show();
} }
wxCoord wxTextCtrl::GetCaretPosition() const wxCoord wxTextCtrl::GetCaretPosition() const
@@ -1689,7 +1722,16 @@ void wxTextCtrl::OnChar(wxKeyEvent& event)
if ( !event.HasModifiers() ) if ( !event.HasModifiers() )
{ {
int keycode = event.GetKeyCode(); 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); PerformAction(wxACTION_TEXT_INSERT, -1, (wxChar)keycode);

View File

@@ -41,10 +41,10 @@
#include "wx/univ/theme.h" #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 // wxGTKRenderer: draw the GUI elements in GTK style
@@ -734,7 +734,7 @@ wxRect wxGTKRenderer::GetBorderDimensions(wxBorder border) const
{ {
case wxBORDER_RAISED: case wxBORDER_RAISED:
case wxBORDER_SUNKEN: case wxBORDER_SUNKEN:
width = 20; width = 2*BORDER_THICKNESS;
break; break;
case wxBORDER_SIMPLE: case wxBORDER_SIMPLE:

View File

@@ -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 // 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 // blended into it), take account of the right border as well
if ( !m_scrollbarVert || inside ) if ( !m_scrollbarVert || !inside )
w -= rectBorder.width; w -= rectBorder.width;
// and always account for the left border // and always account for the left border
@@ -435,7 +435,7 @@ void wxWindow::DoGetClientSize(int *width, int *height) const
if ( m_scrollbarHorz ) if ( m_scrollbarHorz )
h -= m_scrollbarHorz->GetSize().y; h -= m_scrollbarHorz->GetSize().y;
if ( !m_scrollbarHorz || inside ) if ( !m_scrollbarHorz || !inside )
h -= rectBorder.height; h -= rectBorder.height;
*height = h - rectBorder.y; *height = h - rectBorder.y;