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:
Vadim Zeitlin
2001-05-27 03:28:28 +00:00
parent 1341230e80
commit 4bc1afd502
7 changed files with 216 additions and 21 deletions

View File

@@ -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.

View File

@@ -15,6 +15,7 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// headers // headers
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifdef __GNUG__ #ifdef __GNUG__
#pragma interface "textctrlbase.h" #pragma interface "textctrlbase.h"
#endif #endif
@@ -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

View File

@@ -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",

View File

@@ -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 )

View File

@@ -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
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -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();

View File

@@ -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
#endif // rich/!rich
{
DWORD dwStart, dwEnd; DWORD dwStart, dwEnd;
WPARAM wParam = (WPARAM) (DWORD*) & dwStart; // receives starting position WPARAM wParam = (WPARAM) &dwStart; // receives starting position
LPARAM lParam = (LPARAM) (DWORD*) & dwEnd; // receives ending 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