1. wxNcPaintEvent for wxMSW

2. wxTextCtrl (single line) cursor movement/basic editing


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8382 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-09-17 04:03:07 +00:00
parent 8c1e69867c
commit c7a0b9e59e
17 changed files with 527 additions and 95 deletions

View File

@@ -51,8 +51,6 @@ public:
class WXDLLEXPORT wxClientDC : public wxWindowDC class WXDLLEXPORT wxClientDC : public wxWindowDC
{ {
DECLARE_DYNAMIC_CLASS(wxClientDC)
public: public:
wxClientDC(); wxClientDC();
@@ -60,12 +58,16 @@ public:
wxClientDC(wxWindow *win); wxClientDC(wxWindow *win);
virtual ~wxClientDC(); virtual ~wxClientDC();
protected:
void InitDC();
private:
DECLARE_DYNAMIC_CLASS(wxClientDC)
}; };
class WXDLLEXPORT wxPaintDC : public wxWindowDC class WXDLLEXPORT wxPaintDC : public wxClientDC
{ {
DECLARE_DYNAMIC_CLASS(wxPaintDC)
public: public:
wxPaintDC(); wxPaintDC();
@@ -82,6 +84,9 @@ protected:
// find the entry for this DC in the cache (keyed by the window) // find the entry for this DC in the cache (keyed by the window)
wxPaintDCInfo *FindInCache(size_t *index = NULL) const; wxPaintDCInfo *FindInCache(size_t *index = NULL) const;
private:
DECLARE_DYNAMIC_CLASS(wxPaintDC)
}; };
#endif #endif

View File

@@ -265,7 +265,7 @@ public:
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxStdCheckListBoxHandler // wxStdCheckListBoxInputHandler
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class WXDLLEXPORT wxStdCheckListboxInputHandler : public wxStdListboxInputHandler class WXDLLEXPORT wxStdCheckListboxInputHandler : public wxStdListboxInputHandler
@@ -280,4 +280,23 @@ public:
const wxMouseEvent& event); const wxMouseEvent& event);
}; };
// ----------------------------------------------------------------------------
// wxStdTextCtrlInputHandler: this control handles only the mouse/kbd actions
// common to Win32 and GTK, platform-specific things are implemented elsewhere
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxStdTextCtrlInputHandler : public wxStdInputHandler
{
public:
wxStdTextCtrlInputHandler(wxInputHandler *inphand);
virtual bool HandleKey(wxControl *control,
const wxKeyEvent& event,
bool pressed);
virtual bool HandleMouse(wxControl *control,
const wxMouseEvent& event);
virtual bool HandleMouseMove(wxControl *control,
const wxMouseEvent& event);
};
#endif // _WX_UNIV_INPHAND_H_ #endif // _WX_UNIV_INPHAND_H_

View File

