implemented text styles for GTK+

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10610 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2001-06-18 17:41:33 +00:00
parent 58d5ad5e3c
commit 17665a2b5c
6 changed files with 325 additions and 82 deletions

View File

@ -79,6 +79,10 @@ public:
virtual void WriteText(const wxString& text);
virtual void AppendText(const wxString& text);
// apply text attribute to the range of text (only works with richedit
// controls)
virtual bool SetStyle(long start, long end, const wxTextAttr& style);
// 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.
@ -130,8 +134,9 @@ public:
void OnUpdateUndo(wxUpdateUIEvent& event);
void OnUpdateRedo(wxUpdateUIEvent& event);
bool SetFont( const wxFont &font );
bool SetBackgroundColour(const wxColour &colour);
bool SetFont(const wxFont& font);
bool SetForegroundColour(const wxColour& colour);
bool SetBackgroundColour(const wxColour& colour);
GtkWidget* GetConnectWidget();
bool IsOwnGtkWindow( GdkWindow *window );

View File

@ -79,6 +79,10 @@ public:
virtual void WriteText(const wxString& text);
virtual void AppendText(const wxString& text);
// apply text attribute to the range of text (only works with richedit
// controls)
virtual bool SetStyle(long start, long end, const wxTextAttr& style);
// 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.
@ -130,8 +134,9 @@ public:
void OnUpdateUndo(wxUpdateUIEvent& event);
void OnUpdateRedo(wxUpdateUIEvent& event);
bool SetFont( const wxFont &font );
bool SetBackgroundColour(const wxColour &colour);
bool SetFont(const wxFont& font);
bool SetForegroundColour(const wxColour& colour);
bool SetBackgroundColour(const wxColour& colour);
GtkWidget* GetConnectWidget();
bool IsOwnGtkWindow( GdkWindow *window );

View File

@ -80,10 +80,17 @@ public:
bool HasBackgroundColour() const { return m_colBack.Ok(); }
bool HasFont() const { return m_font.Ok(); }
// setters
const wxColour& GetTextColour() const { return m_colText; }
const wxColour& GetBackgroundColour() const { return m_colBack; }
const wxFont& GetFont() const { return m_font; }
// returns false if we have any attributes set, true otherwise
bool IsDefault() const
{
return !HasTextColour() && !HasBackgroundColour() && !HasFont();
}
private:
wxColour m_colText,
m_colBack;

View File

@ -186,7 +186,7 @@ bool MyApp::OnInit()
{
// Create the main frame window
MyFrame *frame = new MyFrame((wxFrame *) NULL,
"Text wxWindows sample", 50, 50, 660, 420);
"Text wxWindows sample", 50, 50, 700, 420);
frame->SetSizeHints( 500, 400 );
wxMenu *file_menu = new wxMenu;
@ -643,19 +643,23 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
"and a very very very very very "
"very very very long line to test"
"wxHSCROLL style",
wxPoint(450, 10), wxSize(200, 230),
wxPoint(450, 10), wxSize(230, 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(wxTextAttr());
m_textrich->AppendText(_T("\n\nFirst 10 characters should be in red\n"));
m_textrich->AppendText(_T("Next 10 characters should be in blue\n"));
m_textrich->AppendText(_T("Next 10 characters should be normal\n"));
m_textrich->AppendText(_T("And the next 10 characters should be green and italic\n"));
m_textrich->SetDefaultStyle(wxTextAttr(*wxCYAN, *wxBLUE));
m_textrich->AppendText(_T("This text should be cyan on blue\n"));
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
m_textrich->AppendText(_T("And this should be in blue and the text you ")
_T("type should be in blue as well"));
}
void MyPanel::OnSize( wxSizeEvent &event )

View File

