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 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
|
||||
// considering all its contents as a single strings) and (x, y) coordinates
|
||||
// which represent column and line.
|
||||
|
@@ -15,6 +15,7 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface "textctrlbase.h"
|
||||
#endif
|
||||
@@ -48,6 +49,40 @@ class WXDLLEXPORT wxTextCtrl;
|
||||
WXDLLEXPORT_DATA(extern const wxChar*) wxTextCtrlNameStr;
|
||||
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
|
||||
// edit text
|
||||
@@ -102,6 +137,13 @@ public:
|
||||
virtual void WriteText(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
|
||||
// considering all its contents as a single strings) and (x, y) coordinates
|
||||
// which represent column and line.
|
||||
@@ -161,6 +203,9 @@ protected:
|
||||
// SaveFile() by default
|
||||
wxString m_filename;
|
||||
|
||||
// the text style which will be used for any new text added to the control
|
||||
wxTextAttr m_defaultStyle;
|
||||
|
||||
private:
|
||||
#ifndef NO_TEXT_WINDOW_STREAM
|
||||
#if !wxUSE_IOSTREAMH
|
||||
|
@@ -253,13 +253,10 @@ MyFrame::MyFrame()
|
||||
wxMenu *fileMenu = new wxMenu;
|
||||
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,
|
||||
"Quit with &bitmap\tAlt-Q");
|
||||
itemBitmap->SetBitmap(wxBitmap(copy_xpm));
|
||||
fileMenu->Append(itemBitmap);
|
||||
#endif // __WXUNIVERSAL__
|
||||
|
||||
wxMenu *menubarMenu = new wxMenu;
|
||||
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",
|
||||
wxPoint(450, 10), wxSize(200, 230),
|
||||
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->SetBackgroundColour(*wxBLUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MyPanel::OnSize( wxSizeEvent &event )
|
||||
|
@@ -69,6 +69,31 @@ wxTextCtrlBase::~wxTextCtrlBase()
|
||||
#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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -273,7 +273,7 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
|
||||
#endif // __WIN32__
|
||||
|
||||
// if we're already attached to the menubar, we must update it
|
||||
if ( IsAttached() )
|
||||
if ( IsAttached() && m_menuBar->IsAttached() )
|
||||
{
|
||||
m_menuBar->Refresh();
|
||||
}
|
||||
@@ -326,7 +326,7 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
|
||||
wxLogLastError(wxT("RemoveMenu"));
|
||||
}
|
||||
|
||||
if ( IsAttached() )
|
||||
if ( IsAttached() && m_menuBar->IsAttached() )
|
||||
{
|
||||
// otherwise, the chane won't be visible
|
||||
m_menuBar->Refresh();
|
||||
|
@@ -126,7 +126,6 @@ BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
|
||||
#endif
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
// ============================================================================
|
||||
@@ -450,6 +449,17 @@ void wxTextCtrl::WriteText(const wxString& value)
|
||||
{
|
||||
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());
|
||||
|
||||
AdjustSpaceLimit();
|
||||
@@ -625,19 +635,20 @@ void wxTextCtrl::GetSelection(long* from, long* to) const
|
||||
|
||||
*from = charRange.cpMin;
|
||||
*to = charRange.cpMax;
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
#endif // rich/!rich
|
||||
{
|
||||
DWORD dwStart, dwEnd;
|
||||
WPARAM wParam = (WPARAM) (DWORD*) & dwStart; // receives starting position
|
||||
LPARAM lParam = (LPARAM) (DWORD*) & dwEnd; // receives ending position
|
||||
WPARAM wParam = (WPARAM) &dwStart; // receives starting position
|
||||
LPARAM lParam = (LPARAM) &dwEnd; // receives ending position
|
||||
|
||||
::SendMessage(GetHwnd(), EM_GETSEL, wParam, lParam);
|
||||
|
||||
*from = dwStart;
|
||||
*to = dwEnd;
|
||||
}
|
||||
}
|
||||
|
||||
bool wxTextCtrl::IsEditable() const
|
||||
{
|
||||
@@ -1151,12 +1162,13 @@ void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
|
||||
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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_RICHEDIT
|
||||
|
||||
// Watcom C++ doesn't define this
|
||||
#ifndef SCF_ALL
|
||||
#define SCF_ALL 0x0004
|
||||
@@ -1202,14 +1214,115 @@ bool wxTextCtrl::SetForegroundColour(const wxColour& colour)
|
||||
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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_RICHEDIT
|
||||
|
||||
bool wxRichEditModule::OnInit()
|
||||
{
|
||||
// don't do anything - we will load it when needed
|
||||
|
Reference in New Issue
Block a user