@@ -97,6 +97,12 @@ public:
int indexAccel = -1, int indexAccel = -1,
wxRect *rectBounds = NULL) = 0; wxRect *rectBounds = NULL) = 0;
// draw a line of the text ctrl
virtual void DrawTextLine(wxDC& dc,
const wxString& text,
const wxRect &rect,
int flags = 0) = 0;
// draw the border and optionally return the rectangle containing the // draw the border and optionally return the rectangle containing the
// region inside the border // region inside the border
virtual void DrawBorder(wxDC& dc, virtual void DrawBorder(wxDC& dc,
@@ -291,6 +297,11 @@ public:
wxRect *rectBounds = NULL) wxRect *rectBounds = NULL)
{ m_renderer->DrawButtonLabel(dc, label, image, rect, { m_renderer->DrawButtonLabel(dc, label, image, rect,
flags, align, indexAccel, rectBounds); } flags, align, indexAccel, rectBounds); }
virtual void DrawTextLine(wxDC& dc,
const wxString& text,
const wxRect &rect,
int flags = 0)
{ m_renderer->DrawTextLine(dc, text, rect, flags); }
virtual void DrawBorder(wxDC& dc, virtual void DrawBorder(wxDC& dc,
wxBorder border, wxBorder border,
const wxRect& rect, const wxRect& rect,
@@ -412,6 +423,7 @@ public:
// operations // operations
void DrawLabel(const wxBitmap& bitmap = wxNullBitmap, void DrawLabel(const wxBitmap& bitmap = wxNullBitmap,
wxCoord marginX = 0, wxCoord marginY = 0); wxCoord marginX = 0, wxCoord marginY = 0);
void DrawTextLine(const wxString& text);
void DrawItems(const wxListBox *listbox, void DrawItems(const wxListBox *listbox,
size_t itemFirst, size_t itemLast); size_t itemFirst, size_t itemLast);
void DrawCheckItems(const wxCheckListBox *listbox, void DrawCheckItems(const wxCheckListBox *listbox,

View File

@@ -20,7 +20,7 @@
#define WXWIN_COMPATIBILITY 0 #define WXWIN_COMPATIBILITY 0
#define wxICON_IS_BITMAP 0 #define wxICON_IS_BITMAP 0
#define wxFONT_SIZE_COMPATIBILITY 0 #define wxFONT_SIZE_COMPATIBILITY 0
#define wxDIALOG_UNIT_COMPATIBILITY 1 #define wxDIALOG_UNIT_COMPATIBILITY 0
#define wxUSE_DEBUG_CONTEXT 0 #define wxUSE_DEBUG_CONTEXT 0
#define wxUSE_MEMORY_TRACING 0 #define wxUSE_MEMORY_TRACING 0
#define wxUSE_GLOBAL_MEMORY_OPERATORS 0 #define wxUSE_GLOBAL_MEMORY_OPERATORS 0
@@ -68,7 +68,7 @@
#define wxUSE_CONTROLS 1 #define wxUSE_CONTROLS 1
#define wxUSE_BUTTON 1 #define wxUSE_BUTTON 1
#define wxUSE_BMPBUTTON 1 #define wxUSE_BMPBUTTON 1
#define wxUSE_CARET 0 #define wxUSE_CARET 1
#define wxUSE_CHECKBOX 1 #define wxUSE_CHECKBOX 1
#define wxUSE_CHECKLISTBOX 1 #define wxUSE_CHECKLISTBOX 1
#define wxUSE_CHOICE 0 #define wxUSE_CHOICE 0
@@ -88,6 +88,7 @@
#define wxUSE_STATTEXT 1 #define wxUSE_STATTEXT 1
#define wxUSE_STATBMP 1 #define wxUSE_STATBMP 1
#define wxUSE_STATUSBAR 0 #define wxUSE_STATUSBAR 0
#define wxUSE_TEXTCTRL 1
#define wxUSE_TOOLTIPS 0 #define wxUSE_TOOLTIPS 0
#define wxUSE_TREECTRL 0 #define wxUSE_TREECTRL 0

View File

@@ -22,6 +22,32 @@ class WXDLLEXPORT wxCaret;
// wxTextCtrl actions // wxTextCtrl actions
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// cursor movement and also selection and delete operations
#define wxACTION_TEXT_HOME _T("home")
#define wxACTION_TEXT_END _T("end")
#define wxACTION_TEXT_LEFT _T("left")
#define wxACTION_TEXT_RIGHT _T("right")
#define wxACTION_TEXT_UP _T("up")
#define wxACTION_TEXT_DOWN _T("down")
#define wxACTION_TEXT_WORD_LEFT _T("wordleft")
#define wxACTION_TEXT_WORD_RIGHT _T("wordright")
#define wxACTION_TEXT_PAGE_UP _T("pageup")
#define wxACTION_TEXT_PAGE_DOWN _T("pagedown")
// clipboard operations
#define wxACTION_TEXT_COPY _T("copy")
#define wxACTION_TEXT_CUT _T("cut")
#define wxACTION_TEXT_PASTE _T("paste")
// insert text at the cursor position: the text is in strArg of PerformAction
#define wxACTION_TEXT_INSERT _T("insert")
// if the action starts with either of these prefixes and the rest of the
// string is one of the movement commands, it means to select/delete text from
// the current cursor position to the new one
#define wxACTION_TEXT_PREFIX_SEL _T("sel")
#define wxACTION_TEXT_PREFIX_DEL _T("del")
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxTextCtrl // wxTextCtrl
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -125,6 +151,10 @@ public:
virtual void ShowCaret(bool show = TRUE); virtual void ShowCaret(bool show = TRUE);
void HideCaret() { ShowCaret(FALSE); } void HideCaret() { ShowCaret(FALSE); }
// helpers for cursor movement
long GetWordStart() const;
long GetWordEnd() const;
// implementation only from now on // implementation only from now on
// ------------------------------- // -------------------------------
@@ -151,6 +181,9 @@ protected:
// is this a single-line control? // is this a single-line control?
bool IsSingleLine() const { return !(GetWindowStyle() & wxTE_MULTILINE); } bool IsSingleLine() const { return !(GetWindowStyle() & wxTE_MULTILINE); }
// event handlers
void OnChar(wxKeyEvent& event);
private: private:
// the value (may be only part of it for the multiline controls) // the value (may be only part of it for the multiline controls)
wxString m_value; wxString m_value;

View File

@@ -115,6 +115,7 @@ protected:
void OnCheckBox(wxCommandEvent& event); void OnCheckBox(wxCommandEvent& event);
void OnRadioBox(wxCommandEvent& event); void OnRadioBox(wxCommandEvent& event);
void OnListBox(wxCommandEvent& event); void OnListBox(wxCommandEvent& event);
void OnTextChange(wxCommandEvent& event);
void OnLeftUp(wxMouseEvent& event); void OnLeftUp(wxMouseEvent& event);
private: private:
@@ -157,6 +158,7 @@ BEGIN_EVENT_TABLE(MyUnivFrame, wxFrame)
EVT_CHECKBOX(-1, MyUnivFrame::OnCheckBox) EVT_CHECKBOX(-1, MyUnivFrame::OnCheckBox)
EVT_RADIOBUTTON(-1, MyUnivFrame::OnRadioBox) EVT_RADIOBUTTON(-1, MyUnivFrame::OnRadioBox)
EVT_LISTBOX(-1, MyUnivFrame::OnListBox) EVT_LISTBOX(-1, MyUnivFrame::OnListBox)
EVT_TEXT(-1, MyUnivFrame::OnTextChange)
EVT_LEFT_UP(MyUnivFrame::OnLeftUp) EVT_LEFT_UP(MyUnivFrame::OnLeftUp)
END_EVENT_TABLE() END_EVENT_TABLE()
@@ -225,18 +227,18 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
{ {
SetBackgroundColour(wxGetApp().GetBgColour()); SetBackgroundColour(wxGetApp().GetBgColour());
wxStaticText *text;
new wxStaticText(this, _T("Test static text"), wxPoint(10, 10)); new wxStaticText(this, _T("Test static text"), wxPoint(10, 10));
new wxStaticText(this, -1, #if 0
new wxStaticText(this,
_T("&Multi line\n(and very very very very long)\nstatic text"), _T("&Multi line\n(and very very very very long)\nstatic text"),
wxPoint(210, 10), wxDefaultSize, wxBORDER_SUNKEN); wxPoint(210, 10));
(new wxStaticText(this, _T("&Disabled text"), wxPoint(10, 30)))->Disable(); (new wxStaticText(this, _T("&Disabled text"), wxPoint(10, 30)))->Disable();
new wxStaticLine(this, wxPoint(190, 10), 50, wxLI_VERTICAL); new wxStaticLine(this, wxPoint(190, 10), 50, wxLI_VERTICAL);
text = new wxStaticText(this, _T("Demo of &border styles:"), wxPoint(10, 60)); wxStaticText *text = new wxStaticText(this, _T("Demo of &border styles:"),
wxPoint(10, 60));
text->SetFont(*wxITALIC_FONT); text->SetFont(*wxITALIC_FONT);
text->SetBackgroundColour(*wxWHITE); text->SetBackgroundColour(*wxWHITE);
text->SetForegroundColour(*wxBLUE); text->SetForegroundColour(*wxBLUE);
@@ -368,6 +370,10 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
new wxTextCtrl(this, -1, _T("Hello, Universe!"), new wxTextCtrl(this, -1, _T("Hello, Universe!"),
wxPoint(550, 150), wxDefaultSize); wxPoint(550, 150), wxDefaultSize);
#else // 1
new wxTextCtrl(this, -1, _T("Hello, Universe!"),
wxPoint(10, 50), wxSize(200, -1));
#endif // 0/1
} }
void MyUnivFrame::OnButton(wxCommandEvent& event) void MyUnivFrame::OnButton(wxCommandEvent& event)
@@ -399,6 +405,11 @@ void MyUnivFrame::OnListBox(wxCommandEvent& event)
wxLogDebug(_T("Listbox item %d selected."), event.GetInt()); wxLogDebug(_T("Listbox item %d selected."), event.GetInt());
} }
void MyUnivFrame::OnTextChange(wxCommandEvent& event)
{
wxLogDebug(_T("Text control value changed: now '%s'"), event.GetString());
}
void MyUnivFrame::OnLeftUp(wxMouseEvent& event) void MyUnivFrame::OnLeftUp(wxMouseEvent& event)
{ {
if ( event.ControlDown() ) if ( event.ControlDown() )

View File

@@ -483,16 +483,6 @@ void wxScrollHelper::DoPrepareDC(wxDC& dc)
dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine, dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine,
-m_yScrollPosition * m_yScrollPixelsPerLine ); -m_yScrollPosition * m_yScrollPixelsPerLine );
dc.SetUserScale( m_scaleX, m_scaleY ); dc.SetUserScale( m_scaleX, m_scaleY );
// now done in wxPaintDC itself
#if 0
// for wxUniversal we need to set the clipping region to avoid overwriting
// the scrollbars with the user drawing
wxSize size = m_win->GetClientSize();
dc.SetClippingRegion(m_xScrollPosition * m_xScrollPixelsPerLine,
m_yScrollPosition * m_yScrollPixelsPerLine,
size.x, size.y);
#endif // 0
} }
void wxScrollHelper::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const void wxScrollHelper::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const

