added text style support to wxTextCtrl for MSW
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10345 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -77,6 +77,12 @@ public:
|
|||||||
virtual void WriteText(const wxString& text);
|
virtual void WriteText(const wxString& text);
|
||||||
virtual void AppendText(const wxString& text);
|
virtual void AppendText(const wxString& text);
|
||||||
|
|
||||||
|
#if wxUSE_RICHEDIT
|
||||||
|
// apply text attribute to the range of text (only works with richedit
|
||||||
|
// controls)
|
||||||
|
virtual bool SetStyle(long start, long end, const wxTextAttr& style);
|
||||||
|
#endif // wxUSE_RICHEDIT
|
||||||
|
|
||||||
// translate between the position (which is just an index in the text ctrl
|
// translate between the position (which is just an index in the text ctrl
|
||||||
// considering all its contents as a single strings) and (x, y) coordinates
|
// considering all its contents as a single strings) and (x, y) coordinates
|
||||||
// which represent column and line.
|
// which represent column and line.
|
||||||
|
@@ -15,9 +15,10 @@
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// headers
|
// headers
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
#pragma interface "textctrlbase.h"
|
#pragma interface "textctrlbase.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/defs.h"
|
#include "wx/defs.h"
|
||||||
#include "wx/control.h" // the base class
|
#include "wx/control.h" // the base class
|
||||||
@@ -48,6 +49,40 @@ class WXDLLEXPORT wxTextCtrl;
|
|||||||
WXDLLEXPORT_DATA(extern const wxChar*) wxTextCtrlNameStr;
|
WXDLLEXPORT_DATA(extern const wxChar*) wxTextCtrlNameStr;
|
||||||
WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString;
|
WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxTextAttr: a structure containing the visual attributes of a text
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class WXDLLEXPORT wxTextAttr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// ctors
|
||||||
|
wxTextAttr() { }
|
||||||
|
wxTextAttr(const wxColour& colText,
|
||||||
|
const wxColour& colBack = wxNullColour,
|
||||||
|
const wxFont& font = wxNullFont)
|
||||||
|
: m_colText(colText), m_colBack(colBack), m_font(font) { }
|
||||||
|
|
||||||
|
// setters
|
||||||
|
void SetTextColour(const wxColour& colText) { m_colText = colText; }
|
||||||
|
void SetBackgroundColour(const wxColour& colBack) { m_colBack = colBack; }
|
||||||
|
void SetFont(const wxFont& font) { m_font = font; }
|
||||||
|
|
||||||
|
// accessors
|
||||||
|
bool HasTextColour() const { return m_colText.Ok(); }
|
||||||
|
bool HasBackgroundColour() const { return m_colBack.Ok(); }
|
||||||
|
bool HasFont() const { return m_font.Ok(); }
|
||||||
|
|
||||||
|
const wxColour& GetTextColour() const { return m_colText; }
|
||||||
|
const wxColour& GetBackgroundColour() const { return m_colBack; }
|
||||||
|
const wxFont& GetFont() const { return m_font; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxColour m_colText,
|
||||||
|
m_colBack;
|
||||||
|
wxFont m_font;
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxTextCtrl: a single or multiple line text zone where user can enter and
|
// wxTextCtrl: a single or multiple line text zone where user can enter and
|
||||||
// edit text
|
// edit text
|
||||||
@@ -102,6 +137,13 @@ public:
|
|||||||
virtual void WriteText(const wxString& text) = 0;
|
virtual void WriteText(const wxString& text) = 0;
|
||||||
virtual void AppendText(const wxString& text) = 0;
|
virtual void AppendText(const wxString& text) = 0;
|
||||||
|
|
||||||
|
// text control under some platforms supports the text styles: these
|
||||||
|
// methods allow to apply the given text style to the given selection or to
|
||||||
|
// set/get the style which will be used for all appended text
|
||||||
|
virtual bool SetStyle(long start, long end, const wxTextAttr& style);
|
||||||
|
virtual bool SetDefaultStyle(const wxTextAttr& style);
|
||||||
|
virtual const wxTextAttr& GetDefaultStyle() const;
|
||||||
|
|
||||||
// translate between the position (which is just an index in the text ctrl
|
// translate between the position (which is just an index in the text ctrl
|
||||||
// considering all its contents as a single strings) and (x, y) coordinates
|
// considering all its contents as a single strings) and (x, y) coordinates
|
||||||
// which represent column and line.
|
// which represent column and line.
|
||||||
@@ -161,6 +203,9 @@ protected:
|
|||||||
// SaveFile() by default
|
// SaveFile() by default
|
||||||
wxString m_filename;
|
wxString m_filename;
|
||||||
|
|
||||||
|
// the text style which will be used for any new text added to the control
|
||||||
|
wxTextAttr m_defaultStyle;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifndef NO_TEXT_WINDOW_STREAM
|
#ifndef NO_TEXT_WINDOW_STREAM
|
||||||
#if !wxUSE_IOSTREAMH
|
#if !wxUSE_IOSTREAMH
|
||||||
|
@@ -253,13 +253,10 @@ MyFrame::MyFrame()
|
|||||||
wxMenu *fileMenu = new wxMenu;
|
wxMenu *fileMenu = new wxMenu;
|
||||||
fileMenu->Append(Menu_File_Quit, "E&xit\tAlt-X", "Quit toolbar sample");
|
fileMenu->Append(Menu_File_Quit, "E&xit\tAlt-X", "Quit toolbar sample");
|
||||||
|
|
||||||
// not supported just yet
|
|
||||||
#ifndef __WXUNIVERSAL__
|
|
||||||
wxMenuItem *itemBitmap = new wxMenuItem(fileMenu, Menu_File_Quit,
|
wxMenuItem *itemBitmap = new wxMenuItem(fileMenu, Menu_File_Quit,
|
||||||
"Quit with &bitmap\tAlt-Q");
|
"Quit with &bitmap\tAlt-Q");
|
||||||
itemBitmap->SetBitmap(wxBitmap(copy_xpm));
|
itemBitmap->SetBitmap(wxBitmap(copy_xpm));
|
||||||
fileMenu->Append(itemBitmap);
|
fileMenu->Append(itemBitmap);
|
||||||
#endif // __WXUNIVERSAL__
|
|
||||||
|
|
||||||
wxMenu *menubarMenu = new wxMenu;
|
wxMenu *menubarMenu = new wxMenu;
|
||||||
menubarMenu->Append(Menu_MenuBar_Append, "&Append menu\tCtrl-A",
|
menubarMenu->Append(Menu_MenuBar_Append, "&Append menu\tCtrl-A",
|
||||||
|
@@ -645,8 +645,17 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
|
|||||||
"wxHSCROLL style",
|
"wxHSCROLL style",
|
||||||
wxPoint(450, 10), wxSize(200, 230),
|
wxPoint(450, 10), wxSize(200, 230),
|
||||||
wxTE_RICH | wxTE_MULTILINE | wxHSCROLL);
|
wxTE_RICH | wxTE_MULTILINE | wxHSCROLL);
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
m_textrich->SetStyle(0, 10, *wxRED);
|
||||||
|
m_textrich->SetStyle(10, 20, *wxBLUE);
|
||||||
|
m_textrich->SetStyle(30, 40,
|
||||||
|
wxTextAttr(*wxGREEN, wxNullColour, *wxITALIC_FONT));
|
||||||
|
m_textrich->SetDefaultStyle(*wxBLUE);
|
||||||
|
m_textrich->AppendText(_T("\nIs this text really in blue?"));
|
||||||
|
#else
|
||||||
m_textrich->SetForegroundColour(wxColour(0, 255, 255));
|
m_textrich->SetForegroundColour(wxColour(0, 255, 255));
|
||||||
m_textrich->SetBackgroundColour(*wxBLUE);
|
m_textrich->SetBackgroundColour(*wxBLUE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyPanel::OnSize( wxSizeEvent &event )
|
void MyPanel::OnSize( wxSizeEvent &event )
|
||||||
|
@@ -69,6 +69,31 @@ wxTextCtrlBase::~wxTextCtrlBase()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// style functions - not implemented here
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// apply styling to text range
|
||||||
|
bool wxTextCtrlBase::SetStyle(long WXUNUSED(start), long WXUNUSED(end),
|
||||||
|
const wxTextAttr& WXUNUSED(style))
|
||||||
|
{
|
||||||
|
// to be implemented in derived TextCtrl classes
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// change default text attributes
|
||||||
|
bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr &style)
|
||||||
|
{
|
||||||
|
m_defaultStyle = style;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get default text attributes
|
||||||
|
const wxTextAttr& wxTextCtrlBase::GetDefaultStyle() const
|
||||||
|
{
|
||||||
|
return m_defaultStyle;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// file IO functions
|
// file IO functions
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -273,7 +273,7 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
|
|||||||
#endif // __WIN32__
|
#endif // __WIN32__
|
||||||
|
|
||||||
// if we're already attached to the menubar, we must update it
|
// if we're already attached to the menubar, we must update it
|
||||||
if ( IsAttached() )
|
if ( IsAttached() && m_menuBar->IsAttached() )
|
||||||
{
|
{
|
||||||
m_menuBar->Refresh();
|
m_menuBar->Refresh();
|
||||||
}
|
}
|
||||||
@@ -326,7 +326,7 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
|
|||||||
wxLogLastError(wxT("RemoveMenu"));
|
wxLogLastError(wxT("RemoveMenu"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( IsAttached() )
|
if ( IsAttached() && m_menuBar->IsAttached() )
|
||||||
{
|
{
|
||||||
// otherwise, the chane won't be visible
|
// otherwise, the chane won't be visible
|
||||||
m_menuBar->Refresh();
|
m_menuBar->Refresh();
|
||||||
|
@@ -126,7 +126,6 @@ BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
|
|||||||
#endif
|
#endif
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -450,6 +449,17 @@ void wxTextCtrl::WriteText(const wxString& value)
|
|||||||
{
|
{
|
||||||
wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Dos);
|
wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Dos);
|
||||||
|
|
||||||
|
#if wxUSE_RICHEDIT
|
||||||
|
// ensure that the new text will be in the default style
|
||||||
|
if ( IsRich() &&
|
||||||
|
(m_defaultStyle.HasFont() || m_defaultStyle.HasTextColour()) )
|
||||||
|
{
|
||||||
|
long start, end;
|
||||||
|
GetSelection(&start, &end);
|
||||||
|
SetStyle(start, end, m_defaultStyle );
|
||||||
|
}
|
||||||
|
#endif // wxUSE_RICHEDIT
|
||||||
|
|
||||||
SendMessage(GetHwnd(), EM_REPLACESEL, 0, (LPARAM)valueDos.c_str());
|
SendMessage(GetHwnd(), EM_REPLACESEL, 0, (LPARAM)valueDos.c_str());
|
||||||
|
|
||||||
AdjustSpaceLimit();
|
AdjustSpaceLimit();
|
||||||
@@ -625,18 +635,19 @@ void wxTextCtrl::GetSelection(long* from, long* to) const
|
|||||||
|
|
||||||
*from = charRange.cpMin;
|
*from = charRange.cpMin;
|
||||||
*to = charRange.cpMax;
|
*to = charRange.cpMax;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
#endif
|
else
|
||||||
DWORD dwStart, dwEnd;
|
#endif // rich/!rich
|
||||||
WPARAM wParam = (WPARAM) (DWORD*) & dwStart; // receives starting position
|
{
|
||||||
LPARAM lParam = (LPARAM) (DWORD*) & dwEnd; // receives ending position
|
DWORD dwStart, dwEnd;
|
||||||
|
WPARAM wParam = (WPARAM) &dwStart; // receives starting position
|
||||||
|
LPARAM lParam = (LPARAM) &dwEnd; // receives ending position
|
||||||
|
|
||||||
::SendMessage(GetHwnd(), EM_GETSEL, wParam, lParam);
|
::SendMessage(GetHwnd(), EM_GETSEL, wParam, lParam);
|
||||||
|
|
||||||
*from = dwStart;
|
*from = dwStart;
|
||||||
*to = dwEnd;
|
*to = dwEnd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxTextCtrl::IsEditable() const
|
bool wxTextCtrl::IsEditable() const
|
||||||
@@ -1151,12 +1162,13 @@ void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
|
|||||||
event.Enable( CanRedo() );
|
event.Enable( CanRedo() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the rest of the file only deals with the rich edit controls
|
||||||
|
#if wxUSE_RICHEDIT
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// colour setting for the rich edit controls
|
// colour setting for the rich edit controls
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if wxUSE_RICHEDIT
|
|
||||||
|
|
||||||
// Watcom C++ doesn't define this
|
// Watcom C++ doesn't define this
|
||||||
#ifndef SCF_ALL
|
#ifndef SCF_ALL
|
||||||
#define SCF_ALL 0x0004
|
#define SCF_ALL 0x0004
|
||||||
@@ -1202,14 +1214,115 @@ bool wxTextCtrl::SetForegroundColour(const wxColour& colour)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_RICHEDIT
|
// ----------------------------------------------------------------------------
|
||||||
|
// styling support for rich edit controls
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
|
||||||
|
{
|
||||||
|
if ( !IsRich() )
|
||||||
|
{
|
||||||
|
// can't do it with normal text control
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the rich text control doesn't handle setting background colour, so don't
|
||||||
|
// even try if it's the only thing we want to change
|
||||||
|
if ( !style.HasFont() && !style.HasTextColour() )
|
||||||
|
{
|
||||||
|
// nothing to do: return TRUE if there was really nothing to doand
|
||||||
|
// FALSE fi we failed to set bg colour
|
||||||
|
return !style.HasBackgroundColour();
|
||||||
|
}
|
||||||
|
|
||||||
|
// order the range if needed
|
||||||
|
if ( start > end )
|
||||||
|
{
|
||||||
|
long tmp = start;
|
||||||
|
start = end;
|
||||||
|
end = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we can only change the format of the selection, so select the range we
|
||||||
|
// want and restore the old selection later
|
||||||
|
long startOld, endOld;
|
||||||
|
GetSelection(&startOld, &endOld);
|
||||||
|
|
||||||
|
// but do we really have to change the selection?
|
||||||
|
bool changeSel = start != startOld || end != endOld;
|
||||||
|
|
||||||
|
if ( changeSel )
|
||||||
|
SendMessage(GetHwnd(), EM_SETSEL, (WPARAM) start, (LPARAM) end);
|
||||||
|
|
||||||
|
// initialize CHARFORMAT struct
|
||||||
|
CHARFORMAT cf;
|
||||||
|
wxZeroMemory(cf);
|
||||||
|
cf.cbSize = sizeof(cf);
|
||||||
|
|
||||||
|
if ( style.HasFont() )
|
||||||
|
{
|
||||||
|
cf.dwMask |= CFM_FACE | CFM_SIZE | CFM_CHARSET;
|
||||||
|
|
||||||
|
// fill in data from LOGFONT but recalculate lfHeight because we need
|
||||||
|
// the real height in twips and not the negative number which
|
||||||
|
// wxFillLogFont() returns (this is correct in general and works with
|
||||||
|
// the Windows font mapper, but not here)
|
||||||
|
LOGFONT lf;
|
||||||
|
wxFillLogFont(&lf, &style.GetFont());
|
||||||
|
cf.yHeight = 20*style.GetFont().GetPointSize(); // 1 pt = 20 twips
|
||||||
|
cf.bCharSet = lf.lfCharSet;
|
||||||
|
cf.bPitchAndFamily = lf.lfPitchAndFamily;
|
||||||
|
wxStrncpy( cf.szFaceName, lf.lfFaceName, WXSIZEOF(cf.szFaceName) );
|
||||||
|
|
||||||
|
// also deal with underline/italic/bold attributes
|
||||||
|
if ( lf.lfItalic )
|
||||||
|
{
|
||||||
|
cf.dwMask |= CFM_ITALIC;
|
||||||
|
cf.dwEffects |= CFE_ITALIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( lf.lfWeight == FW_BOLD )
|
||||||
|
{
|
||||||
|
cf.dwMask |= CFM_BOLD;
|
||||||
|
cf.dwEffects |= CFE_BOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( lf.lfUnderline )
|
||||||
|
{
|
||||||
|
cf.dwMask |= CFM_UNDERLINE;
|
||||||
|
cf.dwEffects |= CFE_UNDERLINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// strikeout fonts are not supported by wxWindows
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( style.HasTextColour() )
|
||||||
|
{
|
||||||
|
cf.dwMask |= CFM_COLOR;
|
||||||
|
cf.crTextColor = wxColourToRGB(style.GetTextColour());
|
||||||
|
}
|
||||||
|
|
||||||
|
// do format the selection
|
||||||
|
bool ok = ::SendMessage(GetHwnd(), EM_SETCHARFORMAT,
|
||||||
|
SCF_SELECTION, (LPARAM)&cf) != 0;
|
||||||
|
if ( !ok )
|
||||||
|
{
|
||||||
|
wxLogDebug(_T("SendMessage(EM_SETCHARFORMAT, SCF_SELECTION) failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( changeSel )
|
||||||
|
{
|
||||||
|
// restore the original selection
|
||||||
|
SendMessage(GetHwnd(), EM_SETSEL, (WPARAM)startOld, (LPARAM)endOld);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxRichEditModule
|
// wxRichEditModule
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if wxUSE_RICHEDIT
|
|
||||||
|
|
||||||
bool wxRichEditModule::OnInit()
|
bool wxRichEditModule::OnInit()
|
||||||
{
|
{
|
||||||
// don't do anything - we will load it when needed
|
// don't do anything - we will load it when needed
|
||||||
|
Reference in New Issue
Block a user