@ -396,10 +396,18 @@ bool wxTextCtrl::Create( wxWindow *parent,
/* we don't set a valid background colour, because the window
manager should use a default one */
m_backgroundColour = wxColour();
SetForegroundColour( parent->GetForegroundColour() );
wxColour colFg = parent->GetForegroundColour();
SetForegroundColour( colFg );
m_cursor = wxCursor( wxCURSOR_IBEAM );
// FIXME: is the bg colour correct here?
wxTextAttr attrDef( colFg,
wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW),
parent->GetFont() );
SetDefaultStyle( attrDef );
Show( TRUE );
return TRUE;
@ -481,33 +489,53 @@ void wxTextCtrl::WriteText( const wxString &text )
{
wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
if (text.IsEmpty()) return;
if ( text.empty() )
return;
if (m_windowStyle & wxTE_MULTILINE)
#if wxUSE_UNICODE
wxWX2MBbuf buf = text.mbc_str();
const char *txt = buf;
size_t txtlen = strlen(buf);
#else
const char *txt = text;
size_t txtlen = text.length();
#endif
if ( m_windowStyle & wxTE_MULTILINE )
{
/* this moves the cursor pos to behind the inserted text */
gint len = GTK_EDITABLE(m_text)->current_pos;
#if wxUSE_UNICODE
wxWX2MBbuf buf = text.mbc_str();
gtk_editable_insert_text( GTK_EDITABLE(m_text), buf, strlen(buf), &len );
#else
gtk_editable_insert_text( GTK_EDITABLE(m_text), text, text.Length(), &len );
#endif
// if we have any special style, use it
if ( !m_defaultStyle.IsDefault() )
{
GdkFont *font = m_defaultStyle.HasFont()
? m_defaultStyle.GetFont().GetInternalFont()
: NULL;
GdkColor *colFg = m_defaultStyle.HasTextColour()
? m_defaultStyle.GetTextColour().GetColor()
: NULL;
GdkColor *colBg = m_defaultStyle.HasBackgroundColour()
? m_defaultStyle.GetBackgroundColour().GetColor()
: NULL;
gtk_text_insert( GTK_TEXT(m_text), font, colFg, colBg, txt, txtlen );
}
else // no style
{
gtk_editable_insert_text( GTK_EDITABLE(m_text), txt, txtlen, &len );
}
/* bring editable's cursor uptodate. bug in GTK. */
GTK_EDITABLE(m_text)->current_pos = gtk_text_get_point( GTK_TEXT(m_text) );
}
else
else // single line
{
/* this moves the cursor pos to behind the inserted text */
gint len = GTK_EDITABLE(m_text)->current_pos;
#if wxUSE_UNICODE
wxWX2MBbuf buf = text.mbc_str();
gtk_editable_insert_text( GTK_EDITABLE(m_text), buf, strlen(buf), &len );
#else
gtk_editable_insert_text( GTK_EDITABLE(m_text), text, text.Length(), &len );
#endif
gtk_editable_insert_text( GTK_EDITABLE(m_text), txt, txtlen, &len );
/* bring editable's cursor uptodate. bug in GTK. */
GTK_EDITABLE(m_text)->current_pos += text.Len();
@ -521,40 +549,49 @@ void wxTextCtrl::AppendText( const wxString &text )
{
wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
if (text.IsEmpty()) return;
if ( text.empty() )
return;
#if wxUSE_UNICODE
wxWX2MBbuf buf = text.mbc_str();
const char *txt = buf;
size_t txtlen = strlen(buf);
#else
const char *txt = text;
size_t txtlen = text.length();
#endif
if (m_windowStyle & wxTE_MULTILINE)
{
bool hasSpecialAttributes = m_font.Ok() ||
m_foregroundColour.Ok();
if ( hasSpecialAttributes )
if ( !m_defaultStyle.IsDefault() )
{
gtk_text_insert( GTK_TEXT(m_text),
m_font.GetInternalFont(),
m_foregroundColour.GetColor(),
m_backgroundColour.Ok() ?
m_backgroundColour.GetColor(): NULL,
text.mbc_str(), text.length());
GdkFont *font = m_defaultStyle.HasFont()
? m_defaultStyle.GetFont().GetInternalFont()
: NULL;
GdkColor *colFg = m_defaultStyle.HasTextColour()
? m_defaultStyle.GetTextColour().GetColor()
: NULL;
GdkColor *colBg = m_defaultStyle.HasBackgroundColour()
? m_defaultStyle.GetBackgroundColour().GetColor()
: NULL;
gtk_text_insert( GTK_TEXT(m_text), font, colFg, colBg, txt, txtlen );
}
else
else // no style
{
/* we'll insert at the last position */
gint len = gtk_text_get_length( GTK_TEXT(m_text) );
#if wxUSE_UNICODE
wxWX2MBbuf buf = text.mbc_str();
gtk_editable_insert_text( GTK_EDITABLE(m_text), buf, strlen(buf), &len );
#else
gtk_editable_insert_text( GTK_EDITABLE(m_text), text, text.Length(), &len );
#endif
gtk_editable_insert_text( GTK_EDITABLE(m_text), txt, txtlen, &len );
}
/* bring editable's cursor uptodate. bug in GTK. */
GTK_EDITABLE(m_text)->current_pos = gtk_text_get_point( GTK_TEXT(m_text) );
}
else
else // single line
{
gtk_entry_append_text( GTK_ENTRY(m_text), text.mbc_str() );
gtk_entry_append_text( GTK_ENTRY(m_text), txt );
}
}
@ -1072,6 +1109,17 @@ void wxTextCtrl::UpdateFontIfNeeded()
ChangeFontGlobally();
}
bool wxTextCtrl::SetForegroundColour(const wxColour& colour)
{
if ( !wxControl::SetForegroundColour(colour) )
return FALSE;
// update default fg colour too
m_defaultStyle.SetTextColour(colour);
return TRUE;
}
bool wxTextCtrl::SetBackgroundColour( const wxColour &colour )
{
wxCHECK_MSG( m_text != NULL, FALSE, wxT("invalid text ctrl") );
@ -1102,9 +1150,72 @@ bool wxTextCtrl::SetBackgroundColour( const wxColour &colour )
gdk_window_clear( window );
}
// change active background color too
m_defaultStyle.SetBackgroundColour( colour );
return TRUE;
}
bool wxTextCtrl::SetStyle( long start, long end, const wxTextAttr &style )
{
/* VERY dirty way to do that - removes the required text and re-adds it
with styling (FIXME) */
if ( m_windowStyle & wxTE_MULTILINE )
{
if ( style.IsDefault() )
{
// nothing to do
return TRUE;
}
gint l = gtk_text_get_length( GTK_TEXT(m_text) );
wxCHECK_MSG( start >= 0 && end <= l, FALSE,
_T("invalid range in wxTextCtrl::SetStyle") );
gint old_pos = gtk_editable_get_position( GTK_EDITABLE(m_text) );
char *text = gtk_editable_get_chars( GTK_EDITABLE(m_text), start, end );
wxString tmp(text,*wxConvCurrent);
g_free( text );
gtk_editable_delete_text( GTK_EDITABLE(m_text), start, end );
gtk_editable_set_position( GTK_EDITABLE(m_text), start );
#if wxUSE_UNICODE
wxWX2MBbuf buf = tmp.mbc_str();
const char *txt = buf;
size_t txtlen = strlen(buf);
#else
const char *txt = tmp;
size_t txtlen = tmp.length();
#endif
GdkFont *font = style.HasFont()
? style.GetFont().GetInternalFont()
: NULL;
GdkColor *colFg = style.HasTextColour()
? style.GetTextColour().GetColor()
: NULL;
GdkColor *colBg = style.HasBackgroundColour()
? style.GetBackgroundColour().GetColor()
: NULL;
gtk_text_insert( GTK_TEXT(m_text), font, colFg, colBg, txt, txtlen );
/* does not seem to help under GTK+ 1.2 !!!
gtk_editable_set_position( GTK_EDITABLE(m_text), old_pos ); */
SetInsertionPoint( old_pos );
return TRUE;
}
else // singe line
{
// cannot do this for GTK+'s Entry widget
return FALSE;
}
}
void wxTextCtrl::ApplyWidgetStyle()
{
if (m_windowStyle & wxTE_MULTILINE)

View File

@ -396,10 +396,18 @@ bool wxTextCtrl::Create( wxWindow *parent,
/* we don't set a valid background colour, because the window
manager should use a default one */
m_backgroundColour = wxColour();
SetForegroundColour( parent->GetForegroundColour() );
wxColour colFg = parent->GetForegroundColour();
SetForegroundColour( colFg );
m_cursor = wxCursor( wxCURSOR_IBEAM );
// FIXME: is the bg colour correct here?
wxTextAttr attrDef( colFg,
wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW),
parent->GetFont() );
SetDefaultStyle( attrDef );
Show( TRUE );
return TRUE;
@ -481,33 +489,53 @@ void wxTextCtrl::WriteText( const wxString &text )
{
wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
if (text.IsEmpty()) return;
if ( text.empty() )
return;
if (m_windowStyle & wxTE_MULTILINE)
#if wxUSE_UNICODE
wxWX2MBbuf buf = text.mbc_str();
const char *txt = buf;
size_t txtlen = strlen(buf);
#else
const char *txt = text;
size_t txtlen = text.length();
#endif
if ( m_windowStyle & wxTE_MULTILINE )
{
/* this moves the cursor pos to behind the inserted text */
gint len = GTK_EDITABLE(m_text)->current_pos;
#if wxUSE_UNICODE
wxWX2MBbuf buf = text.mbc_str();
gtk_editable_insert_text( GTK_EDITABLE(m_text), buf, strlen(buf), &len );
#else
gtk_editable_insert_text( GTK_EDITABLE(m_text), text, text.Length(), &len );
#endif
// if we have any special style, use it
if ( !m_defaultStyle.IsDefault() )
{
GdkFont *font = m_defaultStyle.HasFont()
? m_defaultStyle.GetFont().GetInternalFont()
: NULL;
GdkColor *colFg = m_defaultStyle.HasTextColour()
? m_defaultStyle.GetTextColour().GetColor()
: NULL;
GdkColor *colBg = m_defaultStyle.HasBackgroundColour()
? m_defaultStyle.GetBackgroundColour().GetColor()
: NULL;
gtk_text_insert( GTK_TEXT(m_text), font, colFg, colBg, txt, txtlen );
}
else // no style
{
gtk_editable_insert_text( GTK_EDITABLE(m_text), txt, txtlen, &len );
}
/* bring editable's cursor uptodate. bug in GTK. */
GTK_EDITABLE(m_text)->current_pos = gtk_text_get_point( GTK_TEXT(m_text) );
}
else
else // single line
{
/* this moves the cursor pos to behind the inserted text */
gint len = GTK_EDITABLE(m_text)->current_pos;
#if wxUSE_UNICODE
wxWX2MBbuf buf = text.mbc_str();
gtk_editable_insert_text( GTK_EDITABLE(m_text), buf, strlen(buf), &len );
#else
gtk_editable_insert_text( GTK_EDITABLE(m_text), text, text.Length(), &len );
#endif
gtk_editable_insert_text( GTK_EDITABLE(m_text), txt, txtlen, &len );
/* bring editable's cursor uptodate. bug in GTK. */
GTK_EDITABLE(m_text)->current_pos += text.Len();
@ -521,40 +549,49 @@ void wxTextCtrl::AppendText( const wxString &text )
{
wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
if (text.IsEmpty()) return;
if ( text.empty() )
return;
#if wxUSE_UNICODE
wxWX2MBbuf buf = text.mbc_str();
const char *txt = buf;
size_t txtlen = strlen(buf);
#else
const char *txt = text;
size_t txtlen = text.length();
#endif
if (m_windowStyle & wxTE_MULTILINE)
{
bool hasSpecialAttributes = m_font.Ok() ||
m_foregroundColour.Ok();
if ( hasSpecialAttributes )
if ( !m_defaultStyle.IsDefault() )
{
gtk_text_insert( GTK_TEXT(m_text),
m_font.GetInternalFont(),
m_foregroundColour.GetColor(),
m_backgroundColour.Ok() ?
m_backgroundColour.GetColor(): NULL,
text.mbc_str(), text.length());
GdkFont *font = m_defaultStyle.HasFont()
? m_defaultStyle.GetFont().GetInternalFont()
: NULL;
GdkColor *colFg = m_defaultStyle.HasTextColour()
? m_defaultStyle.GetTextColour().GetColor()
: NULL;
GdkColor *colBg = m_defaultStyle.HasBackgroundColour()
? m_defaultStyle.GetBackgroundColour().GetColor()
: NULL;
gtk_text_insert( GTK_TEXT(m_text), font, colFg, colBg, txt, txtlen );
}
else
else // no style
{
/* we'll insert at the last position */
gint len = gtk_text_get_length( GTK_TEXT(m_text) );
#if wxUSE_UNICODE
wxWX2MBbuf buf = text.mbc_str();
gtk_editable_insert_text( GTK_EDITABLE(m_text), buf, strlen(buf), &len );
#else
gtk_editable_insert_text( GTK_EDITABLE(m_text), text, text.Length(), &len );
#endif
gtk_editable_insert_text( GTK_EDITABLE(m_text), txt, txtlen, &len );
}
/* bring editable's cursor uptodate. bug in GTK. */
GTK_EDITABLE(m_text)->current_pos = gtk_text_get_point( GTK_TEXT(m_text) );
}
else
else // single line
{
gtk_entry_append_text( GTK_ENTRY(m_text), text.mbc_str() );
gtk_entry_append_text( GTK_ENTRY(m_text), txt );
}
}
@ -1072,6 +1109,17 @@ void wxTextCtrl::UpdateFontIfNeeded()
ChangeFontGlobally();
}
bool wxTextCtrl::SetForegroundColour(const wxColour& colour)
{
if ( !wxControl::SetForegroundColour(colour) )
return FALSE;
// update default fg colour too
m_defaultStyle.SetTextColour(colour);
return TRUE;
}
bool wxTextCtrl::SetBackgroundColour( const wxColour &colour )
{
wxCHECK_MSG( m_text != NULL, FALSE, wxT("invalid text ctrl") );
@ -1102,9 +1150,72 @@ bool wxTextCtrl::SetBackgroundColour( const wxColour &colour )
gdk_window_clear( window );
}
// change active background color too
m_defaultStyle.SetBackgroundColour( colour );
return TRUE;
}
bool wxTextCtrl::SetStyle( long start, long end, const wxTextAttr &style )
{
/* VERY dirty way to do that - removes the required text and re-adds it
with styling (FIXME) */
if ( m_windowStyle & wxTE_MULTILINE )
{
if ( style.IsDefault() )
{
// nothing to do
return TRUE;
}
gint l = gtk_text_get_length( GTK_TEXT(m_text) );
wxCHECK_MSG( start >= 0 && end <= l, FALSE,
_T("invalid range in wxTextCtrl::SetStyle") );
gint old_pos = gtk_editable_get_position( GTK_EDITABLE(m_text) );
char *text = gtk_editable_get_chars( GTK_EDITABLE(m_text), start, end );
wxString tmp(text,*wxConvCurrent);
g_free( text );
gtk_editable_delete_text( GTK_EDITABLE(m_text), start, end );
gtk_editable_set_position( GTK_EDITABLE(m_text), start );
#if wxUSE_UNICODE
wxWX2MBbuf buf = tmp.mbc_str();
const char *txt = buf;
size_t txtlen = strlen(buf);
#else
const char *txt = tmp;
size_t txtlen = tmp.length();
#endif
GdkFont *font = style.HasFont()
? style.GetFont().GetInternalFont()
: NULL;
GdkColor *colFg = style.HasTextColour()
? style.GetTextColour().GetColor()
: NULL;
GdkColor *colBg = style.HasBackgroundColour()
? style.GetBackgroundColour().GetColor()
: NULL;
gtk_text_insert( GTK_TEXT(m_text), font, colFg, colBg, txt, txtlen );
/* does not seem to help under GTK+ 1.2 !!!
gtk_editable_set_position( GTK_EDITABLE(m_text), old_pos ); */
SetInsertionPoint( old_pos );
return TRUE;
}
else // singe line
{
// cannot do this for GTK+'s Entry widget
return FALSE;
}
}
void wxTextCtrl::ApplyWidgetStyle()
{
if (m_windowStyle & wxTE_MULTILINE)