View File

@@ -64,7 +64,7 @@ WX_DEFINE_OBJARRAY(wxArrayDCInfo);
IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC) IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC)
IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC) IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxClientDC)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// global variables // global variables
@@ -93,10 +93,10 @@ wxWindowDC::wxWindowDC()
m_canvas = NULL; m_canvas = NULL;
} }
wxWindowDC::wxWindowDC(wxWindow *the_canvas) wxWindowDC::wxWindowDC(wxWindow *canvas)
{ {
m_canvas = the_canvas; m_canvas = canvas;
m_hDC = (WXHDC) ::GetWindowDC(GetWinHwnd(the_canvas) ); m_hDC = (WXHDC) ::GetWindowDC(GetWinHwnd(canvas) );
m_hDCCount++; m_hDCCount++;
SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID)); SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID));
@@ -128,17 +128,31 @@ wxClientDC::wxClientDC()
m_canvas = NULL; m_canvas = NULL;
} }
wxClientDC::wxClientDC(wxWindow *the_canvas) wxClientDC::wxClientDC(wxWindow *canvas)
{ {
m_canvas = the_canvas; // init the DC
m_hDC = (WXHDC) ::GetDC(GetWinHwnd(the_canvas)); m_canvas = canvas;
m_hDC = (WXHDC) ::GetDC(GetWinHwnd(canvas));
// the background mode is only used for text background // (re)set the DC parameters
// and is set in DrawText() to OPAQUE as required, other- InitDC();
// wise always TRANSPARENT, RR }
void wxClientDC::InitDC()
{
// the background mode is only used for text background and is set in
// DrawText() to OPAQUE as required, otherwise always TRANSPARENT (RR)
::SetBkMode(GetHdc(), TRANSPARENT); ::SetBkMode(GetHdc(), TRANSPARENT);
SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID)); SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID));
// clip the DC to avoid overwriting the non client area
#ifdef __WXUNIVERSAL__
wxPoint ptOrigin = m_canvas->GetClientAreaOrigin();
SetDeviceOrigin(ptOrigin.x, ptOrigin.y);
wxSize size = m_canvas->GetClientSize();
SetClippingRegion(wxPoint(0, 0), size);
#endif // __WXUNIVERSAL__
} }
wxClientDC::~wxClientDC() wxClientDC::~wxClientDC()
@@ -208,12 +222,8 @@ wxPaintDC::wxPaintDC(wxWindow *canvas)
ms_cache.Add(new wxPaintDCInfo(m_canvas, this)); ms_cache.Add(new wxPaintDCInfo(m_canvas, this));
} }
// the background mode is only used for text background // (re)set the DC parameters
// and is set in DrawText() to OPAQUE as required, other- InitDC();
// wise always TRANSPARENT, RR
::SetBkMode( GetHdc(), TRANSPARENT );
SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID));
} }
wxPaintDC::~wxPaintDC() wxPaintDC::~wxPaintDC()

View File

@@ -2992,19 +2992,28 @@ bool wxWindowMSW::HandlePaint()
wxLogLastError(wxT("GetUpdateRgn")); wxLogLastError(wxT("GetUpdateRgn"));
m_updateRegion = wxRegion((WXHRGN) hRegion); m_updateRegion = wxRegion((WXHRGN) hRegion);
#else #else // Win16
RECT updateRect; RECT updateRect;
::GetUpdateRect(GetHwnd(), &updateRect, FALSE); ::GetUpdateRect(GetHwnd(), &updateRect, FALSE);
m_updateRegion = wxRegion(updateRect.left, updateRect.top, m_updateRegion = wxRegion(updateRect.left, updateRect.top,
updateRect.right - updateRect.left, updateRect.right - updateRect.left,
updateRect.bottom - updateRect.top); updateRect.bottom - updateRect.top);
#endif #endif // Win32/16
wxPaintEvent event(m_windowId); wxPaintEvent event(m_windowId);
event.SetEventObject(this); event.SetEventObject(this);
return GetEventHandler()->ProcessEvent(event); bool processed = GetEventHandler()->ProcessEvent(event);
// note that we must generate NC event after the normal one as otherwise
// BeginPaint() will happily overwrite our decorations with the background
// colour
wxNcPaintEvent eventNc(m_windowId);
eventNc.SetEventObject(this);
GetEventHandler()->ProcessEvent(eventNc);
return processed;
} }
// Can be called from an application's OnPaint handler // Can be called from an application's OnPaint handler

View File

@@ -132,9 +132,8 @@ int wxListBox::DoAppend(const wxString& item)
if ( HasHorzScrollbar() ) if ( HasHorzScrollbar() )
{ {
// has the max width increased? // has the max width increased?
wxClientDC dc(this);
wxCoord width; wxCoord width;
dc.GetTextExtent(item, &width, NULL); GetTextExtent(item, &width, NULL);
if ( width > m_maxWidth ) if ( width > m_maxWidth )
{ {
m_maxWidth = width; m_maxWidth = width;
@@ -523,12 +522,12 @@ void wxListBox::DoDraw(wxControlRenderer *renderer)
// adjust the DC to account for scrolling // adjust the DC to account for scrolling
wxDC& dc = renderer->GetDC(); wxDC& dc = renderer->GetDC();
PrepareDC(dc); PrepareDC(dc);
dc.SetFont(GetFont());
// get the items which must be redrawn // get the items which must be redrawn
wxCoord lineHeight = GetLineHeight(); wxCoord lineHeight = GetLineHeight();
wxRegion rgnUpdate = GetUpdateRegion(); wxRegion rgnUpdate = GetUpdateRegion();
rgnUpdate.Intersect(GetClientRect()); rgnUpdate.Intersect(GetClientRect());
//dc.SetClippingRegion(rgnUpdate);
wxRect rectUpdate = rgnUpdate.GetBox(); wxRect rectUpdate = rgnUpdate.GetBox();
int yTop, yBottom; int yTop, yBottom;
@@ -575,8 +574,7 @@ bool wxListBox::SetFont(const wxFont& font)
void wxListBox::CalcItemsPerPage() void wxListBox::CalcItemsPerPage()
{ {
m_lineHeight = GetRenderer()-> m_lineHeight = GetRenderer()->GetListboxItemHeight(GetCharHeight());
GetListboxItemHeight(wxClientDC(this).GetCharHeight());
m_itemsPerPage = GetClientSize().y / m_lineHeight; m_itemsPerPage = GetClientSize().y / m_lineHeight;
} }
@@ -634,8 +632,6 @@ void wxListBox::DoSetFirstItem(int n)
wxSize wxListBox::DoGetBestClientSize() const wxSize wxListBox::DoGetBestClientSize() const
{ {
wxClientDC dc(wxConstCast(this, wxListBox));
wxCoord width = 0, wxCoord width = 0,
height = 0; height = 0;
@@ -643,7 +639,7 @@ wxSize wxListBox::DoGetBestClientSize() const
for ( size_t n = 0; n < count; n++ ) for ( size_t n = 0; n < count; n++ )
{ {
wxCoord w,h; wxCoord w,h;
dc.GetTextExtent(m_strings[n], &w, &h); GetTextExtent(m_strings[n], &w, &h);
if ( w > width ) if ( w > width )
width = w; width = w;
@@ -656,10 +652,10 @@ wxSize wxListBox::DoGetBestClientSize() const
if ( !width ) if ( !width )
width = 100; width = 100;
else else
width += 3*dc.GetCharWidth(); width += 3*GetCharWidth();
if ( !height ) if ( !height )
height = dc.GetCharHeight(); height = GetCharHeight();
// we need the height of the entire listbox, not just of one line // we need the height of the entire listbox, not just of one line
height *= wxMax(count, 7); height *= wxMax(count, 7);

View File

@@ -45,8 +45,8 @@
// constants // constants
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static const int BUTTON_BORDER_X = 3; static const int BUTTON_BORDER_X = 0;
static const int BUTTON_BORDER_Y = 3; static const int BUTTON_BORDER_Y = 0;
static const int BOX_BORDER_X = 0; static const int BOX_BORDER_X = 0;
static const int BOX_BORDER_Y = 0; static const int BOX_BORDER_Y = 0;

View File

@@ -575,7 +575,10 @@ void wxControlRenderer::DoDrawItems(const wxListBox *lbox,
// note that SetClippingRegion() needs the physical (unscrolled) // note that SetClippingRegion() needs the physical (unscrolled)
// coordinates while we use the logical (scrolled) ones for the drawing // coordinates while we use the logical (scrolled) ones for the drawing
// itself // itself
wxRect rect = lbox->GetClientRect(); wxRect rect;
wxSize size = lbox->GetClientSize();
rect.width = size.x;
rect.height = size.y;
// keep the text inside the client rect or we will overwrite the vertical // keep the text inside the client rect or we will overwrite the vertical
// scrollbar for the long strings // scrollbar for the long strings
@@ -626,3 +629,11 @@ void wxControlRenderer::DoDrawItems(const wxListBox *lbox,
rect.y += lineHeight; rect.y += lineHeight;
} }
} }
void wxControlRenderer::DrawTextLine(const wxString& text)
{
m_dc.SetFont(m_window->GetFont());
m_dc.SetTextForeground(m_window->GetForegroundColour());
m_renderer->DrawTextLine(m_dc, text, m_rect, m_window->GetStateFlags());
}

View File

@@ -46,6 +46,7 @@
// ============================================================================ // ============================================================================
BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
EVT_CHAR(OnChar)
END_EVENT_TABLE() END_EVENT_TABLE()
IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl) IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
@@ -80,7 +81,8 @@ bool wxTextCtrl::Create(wxWindow *parent,
return FALSE; return FALSE;
} }
wxCaret *caret = new wxCaret(this, 1, GetCharHeight()); // FIXME use renderer
wxCaret *caret = new wxCaret(this, 2, GetCharHeight());
SetCaret(caret); SetCaret(caret);
caret->Show(); caret->Show();
@@ -98,6 +100,9 @@ bool wxTextCtrl::Create(wxWindow *parent,
void wxTextCtrl::SetValue(const wxString& value) void wxTextCtrl::SetValue(const wxString& value)
{ {
if ( m_value == value )
return;
m_value = value; m_value = value;
if ( IsSingleLine() ) if ( IsSingleLine() )
@@ -108,6 +113,8 @@ void wxTextCtrl::SetValue(const wxString& value)
{ {
SetInsertionPoint(0); SetInsertionPoint(0);
} }
Refresh();
} }
wxString wxTextCtrl::GetValue() const wxString wxTextCtrl::GetValue() const
@@ -120,15 +127,38 @@ void wxTextCtrl::Clear()
SetValue(_T("")); SetValue(_T(""));
} }
void wxTextCtrl::Replace(long from, long to, const wxString& value) void wxTextCtrl::Replace(long from, long to, const wxString& text)
{ {
wxFAIL_MSG(_T("not implemented")); wxCHECK_RET( from >= 0 && to >= 0 && from <= to,
_T("invalid range in wxTextCtrl::Replace") );
// replace the part of the text with the new value
wxString valueNew(m_value, (size_t)from);
valueNew += text;
if ( (unsigned long)to < m_value.length() )
{
valueNew += m_value.c_str() + (size_t)to;
}
m_value = valueNew;
// update current position // update current position
SetInsertionPoint(from + text.length());
// FIXME shouldn't refresh everything of course
Refresh();
} }
void wxTextCtrl::Remove(long from, long to) void wxTextCtrl::Remove(long from, long to)
{ {
if ( from > to )
{
// Replace() only works with correctly ordered arguments, so exchange
// them
long tmp = from;
from = to;
to = tmp;
}
Replace(from, to, _T("")); Replace(from, to, _T(""));
} }
@@ -148,13 +178,29 @@ void wxTextCtrl::AppendText(const wxString& text)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void wxTextCtrl::SetInsertionPoint(long pos) void wxTextCtrl::SetInsertionPoint(long pos)
{
wxCHECK_RET( pos >= 0 && pos <= GetLastPosition(),
_T("insertion poitn position out of range") );
if ( pos != m_curPos )
{ {
HideCaret(); HideCaret();
m_curPos = pos; m_curPos = pos;
if ( IsSingleLine() )
{
m_curLine = 0;
m_curRow = m_curPos;
}
else // multi line
{
wxFAIL_MSG(_T("unimplemented for multi line"));
}
ShowCaret(); ShowCaret();
} }
}
void wxTextCtrl::SetInsertionPointEnd() void wxTextCtrl::SetInsertionPointEnd()
{ {
@@ -322,6 +368,82 @@ void wxTextCtrl::ShowPosition(long pos)
wxFAIL_MSG(_T("not implemented")); wxFAIL_MSG(_T("not implemented"));
} }
// ----------------------------------------------------------------------------
// word stuff
// ----------------------------------------------------------------------------
/*
TODO: we could have (easy to do) vi-like options for word movement, i.e.
distinguish between inlusive/exclusive words and between words and
WORDS (in vim sense) and also, finally, make the set of characters
which make up a word configurable - currently we use the exclusive
WORDS only (coincidentally, this is what Windows edit control does)
For future references, here is what vim help says:
A word consists of a sequence of letters, digits and underscores, or
a sequence of other non-blank characters, separated with white space
(spaces, tabs, <EOL>). This can be changed with the 'iskeyword'
option.
A WORD consists of a sequence of non-blank characters, separated with
white space. An empty line is also considered to be a word and a
WORD.
*/
static inline bool IsWordChar(wxChar ch)
{
return !wxIsspace(ch);
}
long wxTextCtrl::GetWordStart() const
{
if ( m_curPos == -1 || m_curPos == 0 )
return 0;
// start at the previous position
const wxChar *p0 = m_value.c_str();
const wxChar *p = p0 + m_curPos - 1;
// find the end of the previous word
while ( (p > p0) && !IsWordChar(*p) )
p--;
// now find the beginning of this word
while ( (p > p0) && IsWordChar(*p) )
p--;
// we might have gone too far
if ( !IsWordChar(*p) )
p++;
return p - p0;
}
long wxTextCtrl::GetWordEnd() const
{
if ( m_curPos == -1 )
return 0;
// start at the current position
const wxChar *p0 = m_value.c_str();
const wxChar *p = p0 + m_curPos;
// find the start of the next word
while ( *p && !IsWordChar(*p) )
p++;
// now find the end of it
while ( *p && IsWordChar(*p) )
p++;
// and find the start of the next word
while ( *p && !IsWordChar(*p) )
p++;
return p - p0;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// clipboard stuff // clipboard stuff
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -381,6 +503,7 @@ wxSize wxTextCtrl::DoGetBestClientSize() const
h = hChar; h = hChar;
w += 2*wChar; w += 2*wChar;
h += hChar / 2;
return wxSize(w, h); return wxSize(w, h);
} }
@@ -394,7 +517,7 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
if ( IsSingleLine() ) if ( IsSingleLine() )
{ {
// just redraw everything // just redraw everything
renderer->GetDC().DrawText(m_value, 0, 0); renderer->DrawTextLine(m_value);
} }
else else
{ {
@@ -416,7 +539,8 @@ void wxTextCtrl::ShowCaret(bool show)
wxCoord x; wxCoord x;
GetTextExtent(textBeforeCaret, &x, NULL); GetTextExtent(textBeforeCaret, &x, NULL);
caret->Move(x + 1, 0); // FIXME: use renderer
caret->Move(x + 3, 3);
} }
} }
} }
@@ -430,11 +554,194 @@ wxString wxTextCtrl::GetInputHandlerType() const
return wxINP_HANDLER_TEXTCTRL; return wxINP_HANDLER_TEXTCTRL;
} }
bool wxTextCtrl::PerformAction(const wxControlAction& action, bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig,
long numArg, long numArg,
const wxString& strArg) const wxString& strArg)
{
bool textChanged = FALSE;
wxString action;
bool del = FALSE;
if ( actionOrig.StartsWith(wxACTION_TEXT_PREFIX_DEL, &action) )
{
del = TRUE;
}
else // not selection nor delete action
{
action = actionOrig;
}
long newPos = -1;
if ( action == wxACTION_TEXT_HOME )
{
newPos = m_curPos - m_curRow;
}
else if ( action == wxACTION_TEXT_END )
{
newPos = m_curPos + GetLineLength(m_curLine) - m_curRow;
}
else if ( action == wxACTION_TEXT_LEFT )
{
newPos = m_curPos - 1;
}
else if ( action == wxACTION_TEXT_WORD_LEFT )
{
newPos = GetWordStart();
}
else if ( action == wxACTION_TEXT_RIGHT )
{
newPos = m_curPos + 1;
}
else if ( action == wxACTION_TEXT_WORD_RIGHT )
{
newPos = GetWordEnd();
}
else if ( action == wxACTION_TEXT_INSERT )
{
if ( !strArg.empty() )
{
WriteText(strArg);
textChanged = TRUE;
}
}
else
{ {
return wxControl::PerformAction(action, numArg, strArg); return wxControl::PerformAction(action, numArg, strArg);
} }
if ( newPos != -1 )
{
// bring the new position into the range
if ( newPos < 0 )
newPos = 0;
long posLast = GetLastPosition();
if ( newPos > posLast )
newPos = posLast;
if ( del )
{
// delete everything between current opsition and the new one
if ( m_curPos != newPos )
{
Remove(m_curPos, newPos);
textChanged = TRUE;
}
}
else
{
// just go there
SetInsertionPoint(newPos);
}
}
if ( textChanged )
{
wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
InitCommandEvent(event);
event.SetString(GetValue());
GetEventHandler()->ProcessEvent(event);
}
return TRUE;
}
void wxTextCtrl::OnChar(wxKeyEvent& event)
{
// only process the key events from "simple keys" here
if ( !event.HasModifiers() )
{
int keycode = event.GetKeyCode();
if ( keycode != WXK_DELETE && keycode != WXK_BACK )
{
PerformAction(wxACTION_TEXT_INSERT, -1, (wxChar)keycode);
// skip event.Skip() below
return;
}
}
event.Skip();
}
// ----------------------------------------------------------------------------
// wxStdTextCtrlInputHandler
// ----------------------------------------------------------------------------
wxStdTextCtrlInputHandler::wxStdTextCtrlInputHandler(wxInputHandler *inphand)
: wxStdInputHandler(inphand)
{
}
bool wxStdTextCtrlInputHandler::HandleKey(wxControl *control,
const wxKeyEvent& event,
bool pressed)
{
if ( !pressed )
return FALSE;
wxControlAction action;
wxString str;
bool ctrlDown = event.ControlDown();
if ( event.ShiftDown() )
{
action = wxACTION_TEXT_PREFIX_SEL;
}
int keycode = event.GetKeyCode();
switch ( keycode )
{
// cursor movement
case WXK_HOME:
action << wxACTION_TEXT_HOME;
break;
case WXK_END:
action << wxACTION_TEXT_END;
break;
case WXK_LEFT:
action << (ctrlDown ? wxACTION_TEXT_WORD_LEFT
: wxACTION_TEXT_LEFT);
break;
case WXK_RIGHT:
action << (ctrlDown ? wxACTION_TEXT_WORD_RIGHT
: wxACTION_TEXT_RIGHT);
break;
// delete
case WXK_DELETE:
action << wxACTION_TEXT_PREFIX_DEL << wxACTION_TEXT_RIGHT;
break;
case WXK_BACK:
action << wxACTION_TEXT_PREFIX_DEL << wxACTION_TEXT_LEFT;
break;
}
if ( !!action )
{
control->PerformAction(action, -1, str);
return TRUE;
}
return wxStdInputHandler::HandleKey(control, event, pressed);
}
bool wxStdTextCtrlInputHandler::HandleMouse(wxControl *control,
const wxMouseEvent& event)
{
return wxStdInputHandler::HandleMouse(control, event);
}
bool wxStdTextCtrlInputHandler::HandleMouseMove(wxControl *control,
const wxMouseEvent& event)
{
return wxStdInputHandler::HandleMouseMove(control, event);
}
#endif // wxUSE_TEXTCTRL #endif // wxUSE_TEXTCTRL

View File

@@ -72,6 +72,10 @@ public:
int alignment = wxALIGN_LEFT | wxALIGN_TOP, int alignment = wxALIGN_LEFT | wxALIGN_TOP,
int indexAccel = -1, int indexAccel = -1,
wxRect *rectBounds = NULL); wxRect *rectBounds = NULL);
virtual void DrawTextLine(wxDC& dc,
const wxString& text,
const wxRect &rect,
int flags = 0);
virtual void DrawBorder(wxDC& dc, virtual void DrawBorder(wxDC& dc,
wxBorder border, wxBorder border,
const wxRect& rect, const wxRect& rect,
@@ -440,6 +444,8 @@ wxInputHandler *wxGTKTheme::GetInputHandler(const wxString& control)
handler = new wxStdListboxInputHandler(GetDefaultInputHandler()); handler = new wxStdListboxInputHandler(GetDefaultInputHandler());
else if ( control == wxINP_HANDLER_CHECKLISTBOX ) else if ( control == wxINP_HANDLER_CHECKLISTBOX )
handler = new wxStdCheckListboxInputHandler(GetDefaultInputHandler()); handler = new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
else if ( control == wxINP_HANDLER_TEXTCTRL )
handler = new wxStdTextCtrlInputHandler(GetDefaultInputHandler());
else else
handler = GetDefaultInputHandler(); handler = GetDefaultInputHandler();
@@ -905,6 +911,14 @@ void wxGTKRenderer::DrawButtonLabel(wxDC& dc,
dc.DrawLabel(label, image, rect, alignment, indexAccel, rectBounds); dc.DrawLabel(label, image, rect, alignment, indexAccel, rectBounds);
} }
void wxGTKRenderer::DrawTextLine(wxDC& dc,
const wxString& text,
const wxRect &rect,
int flags)
{
dc.DrawText(text, rect.x, rect.y);
}
void wxGTKRenderer::DrawItem(wxDC& dc, void wxGTKRenderer::DrawItem(wxDC& dc,
const wxString& label, const wxString& label,
const wxRect& rect, const wxRect& rect,

View File

@@ -89,6 +89,10 @@ public:
int alignment = wxALIGN_LEFT | wxALIGN_TOP, int alignment = wxALIGN_LEFT | wxALIGN_TOP,
int indexAccel = -1, int indexAccel = -1,
wxRect *rectBounds = NULL); wxRect *rectBounds = NULL);
virtual void DrawTextLine(wxDC& dc,
const wxString& text,
const wxRect &rect,
int flags = 0);
virtual void DrawBorder(wxDC& dc, virtual void DrawBorder(wxDC& dc,
wxBorder border, wxBorder border,
const wxRect& rect, const wxRect& rect,
@@ -160,7 +164,7 @@ public:
int thumbPos = -1); int thumbPos = -1);
virtual int PixelToScrollbar(const wxScrollBar *scrollbar, wxCoord coord); virtual int PixelToScrollbar(const wxScrollBar *scrollbar, wxCoord coord);
virtual wxCoord GetListboxItemHeight(wxCoord fontHeight) virtual wxCoord GetListboxItemHeight(wxCoord fontHeight)
{ return fontHeight; } { return fontHeight + 2; }
virtual wxSize GetCheckBitmapSize() const virtual wxSize GetCheckBitmapSize() const
{ return wxSize(13, 13); } { return wxSize(13, 13); }
virtual wxSize GetRadioBitmapSize() const virtual wxSize GetRadioBitmapSize() const
@@ -650,6 +654,8 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control)
handler = new wxStdListboxInputHandler(GetDefaultInputHandler()); handler = new wxStdListboxInputHandler(GetDefaultInputHandler());
else if ( control == wxINP_HANDLER_CHECKLISTBOX ) else if ( control == wxINP_HANDLER_CHECKLISTBOX )
handler = new wxStdCheckListboxInputHandler(GetDefaultInputHandler()); handler = new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
else if ( control == wxINP_HANDLER_TEXTCTRL )
handler = new wxStdTextCtrlInputHandler(GetDefaultInputHandler());
else else
handler = GetDefaultInputHandler(); handler = GetDefaultInputHandler();
@@ -1385,6 +1391,14 @@ void wxWin32Renderer::DrawButtonLabel(wxDC& dc,
} }
} }
void wxWin32Renderer::DrawTextLine(wxDC& dc,
const wxString& text,
const wxRect &rect,
int flags)
{
dc.DrawText(text, rect.x + 2, rect.y + 1);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// (check)listbox items // (check)listbox items
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1439,7 +1453,7 @@ void wxWin32Renderer::DrawCheckItem(wxDC& dc,
: unchecked_item_xpm); : unchecked_item_xpm);
} }
dc.DrawBitmap(bmp, rect.x, rect.y + (rect.height - bmp.GetHeight()) / 2, dc.DrawBitmap(bmp, rect.x, rect.y + (rect.height - bmp.GetHeight()) / 2 - 1,
TRUE /* use mask */); TRUE /* use mask */);
wxRect rectLabel = rect; wxRect rectLabel = rect;