From f99ae84d7c106b3dc81d3da3a69c660b6160d71e Mon Sep 17 00:00:00 2001 From: Igor Korot Date: Sat, 15 Jun 2019 07:48:53 +0200 Subject: [PATCH 1/7] Implement different underline styles for wxTextCtrl --- include/wx/textctrl.h | 23 +++++++++++- interface/wx/textctrl.h | 42 +++++++++++++++++++++ samples/text/text.cpp | 12 +++++- src/common/gdicmn.cpp | 8 +++- src/common/textcmn.cpp | 6 +++ src/gtk/textctrl.cpp | 58 +++++++++++++++++++++++++++++ src/msw/textctrl.cpp | 78 ++++++++++++++++++++++++++++++++++++++- src/osx/cocoa/textctrl.mm | 58 ++++++++++++++++++++++++++++- 8 files changed, 280 insertions(+), 5 deletions(-) diff --git a/include/wx/textctrl.h b/include/wx/textctrl.h index 341409530e..0d1f3892eb 100644 --- a/include/wx/textctrl.h +++ b/include/wx/textctrl.h @@ -270,6 +270,14 @@ enum wxTextAttrLineSpacing wxTEXT_ATTR_LINE_SPACING_TWICE = 20 }; +enum wxTextAttrUnderlineType + { + wxTEXT_ATTR_UNDERLINE_NONE, + wxTEXT_ATTR_UNDERLINE_SOLID, + wxTEXT_ATTR_UNDERLINE_DOUBLE, + wxTEXT_ATTR_UNDERLINE_WAVE +}; + // ---------------------------------------------------------------------------- // wxTextAttr: a structure containing the visual attributes of a text // ---------------------------------------------------------------------------- @@ -321,6 +329,14 @@ public: void SetFontWeight(wxFontWeight fontWeight) { m_fontWeight = fontWeight; m_flags |= wxTEXT_ATTR_FONT_WEIGHT; } void SetFontFaceName(const wxString& faceName) { m_fontFaceName = faceName; m_flags |= wxTEXT_ATTR_FONT_FACE; } void SetFontUnderlined(bool underlined) { m_fontUnderlined = underlined; m_flags |= wxTEXT_ATTR_FONT_UNDERLINE; } + void SetFontUnderline(/*bool underlined, */wxTextAttrUnderlineType type = wxTEXT_ATTR_UNDERLINE_NONE, const wxColour& colour = wxNullColour) + { + if( type != wxTEXT_ATTR_UNDERLINE_NONE ) + m_flags |= wxTEXT_ATTR_FONT_UNDERLINE; +// m_fontUnderlined = underlined; + m_fontUnderlineType = type; + m_colUnderline = colour; + } void SetFontStrikethrough(bool strikethrough) { m_fontStrikethrough = strikethrough; m_flags |= wxTEXT_ATTR_FONT_STRIKETHROUGH; } void SetFontEncoding(wxFontEncoding encoding) { m_fontEncoding = encoding; m_flags |= wxTEXT_ATTR_FONT_ENCODING; } void SetFontFamily(wxFontFamily family) { m_fontFamily = family; m_flags |= wxTEXT_ATTR_FONT_FAMILY; } @@ -360,6 +376,8 @@ public: wxFontStyle GetFontStyle() const { return m_fontStyle; } wxFontWeight GetFontWeight() const { return m_fontWeight; } bool GetFontUnderlined() const { return m_fontUnderlined; } + wxTextAttrUnderlineType GetUnderlineType() const { return m_fontUnderlineType; } + const wxColour& GetUnderlineColour() const { return m_colUnderline; } bool GetFontStrikethrough() const { return m_fontStrikethrough; } const wxString& GetFontFaceName() const { return m_fontFaceName; } wxFontEncoding GetFontEncoding() const { return m_fontEncoding; } @@ -396,7 +414,8 @@ public: bool HasFontPointSize() const { return HasFlag(wxTEXT_ATTR_FONT_POINT_SIZE); } bool HasFontPixelSize() const { return HasFlag(wxTEXT_ATTR_FONT_PIXEL_SIZE); } bool HasFontItalic() const { return HasFlag(wxTEXT_ATTR_FONT_ITALIC); } - bool HasFontUnderlined() const { return HasFlag(wxTEXT_ATTR_FONT_UNDERLINE); } + bool HasFontUnderlined() const { return m_fontUnderlined; } + bool HasFontUnderline() const { return HasFlag(wxTEXT_ATTR_FONT_UNDERLINE); } bool HasFontStrikethrough() const { return HasFlag(wxTEXT_ATTR_FONT_STRIKETHROUGH); } bool HasFontFaceName() const { return HasFlag(wxTEXT_ATTR_FONT_FACE); } bool HasFontEncoding() const { return HasFlag(wxTEXT_ATTR_FONT_ENCODING); } @@ -509,6 +528,8 @@ private: wxFontWeight m_fontWeight; wxFontFamily m_fontFamily; bool m_fontUnderlined; + wxTextAttrUnderlineType m_fontUnderlineType; + wxColour m_colUnderline; bool m_fontStrikethrough; wxString m_fontFaceName; diff --git a/interface/wx/textctrl.h b/interface/wx/textctrl.h index a0b6b7464f..9f70fbce03 100644 --- a/interface/wx/textctrl.h +++ b/interface/wx/textctrl.h @@ -219,6 +219,19 @@ enum wxTextAttrLineSpacing }; +/** + The values that can be used with SetFontUnderline + + @since 3.1.3 +*/ +enum wxTextAttrUnderlineType +{ + wxTEXT_ATTR_UNDERLINE_NONE, + wxTEXT_ATTR_UNDERLINE_SOLID, + wxTEXT_ATTR_UNDERLINE_DOUBLE, + wxTEXT_ATTR_UNDERLINE_WAVE +}; + /** Describes the possible return values of wxTextCtrl::HitTest(). @@ -422,6 +435,20 @@ public: */ bool GetFontUnderlined() const; + /** + Returns the underline type, which is one of the @wxTextAttrUnderlineType values + + @since 3.1.3 + */ + wxTextAttrUnderlineType GetUnderlinedType() const; + + /** + Returns the underline color used + + @since 3.1.3 + */ + const wxColour& GetUnderlineColour() const; + /** Returns the font weight. */ @@ -604,6 +631,14 @@ public: */ bool HasFontUnderlined() const; + /** + Returns @true if the attribute object specifies different underline types + and color + + @since 3.1.3 + */ + bool HasFontUnderline() const; + /** Returns @true if the attribute object specifies font weight (bold, light or normal). @@ -807,6 +842,13 @@ public: */ void SetFontUnderlined(bool underlined); + /** + Set the different underline type and the underline color + + @since 3.1.3 + */ + void SetFontUnderline(wxTextAttrUnderlineType type = wxTEXT_ATTR_UNDERLINE_SOLID, wxColour colour = *wxBLACK); + /** Sets the font weight. */ diff --git a/samples/text/text.cpp b/samples/text/text.cpp index 7e5256b0b9..a8ad333492 100644 --- a/samples/text/text.cpp +++ b/samples/text/text.cpp @@ -1228,7 +1228,17 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h ) m_textrich->AppendText("This text should be cyan on blue\n"); m_textrich->SetDefaultStyle(wxTextAttr(*wxBLUE, *wxWHITE)); m_textrich->AppendText("And this should be in blue and the text you " - "type should be in blue as well"); + "type should be in blue as well.\n"); + m_textrich->SetDefaultStyle( wxTextAttr() ); + m_textrich->AppendText("And there is a "); + wxTextAttr attr = m_textrich->GetDefaultStyle(); + attr.SetFontUnderline( /*true, */wxTEXT_ATTR_UNDERLINE_WAVE, *wxRED ); + m_textrich->SetDefaultStyle( attr ); + m_textrich->AppendText("mispeled "); + attr.SetFontUnderline( /*false, */wxTEXT_ATTR_UNDERLINE_NONE ); + m_textrich->SetDefaultStyle( attr ); + m_textrich->AppendText("word"); + m_textrich->SetDefaultStyle(wxTextAttr(*wxBLUE, *wxWHITE)); // lay out the controls diff --git a/src/common/gdicmn.cpp b/src/common/gdicmn.cpp index 0b2d514408..1245e8c274 100644 --- a/src/common/gdicmn.cpp +++ b/src/common/gdicmn.cpp @@ -370,7 +370,13 @@ void wxColourDatabase::Initialize() {wxT("WHEAT"), 216, 216, 191}, {wxT("WHITE"), 255, 255, 255}, {wxT("YELLOW"), 255, 255, 0}, - {wxT("YELLOW GREEN"), 153, 204, 50} + {wxT("YELLOW GREEN"), 153, 204, 50}, + {wxT("wxNAVY"), 0, 0, 128}, + {wxT("wxTEAL"), 0, 128, 128}, + {wxT("wxLIGHT GREEN"), 0, 128, 0}, + {wxT("wxPURPLE"), 128, 0, 128}, + {wxT("wxMAROON"), 128, 0, 0}, + {wxT("wxDARK GREY"), 128, 128, 128} }; size_t n; diff --git a/src/common/textcmn.cpp b/src/common/textcmn.cpp index 2774635bbe..104f62a62d 100644 --- a/src/common/textcmn.cpp +++ b/src/common/textcmn.cpp @@ -163,6 +163,7 @@ void wxTextAttr::Init() m_fontStyle = wxFONTSTYLE_NORMAL; m_fontWeight = wxFONTWEIGHT_NORMAL; m_fontUnderlined = false; + m_fontUnderlineType = wxTEXT_ATTR_UNDERLINE_NONE; m_fontStrikethrough = false; m_fontEncoding = wxFONTENCODING_DEFAULT; m_fontFamily = wxFONTFAMILY_DEFAULT; @@ -175,6 +176,7 @@ void wxTextAttr::Init() m_textEffectFlags = wxTEXT_ATTR_EFFECT_NONE; m_outlineLevel = 0; m_bulletNumber = 0; + m_colUnderline = wxNullColour; } // Copy @@ -193,6 +195,8 @@ void wxTextAttr::Copy(const wxTextAttr& attr) m_fontStyle = attr.m_fontStyle; m_fontWeight = attr.m_fontWeight; m_fontUnderlined = attr.m_fontUnderlined; + m_fontUnderlineType = attr.m_fontUnderlineType; + m_colUnderline = attr.m_colUnderline; m_fontStrikethrough = attr.m_fontStrikethrough; m_fontFaceName = attr.m_fontFaceName; m_fontEncoding = attr.m_fontEncoding; @@ -258,6 +262,7 @@ bool wxTextAttr::operator== (const wxTextAttr& attr) const (!HasFontItalic() || (GetFontStyle() == attr.GetFontStyle())) && (!HasFontWeight() || (GetFontWeight() == attr.GetFontWeight())) && (!HasFontUnderlined() || (GetFontUnderlined() == attr.GetFontUnderlined())) && + ( ( GetUnderlineType() == attr.GetUnderlineType() ) && ( GetUnderlineColour() == attr.GetUnderlineColour() ) ) && (!HasFontStrikethrough() || (GetFontStrikethrough() == attr.GetFontStrikethrough())) && (!HasFontFaceName() || (GetFontFaceName() == attr.GetFontFaceName())) && (!HasFontEncoding() || (GetFontEncoding() == attr.GetFontEncoding())) && @@ -791,6 +796,7 @@ wxTextAttr wxTextAttr::Combine(const wxTextAttr& attr, } wxTextAttr newAttr(colFg, colBg, font); + newAttr.SetFontUnderline( /*attr.GetFontUnderlined(), */attr.GetUnderlineType(), attr.GetUnderlineColour()); if (attr.HasAlignment()) newAttr.SetAlignment(attr.GetAlignment()); diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index 54af9c1def..f059ee2d10 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -124,6 +124,64 @@ static void wxGtkTextApplyTagsFromAttr(GtkWidget *text, } } + if ( attr.HasFontUnderlined() ) + { + GtkTextTag *underlineColorTag; + PangoUnderline pangoUnderlineStyle; + switch ( attr.GetUnderlineType() ) + { + case wxTEXT_ATTR_UNDERLINE_NONE: + pangoUnderlineStyle = PANGO_UNDERLINE_NONE; + break; + case wxTEXT_ATTR_UNDERLINE_SOLID: + pangoUnderlineStyle = PANGO_UNDERLINE_SINGLE; + break; + case wxTEXT_ATTR_UNDERLINE_DOUBLE: + pangoUnderlineStyle = PANGO_UNDERLINE_DOUBLE; + break; + case wxTEXT_ATTR_UNDERLINE_WAVE: + pangoUnderlineStyle = PANGO_UNDERLINE_ERROR; + break; + } + + g_snprintf(buf, sizeof(buf), "WXFONTUNDERLINEWITHEFFECT"); + tag = gtk_text_tag_table_lookup( gtk_text_buffer_get_tag_table( text_buffer ), + buf ); + if (!tag) + { + tag = gtk_text_buffer_create_tag( text_buffer, buf, + "underline-set", TRUE, + "underline", pangoUnderlineStyle, + NULL ); + } + gtk_text_buffer_apply_tag (text_buffer, tag, start, end); + +#ifdef __WXGTK3__ + if ( gtk_check_version( 3, 16, 0 ) ) + { + wxColour color = attr.GetUnderlineColour(); + if ( !color.IsOk() ) + { + color = attr.GetTextColour(); + if( !color.IsOk() ) + color = *wxBLACK; + } + const GdkColor *gdkColor = attr.GetUnderlineColour().GetColor(); + GdkRGBA color_rgba = { + .red = CLAMP( (double) gdkColor->red / 65535.0, 0.0, 1.0 ), + .green = CLAMP( (double) gdkColor->green / 65535.0, 0.0, 1.0 ), + .blue = CLAMP ((double) gdkColor->blue / 65535.0, 0.0, 1.0 ), + .alpha = 1.0, + }; + underlineColorTag = gtk_text_buffer_create_tag( text_buffer, buf, + "underline-rgba-set", TRUE, + "underline-rgba", color_rgba, + NULL ); + gtk_text_buffer_apply_tag (text_buffer, underlineColorTag, start, end); + } +#endif + } + if (attr.HasTextColour()) { wxGtkTextRemoveTagsWithPrefix(text_buffer, "WXFORECOLOR", start, end); diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index fed5741b58..164935b07b 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -80,6 +80,23 @@ #define CFE_AUTOBACKCOLOR 0x04000000 #endif +// missing defines for MinGW build +#ifndef CFM_UNDERLINETYPE +#define CFM_UNDERLINETYPE 0x00800000 +#endif + +#ifndef CFU_UNDERLINE +#define CFU_UNDERLINE 1 +#endif + +#ifndef CFU_UNDERLINEDOUBLE +#define CFU_UNDERLINEDOUBLE 3 +#endif + +#ifndef CFU_UNDERLINEWAVE +#define CFU_UNDERLINEWAVE 8 +#endif + #if wxUSE_DRAG_AND_DROP && wxUSE_RICHEDIT // dummy value used for m_dropTarget, different from any valid pointer value @@ -2862,6 +2879,65 @@ bool wxTextCtrl::MSWSetCharFormat(const wxTextAttr& style, long start, long end) } } + if ( style.HasFontUnderline() ) + { + cf.dwMask |= CFM_UNDERLINETYPE; + wxTextAttrUnderlineType underlineType = style.GetUnderlineType(); + switch ( underlineType ) + { + case wxTEXT_ATTR_UNDERLINE_SOLID: + cf.bUnderlineType = CFU_UNDERLINE; + break; + case wxTEXT_ATTR_UNDERLINE_DOUBLE: + cf.bUnderlineType = CFU_UNDERLINEDOUBLE; + break; + case wxTEXT_ATTR_UNDERLINE_WAVE: + cf.bUnderlineType = CFU_UNDERLINEWAVE; + break; + } + +#if _RICHEDIT_VER >= 0x0800 + // The colours are coming from https://docs.microsoft.com/en-us/windows/desktop/api/tom/nf-tom-itextdocument2-geteffectcolor. + // Not all values from wxTheColourDatabase are supported as can be seen from the code + // Those are commented out currently + BYTE colour = 0; + wxColour col = style.GetUnderlineColour(); + if ( col == wxTheColourDatabase->Find( "BLACK" ) ) + colour = 0x01; + else if ( col == wxTheColourDatabase->Find( "BLUE" ) ) + colour = 0x02; + else if ( col == wxTheColourDatabase->Find( "CYAN" ) ) + colour = 0x03; + else if ( col == wxTheColourDatabase->Find( "GREEN" ) ) + colour = 0x04; + else if ( col == wxTheColourDatabase->Find( "MAGENTA" ) ) + colour = 0x05; + else if ( col == wxTheColourDatabase->Find( "RED" ) ) + colour = 0x06; + else if ( col == wxTheColourDatabase->Find( "YELLOW" ) ) + colour = 0x07; + else if ( col == wxTheColourDatabase->Find( "WHITE" ) ) + colour = 0x08; + else if ( col == wxTheColourDatabase->Find( "WXNAVY" ) ) + colour = 0x09; + else if ( col == wxTheColourDatabase->Find( "WXTEAL" ) ) + colour = 0x0A; + else if ( col == wxTheColourDatabase->Find( "WXLIGHT GREEN" ) ) + colour = 0x0B; + else if ( col == wxTheColourDatabase->Find( "WXPURPLE" ) ) + colour = 0x0C; + else if ( col == wxTheColourDatabase->Find( "WXMAROON" ) ) + colour = 0x0D; + else if ( col == wxTheColourDatabase->Find( "OLIVE" ) ) + colour = 0x0E; + else if ( col == wxTheColourDatabase->Find( "wxDARK GREY" ) ) + colour = 0x0F; + else if ( col == wxTheColourDatabase->Find( "LIGHT GREY" ) ) + colour = 0x10; + cf.bUnderlineColor = colour; +#endif + } + if ( style.HasTextColour() ) { cf.dwMask |= CFM_COLOR; @@ -3025,7 +3101,7 @@ bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style) // even try to do anything if it's the only thing we want to change if ( m_verRichEdit == 1 && !style.HasFont() && !style.HasTextColour() && !style.HasLeftIndent() && !style.HasRightIndent() && !style.HasAlignment() && - !style.HasTabs() ) + !style.HasTabs() && !style.GetFontUnderlined() ) { // nothing to do: return true if there was really nothing to do and // false if we failed to set bg colour diff --git a/src/osx/cocoa/textctrl.mm b/src/osx/cocoa/textctrl.mm index 089a1eef7c..6561fc4fb5 100644 --- a/src/osx/cocoa/textctrl.mm +++ b/src/osx/cocoa/textctrl.mm @@ -1082,14 +1082,43 @@ void wxNSTextViewControl::SetStyle(long start, if ( start == -1 && end == -1 ) { NSMutableDictionary* const - attrs = [NSMutableDictionary dictionaryWithCapacity:3]; + attrs = [NSMutableDictionary dictionaryWithCapacity:5]; if ( style.HasFont() ) [attrs setValue:style.GetFont().OSXGetNSFont() forKey:NSFontAttributeName]; if ( style.HasBackgroundColour() ) [attrs setValue:style.GetBackgroundColour().OSXGetNSColor() forKey:NSBackgroundColorAttributeName]; if ( style.HasTextColour() ) [attrs setValue:style.GetTextColour().OSXGetNSColor() forKey:NSForegroundColorAttributeName]; + if ( style.GetUnderlineType() ) + { + wxTextAttrUnderlineType underlineType = style.GetUnderlineType(); + switch ( underlineType ) + { + case wxTEXT_ATTR_UNDERLINE_NONE: + [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleNone )] forKey:NSUnderlineStyleAttributeName]; + break; + case wxTEXT_ATTR_UNDERLINE_SOLID: + [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle | NSUnderlineStyleSingle )] forKey:NSUnderlineStyleAttributeName]; + break; + + case wxTEXT_ATTR_UNDERLINE_DOUBLE: + [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle | NSUnderlineStyleDouble )] forKey:NSUnderlineStyleAttributeName]; + break; + + case wxTEXT_ATTR_UNDERLINE_WAVE: + [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle | NSUnderlinePatternDot )] forKey:NSUnderlineStyleAttributeName]; + break; + } + wxColour color = style.GetUnderlineColour(); + if ( !color.IsOk() ) + { + color = style.GetTextColour(); + if ( !color.IsOk() ) + color = *wxBLACK; + } + [attrs setValue:color.OSXGetNSColor() forKey:NSUnderlineColorAttributeName]; + } [m_textView setTypingAttributes:attrs]; } else // Set the attributes just for this range. @@ -1105,6 +1134,33 @@ void wxNSTextViewControl::SetStyle(long start, if ( style.HasTextColour() ) [storage addAttribute:NSForegroundColorAttributeName value:style.GetTextColour().OSXGetNSColor() range:range]; + + if( style.HasFontUnderlined() ) + { + NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; + if( style.GetUnderlineType() == wxTEXT_ATTR_UNDERLINE_NONE ) + [dict setObject:[NSNumber numberWithInt:(NSUnderlineStyleNone)] forKey:NSUnderlineStyleAttributeName]; + + if( style.GetUnderlineType() == wxTEXT_ATTR_UNDERLINE_SOLID ) + [dict setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle )] forKey:NSUnderlineStyleAttributeName]; + + if( style.GetUnderlineType() == wxTEXT_ATTR_UNDERLINE_DOUBLE ) + [dict setObject:[NSNumber numberWithInt:( NSUnderlineStyleDouble )] forKey:NSUnderlineStyleAttributeName]; + + if( style.GetUnderlineType() == wxTEXT_ATTR_UNDERLINE_WAVE ) + [dict setObject:[NSNumber numberWithInt:( NSUnderlinePatternDot )] forKey:NSUnderlineStyleAttributeName]; + wxColour color = style.GetUnderlineColour(); + if( !color.IsOk() ) + { + color = style.GetTextColour(); + if( !color.IsOk() ) + color = *wxBLACK; + } + [dict setValue:color.OSXGetNSColor() forKey:NSUnderlineColorAttributeName]; + + [storage addAttributes:dict range:range]; + [dict release]; + } } if ( style.HasAlignment() ) From 4afea28aabbe9dd704d80280d0d5d73af9846d3c Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sat, 6 Jul 2019 13:47:00 +0200 Subject: [PATCH 2/7] Improve underline changes of wxTextCtrl Get rid of m_fontUnderlined, use m_fontUnderlineType instead. Bugfixes in wxMSW, wxGTK and wxOSX code. Show more underline usage in the text sample. --- include/wx/textctrl.h | 16 +++---- samples/text/text.cpp | 26 +++++++----- src/common/gdicmn.cpp | 11 ++--- src/common/textcmn.cpp | 19 +++++---- src/gtk/textctrl.cpp | 37 +++++++--------- src/msw/textctrl.cpp | 88 +++++++++++++++++++++------------------ src/osx/cocoa/textctrl.mm | 57 +++++++++++++------------ 7 files changed, 126 insertions(+), 128 deletions(-) diff --git a/include/wx/textctrl.h b/include/wx/textctrl.h index 0d1f3892eb..693529bab4 100644 --- a/include/wx/textctrl.h +++ b/include/wx/textctrl.h @@ -271,7 +271,7 @@ enum wxTextAttrLineSpacing }; enum wxTextAttrUnderlineType - { +{ wxTEXT_ATTR_UNDERLINE_NONE, wxTEXT_ATTR_UNDERLINE_SOLID, wxTEXT_ATTR_UNDERLINE_DOUBLE, @@ -328,12 +328,10 @@ public: void SetFontStyle(wxFontStyle fontStyle) { m_fontStyle = fontStyle; m_flags |= wxTEXT_ATTR_FONT_ITALIC; } void SetFontWeight(wxFontWeight fontWeight) { m_fontWeight = fontWeight; m_flags |= wxTEXT_ATTR_FONT_WEIGHT; } void SetFontFaceName(const wxString& faceName) { m_fontFaceName = faceName; m_flags |= wxTEXT_ATTR_FONT_FACE; } - void SetFontUnderlined(bool underlined) { m_fontUnderlined = underlined; m_flags |= wxTEXT_ATTR_FONT_UNDERLINE; } - void SetFontUnderline(/*bool underlined, */wxTextAttrUnderlineType type = wxTEXT_ATTR_UNDERLINE_NONE, const wxColour& colour = wxNullColour) + void SetFontUnderlined(bool underlined) { SetFontUnderlined(underlined ? wxTEXT_ATTR_UNDERLINE_SOLID : wxTEXT_ATTR_UNDERLINE_NONE); } + void SetFontUnderlined(wxTextAttrUnderlineType type, const wxColour& colour = wxNullColour) { - if( type != wxTEXT_ATTR_UNDERLINE_NONE ) - m_flags |= wxTEXT_ATTR_FONT_UNDERLINE; -// m_fontUnderlined = underlined; + m_flags |= wxTEXT_ATTR_FONT_UNDERLINE; m_fontUnderlineType = type; m_colUnderline = colour; } @@ -375,7 +373,7 @@ public: int GetFontSize() const { return m_fontSize; } wxFontStyle GetFontStyle() const { return m_fontStyle; } wxFontWeight GetFontWeight() const { return m_fontWeight; } - bool GetFontUnderlined() const { return m_fontUnderlined; } + bool GetFontUnderlined() const { return m_fontUnderlineType != wxTEXT_ATTR_UNDERLINE_NONE; } wxTextAttrUnderlineType GetUnderlineType() const { return m_fontUnderlineType; } const wxColour& GetUnderlineColour() const { return m_colUnderline; } bool GetFontStrikethrough() const { return m_fontStrikethrough; } @@ -414,8 +412,7 @@ public: bool HasFontPointSize() const { return HasFlag(wxTEXT_ATTR_FONT_POINT_SIZE); } bool HasFontPixelSize() const { return HasFlag(wxTEXT_ATTR_FONT_PIXEL_SIZE); } bool HasFontItalic() const { return HasFlag(wxTEXT_ATTR_FONT_ITALIC); } - bool HasFontUnderlined() const { return m_fontUnderlined; } - bool HasFontUnderline() const { return HasFlag(wxTEXT_ATTR_FONT_UNDERLINE); } + bool HasFontUnderlined() const { return HasFlag(wxTEXT_ATTR_FONT_UNDERLINE); } bool HasFontStrikethrough() const { return HasFlag(wxTEXT_ATTR_FONT_STRIKETHROUGH); } bool HasFontFaceName() const { return HasFlag(wxTEXT_ATTR_FONT_FACE); } bool HasFontEncoding() const { return HasFlag(wxTEXT_ATTR_FONT_ENCODING); } @@ -527,7 +524,6 @@ private: wxFontStyle m_fontStyle; wxFontWeight m_fontWeight; wxFontFamily m_fontFamily; - bool m_fontUnderlined; wxTextAttrUnderlineType m_fontUnderlineType; wxColour m_colUnderline; bool m_fontStrikethrough; diff --git a/samples/text/text.cpp b/samples/text/text.cpp index a8ad333492..f5df4e4045 100644 --- a/samples/text/text.cpp +++ b/samples/text/text.cpp @@ -1229,17 +1229,23 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h ) m_textrich->SetDefaultStyle(wxTextAttr(*wxBLUE, *wxWHITE)); m_textrich->AppendText("And this should be in blue and the text you " "type should be in blue as well.\n"); - m_textrich->SetDefaultStyle( wxTextAttr() ); - m_textrich->AppendText("And there is a "); + m_textrich->SetDefaultStyle(wxTextAttr()); wxTextAttr attr = m_textrich->GetDefaultStyle(); - attr.SetFontUnderline( /*true, */wxTEXT_ATTR_UNDERLINE_WAVE, *wxRED ); - m_textrich->SetDefaultStyle( attr ); - m_textrich->AppendText("mispeled "); - attr.SetFontUnderline( /*false, */wxTEXT_ATTR_UNDERLINE_NONE ); - m_textrich->SetDefaultStyle( attr ); - m_textrich->AppendText("word"); - m_textrich->SetDefaultStyle(wxTextAttr(*wxBLUE, *wxWHITE)); - + attr.SetFontUnderlined(true); + m_textrich->SetDefaultStyle(attr); + m_textrich->AppendText("\nAnd there"); + attr.SetFontUnderlined(false); + m_textrich->SetDefaultStyle(attr); + m_textrich->AppendText(" is a "); + attr.SetFontUnderlined(wxTEXT_ATTR_UNDERLINE_WAVE, *wxRED); + m_textrich->SetDefaultStyle(attr); + m_textrich->AppendText("mispeled"); + attr.SetFontUnderlined(false); + m_textrich->SetDefaultStyle(attr); + m_textrich->AppendText(" word."); + attr.SetFontUnderlined(wxTEXT_ATTR_UNDERLINE_DOUBLE, *wxGREEN); + const long endPos = m_textrich->GetLastPosition(); + m_textrich->SetStyle(endPos - 4, endPos - 2, attr); // lay out the controls wxBoxSizer *column1 = new wxBoxSizer(wxVERTICAL); diff --git a/src/common/gdicmn.cpp b/src/common/gdicmn.cpp index 1245e8c274..a7d8980501 100644 --- a/src/common/gdicmn.cpp +++ b/src/common/gdicmn.cpp @@ -328,6 +328,7 @@ void wxColourDatabase::Initialize() {wxT("INDIAN RED"), 79, 47, 47}, {wxT("KHAKI"), 159, 159, 95}, {wxT("LIGHT BLUE"), 191, 216, 216}, + {wxT("LIGHT GREEN"), 0, 128, 0}, {wxT("LIGHT GREY"), 192, 192, 192}, {wxT("LIGHT STEEL BLUE"), 143, 143, 188}, {wxT("LIME GREEN"), 50, 204, 50}, @@ -347,6 +348,7 @@ void wxColourDatabase::Initialize() {wxT("MEDIUM VIOLET RED"), 219, 112, 147}, {wxT("MIDNIGHT BLUE"), 47, 47, 79}, {wxT("NAVY"), 35, 35, 142}, + {wxT("OLIVE"), 128, 128, 0}, {wxT("ORANGE"), 204, 50, 50}, {wxT("ORANGE RED"), 255, 0, 127}, {wxT("ORCHID"), 219, 112, 219}, @@ -363,6 +365,7 @@ void wxColourDatabase::Initialize() {wxT("SPRING GREEN"), 0, 255, 127}, {wxT("STEEL BLUE"), 35, 107, 142}, {wxT("TAN"), 219, 147, 112}, + {wxT("TEAL"), 0, 128, 128}, {wxT("THISTLE"), 216, 191, 216}, {wxT("TURQUOISE"), 173, 234, 234}, {wxT("VIOLET"), 79, 47, 79}, @@ -370,13 +373,7 @@ void wxColourDatabase::Initialize() {wxT("WHEAT"), 216, 216, 191}, {wxT("WHITE"), 255, 255, 255}, {wxT("YELLOW"), 255, 255, 0}, - {wxT("YELLOW GREEN"), 153, 204, 50}, - {wxT("wxNAVY"), 0, 0, 128}, - {wxT("wxTEAL"), 0, 128, 128}, - {wxT("wxLIGHT GREEN"), 0, 128, 0}, - {wxT("wxPURPLE"), 128, 0, 128}, - {wxT("wxMAROON"), 128, 0, 0}, - {wxT("wxDARK GREY"), 128, 128, 128} + {wxT("YELLOW GREEN"), 153, 204, 50} }; size_t n; diff --git a/src/common/textcmn.cpp b/src/common/textcmn.cpp index 104f62a62d..9f8de569bd 100644 --- a/src/common/textcmn.cpp +++ b/src/common/textcmn.cpp @@ -162,7 +162,6 @@ void wxTextAttr::Init() m_fontSize = 12; m_fontStyle = wxFONTSTYLE_NORMAL; m_fontWeight = wxFONTWEIGHT_NORMAL; - m_fontUnderlined = false; m_fontUnderlineType = wxTEXT_ATTR_UNDERLINE_NONE; m_fontStrikethrough = false; m_fontEncoding = wxFONTENCODING_DEFAULT; @@ -194,7 +193,6 @@ void wxTextAttr::Copy(const wxTextAttr& attr) m_fontSize = attr.m_fontSize; m_fontStyle = attr.m_fontStyle; m_fontWeight = attr.m_fontWeight; - m_fontUnderlined = attr.m_fontUnderlined; m_fontUnderlineType = attr.m_fontUnderlineType; m_colUnderline = attr.m_colUnderline; m_fontStrikethrough = attr.m_fontStrikethrough; @@ -261,8 +259,7 @@ bool wxTextAttr::operator== (const wxTextAttr& attr) const (!HasFontSize() || (GetFontSize() == attr.GetFontSize())) && (!HasFontItalic() || (GetFontStyle() == attr.GetFontStyle())) && (!HasFontWeight() || (GetFontWeight() == attr.GetFontWeight())) && - (!HasFontUnderlined() || (GetFontUnderlined() == attr.GetFontUnderlined())) && - ( ( GetUnderlineType() == attr.GetUnderlineType() ) && ( GetUnderlineColour() == attr.GetUnderlineColour() ) ) && + (!HasFontUnderlined() || ((GetUnderlineType() == attr.GetUnderlineType()) && (GetUnderlineColour() == attr.GetUnderlineColour()) )) && (!HasFontStrikethrough() || (GetFontStrikethrough() == attr.GetFontStrikethrough())) && (!HasFontFaceName() || (GetFontFaceName() == attr.GetFontFaceName())) && (!HasFontEncoding() || (GetFontEncoding() == attr.GetFontEncoding())) && @@ -332,7 +329,8 @@ bool wxTextAttr::EqPartial(const wxTextAttr& attr, bool weakTest) const if (HasFontItalic() && attr.HasFontItalic() && GetFontStyle() != attr.GetFontStyle()) return false; - if (HasFontUnderlined() && attr.HasFontUnderlined() && GetFontUnderlined() != attr.GetFontUnderlined()) + if (HasFontUnderlined() && attr.HasFontUnderlined() && + ( (GetUnderlineType() != attr.GetUnderlineType()) || (GetUnderlineColour() != attr.GetUnderlineColour()) )) return false; if (HasFontStrikethrough() && attr.HasFontStrikethrough() && GetFontStrikethrough() != attr.GetFontStrikethrough()) @@ -507,7 +505,7 @@ bool wxTextAttr::GetFontAttributes(const wxFont& font, int flags) m_fontWeight = font.GetWeight(); if (flags & wxTEXT_ATTR_FONT_UNDERLINE) - m_fontUnderlined = font.GetUnderlined(); + m_fontUnderlineType = font.GetUnderlined() ? wxTEXT_ATTR_UNDERLINE_SOLID : wxTEXT_ATTR_UNDERLINE_NONE; if (flags & wxTEXT_ATTR_FONT_STRIKETHROUGH) m_fontStrikethrough = font.GetStrikethrough(); @@ -576,8 +574,10 @@ bool wxTextAttr::Apply(const wxTextAttr& style, const wxTextAttr* compareWith) if (style.HasFontUnderlined()) { - if (!(compareWith && compareWith->HasFontUnderlined() && compareWith->GetFontUnderlined() == style.GetFontUnderlined())) - destStyle.SetFontUnderlined(style.GetFontUnderlined()); + if (!(compareWith && compareWith->HasFontUnderlined() && + compareWith->GetUnderlineType() == style.GetUnderlineType() && + compareWith->GetUnderlineColour() == style.GetUnderlineColour())) + destStyle.SetFontUnderlined(style.GetUnderlineType(), style.GetUnderlineColour()); } if (style.HasFontStrikethrough()) @@ -796,7 +796,8 @@ wxTextAttr wxTextAttr::Combine(const wxTextAttr& attr, } wxTextAttr newAttr(colFg, colBg, font); - newAttr.SetFontUnderline( /*attr.GetFontUnderlined(), */attr.GetUnderlineType(), attr.GetUnderlineColour()); + if (attr.HasFontUnderlined()) + newAttr.SetFontUnderlined(attr.GetUnderlineType(), attr.GetUnderlineColour()); if (attr.HasAlignment()) newAttr.SetAlignment(attr.GetAlignment()); diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index f059ee2d10..ba2d043c53 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -126,7 +126,6 @@ static void wxGtkTextApplyTagsFromAttr(GtkWidget *text, if ( attr.HasFontUnderlined() ) { - GtkTextTag *underlineColorTag; PangoUnderline pangoUnderlineStyle; switch ( attr.GetUnderlineType() ) { @@ -144,40 +143,34 @@ static void wxGtkTextApplyTagsFromAttr(GtkWidget *text, break; } - g_snprintf(buf, sizeof(buf), "WXFONTUNDERLINEWITHEFFECT"); + g_snprintf(buf, sizeof(buf), "WXFONTUNDERLINESTYLE %u", + (unsigned)pangoUnderlineStyle); tag = gtk_text_tag_table_lookup( gtk_text_buffer_get_tag_table( text_buffer ), buf ); if (!tag) - { tag = gtk_text_buffer_create_tag( text_buffer, buf, "underline-set", TRUE, "underline", pangoUnderlineStyle, NULL ); - } gtk_text_buffer_apply_tag (text_buffer, tag, start, end); #ifdef __WXGTK3__ - if ( gtk_check_version( 3, 16, 0 ) ) + if ( wx_is_at_least_gtk3(16) ) { - wxColour color = attr.GetUnderlineColour(); - if ( !color.IsOk() ) + wxColour colour = attr.GetUnderlineColour(); + if ( colour.IsOk() ) { - color = attr.GetTextColour(); - if( !color.IsOk() ) - color = *wxBLACK; + g_snprintf(buf, sizeof(buf), "WXFONTUNDERLINECOLOUR %u %u %u %u", + colour.Red(), colour.Green(), colour.Blue(), colour.Alpha()); + tag = gtk_text_tag_table_lookup( gtk_text_buffer_get_tag_table( text_buffer ), + buf ); + if (!tag) + tag = gtk_text_buffer_create_tag( text_buffer, buf, + "underline-rgba-set", TRUE, + "underline-rgba", static_cast(colour), + NULL ); + gtk_text_buffer_apply_tag (text_buffer, tag, start, end); } - const GdkColor *gdkColor = attr.GetUnderlineColour().GetColor(); - GdkRGBA color_rgba = { - .red = CLAMP( (double) gdkColor->red / 65535.0, 0.0, 1.0 ), - .green = CLAMP( (double) gdkColor->green / 65535.0, 0.0, 1.0 ), - .blue = CLAMP ((double) gdkColor->blue / 65535.0, 0.0, 1.0 ), - .alpha = 1.0, - }; - underlineColorTag = gtk_text_buffer_create_tag( text_buffer, buf, - "underline-rgba-set", TRUE, - "underline-rgba", color_rgba, - NULL ); - gtk_text_buffer_apply_tag (text_buffer, underlineColorTag, start, end); } #endif } diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 164935b07b..42ea91176e 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -82,19 +82,23 @@ // missing defines for MinGW build #ifndef CFM_UNDERLINETYPE -#define CFM_UNDERLINETYPE 0x00800000 + #define CFM_UNDERLINETYPE 0x00800000 +#endif + +#ifndef CFU_UNDERLINENONE + #define CFU_UNDERLINENONE 0 #endif #ifndef CFU_UNDERLINE -#define CFU_UNDERLINE 1 + #define CFU_UNDERLINE 1 #endif #ifndef CFU_UNDERLINEDOUBLE -#define CFU_UNDERLINEDOUBLE 3 + #define CFU_UNDERLINEDOUBLE 3 #endif #ifndef CFU_UNDERLINEWAVE -#define CFU_UNDERLINEWAVE 8 + #define CFU_UNDERLINEWAVE 8 #endif #if wxUSE_DRAG_AND_DROP && wxUSE_RICHEDIT @@ -2879,12 +2883,14 @@ bool wxTextCtrl::MSWSetCharFormat(const wxTextAttr& style, long start, long end) } } - if ( style.HasFontUnderline() ) + if ( style.HasFontUnderlined() ) { cf.dwMask |= CFM_UNDERLINETYPE; - wxTextAttrUnderlineType underlineType = style.GetUnderlineType(); - switch ( underlineType ) + switch ( style.GetUnderlineType() ) { + case wxTEXT_ATTR_UNDERLINE_NONE: + cf.bUnderlineType = CFU_UNDERLINENONE; + break; case wxTEXT_ATTR_UNDERLINE_SOLID: cf.bUnderlineType = CFU_UNDERLINE; break; @@ -2898,42 +2904,42 @@ bool wxTextCtrl::MSWSetCharFormat(const wxTextAttr& style, long start, long end) #if _RICHEDIT_VER >= 0x0800 // The colours are coming from https://docs.microsoft.com/en-us/windows/desktop/api/tom/nf-tom-itextdocument2-geteffectcolor. - // Not all values from wxTheColourDatabase are supported as can be seen from the code - // Those are commented out currently BYTE colour = 0; wxColour col = style.GetUnderlineColour(); - if ( col == wxTheColourDatabase->Find( "BLACK" ) ) - colour = 0x01; - else if ( col == wxTheColourDatabase->Find( "BLUE" ) ) - colour = 0x02; - else if ( col == wxTheColourDatabase->Find( "CYAN" ) ) - colour = 0x03; - else if ( col == wxTheColourDatabase->Find( "GREEN" ) ) - colour = 0x04; - else if ( col == wxTheColourDatabase->Find( "MAGENTA" ) ) - colour = 0x05; - else if ( col == wxTheColourDatabase->Find( "RED" ) ) - colour = 0x06; - else if ( col == wxTheColourDatabase->Find( "YELLOW" ) ) - colour = 0x07; - else if ( col == wxTheColourDatabase->Find( "WHITE" ) ) - colour = 0x08; - else if ( col == wxTheColourDatabase->Find( "WXNAVY" ) ) - colour = 0x09; - else if ( col == wxTheColourDatabase->Find( "WXTEAL" ) ) - colour = 0x0A; - else if ( col == wxTheColourDatabase->Find( "WXLIGHT GREEN" ) ) - colour = 0x0B; - else if ( col == wxTheColourDatabase->Find( "WXPURPLE" ) ) - colour = 0x0C; - else if ( col == wxTheColourDatabase->Find( "WXMAROON" ) ) - colour = 0x0D; - else if ( col == wxTheColourDatabase->Find( "OLIVE" ) ) - colour = 0x0E; - else if ( col == wxTheColourDatabase->Find( "wxDARK GREY" ) ) - colour = 0x0F; - else if ( col == wxTheColourDatabase->Find( "LIGHT GREY" ) ) - colour = 0x10; + if ( col == wxNullColour ) + colour = 0; + else if ( col == wxTheColourDatabase->Find("BLACK") ) + colour = 1; + else if ( col == wxTheColourDatabase->Find("BLUE") ) + colour = 2; + else if ( col == wxTheColourDatabase->Find("CYAN") ) + colour = 3; + else if ( col == wxTheColourDatabase->Find("GREEN") ) + colour = 4; + else if ( col == wxTheColourDatabase->Find("MAGENTA") ) + colour = 5; + else if ( col == wxTheColourDatabase->Find("RED") ) + colour = 6; + else if ( col == wxTheColourDatabase->Find("YELLOW") ) + colour = 7; + else if ( col == wxTheColourDatabase->Find("WHITE") ) + colour = 8; + else if ( col == wxColour(0, 0, 128) ) // navy + colour = 9; + else if ( col == wxTheColourDatabase->Find("TEAL") ) + colour = 10; + else if ( col == wxTheColourDatabase->Find("LIGHT GREEN") ) + colour = 11; + else if ( col == wxColour(128, 0, 128) ) // purple + colour = 12; + else if ( col == wxColour(128, 0, 0) ) // maroon + colour = 13; + else if ( col == wxTheColourDatabase->Find("OLIVE") ) + colour = 14; + else if ( col == wxTheColourDatabase->Find("GREY") ) + colour = 15; + else if ( col == wxTheColourDatabase->Find("LIGHT GREY") ) + colour = 16; cf.bUnderlineColor = colour; #endif } diff --git a/src/osx/cocoa/textctrl.mm b/src/osx/cocoa/textctrl.mm index 6561fc4fb5..d1f8e3d4c7 100644 --- a/src/osx/cocoa/textctrl.mm +++ b/src/osx/cocoa/textctrl.mm @@ -1089,35 +1089,31 @@ void wxNSTextViewControl::SetStyle(long start, [attrs setValue:style.GetBackgroundColour().OSXGetNSColor() forKey:NSBackgroundColorAttributeName]; if ( style.HasTextColour() ) [attrs setValue:style.GetTextColour().OSXGetNSColor() forKey:NSForegroundColorAttributeName]; - if ( style.GetUnderlineType() ) + if ( style.HasFontUnderlined() ) { - wxTextAttrUnderlineType underlineType = style.GetUnderlineType(); - switch ( underlineType ) + switch ( style.GetUnderlineType() ) { case wxTEXT_ATTR_UNDERLINE_NONE: [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleNone )] forKey:NSUnderlineStyleAttributeName]; break; case wxTEXT_ATTR_UNDERLINE_SOLID: - [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle | NSUnderlineStyleSingle )] forKey:NSUnderlineStyleAttributeName]; + [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle )] forKey:NSUnderlineStyleAttributeName]; break; case wxTEXT_ATTR_UNDERLINE_DOUBLE: - [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle | NSUnderlineStyleDouble )] forKey:NSUnderlineStyleAttributeName]; + [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleDouble )] forKey:NSUnderlineStyleAttributeName]; break; case wxTEXT_ATTR_UNDERLINE_WAVE: [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle | NSUnderlinePatternDot )] forKey:NSUnderlineStyleAttributeName]; break; } - wxColour color = style.GetUnderlineColour(); - if ( !color.IsOk() ) + wxColour colour = style.GetUnderlineColour(); + if ( colour.IsOk() ) { - color = style.GetTextColour(); - if ( !color.IsOk() ) - color = *wxBLACK; + [attrs setValue:colour.OSXGetNSColor() forKey:NSUnderlineColorAttributeName]; } - [attrs setValue:color.OSXGetNSColor() forKey:NSUnderlineColorAttributeName]; } [m_textView setTypingAttributes:attrs]; } @@ -1138,26 +1134,29 @@ void wxNSTextViewControl::SetStyle(long start, if( style.HasFontUnderlined() ) { NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; - if( style.GetUnderlineType() == wxTEXT_ATTR_UNDERLINE_NONE ) - [dict setObject:[NSNumber numberWithInt:(NSUnderlineStyleNone)] forKey:NSUnderlineStyleAttributeName]; - - if( style.GetUnderlineType() == wxTEXT_ATTR_UNDERLINE_SOLID ) - [dict setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle )] forKey:NSUnderlineStyleAttributeName]; - - if( style.GetUnderlineType() == wxTEXT_ATTR_UNDERLINE_DOUBLE ) - [dict setObject:[NSNumber numberWithInt:( NSUnderlineStyleDouble )] forKey:NSUnderlineStyleAttributeName]; - - if( style.GetUnderlineType() == wxTEXT_ATTR_UNDERLINE_WAVE ) - [dict setObject:[NSNumber numberWithInt:( NSUnderlinePatternDot )] forKey:NSUnderlineStyleAttributeName]; - wxColour color = style.GetUnderlineColour(); - if( !color.IsOk() ) + switch ( style.GetUnderlineType() ) { - color = style.GetTextColour(); - if( !color.IsOk() ) - color = *wxBLACK; - } - [dict setValue:color.OSXGetNSColor() forKey:NSUnderlineColorAttributeName]; + case wxTEXT_ATTR_UNDERLINE_NONE: + [dict setObject:[NSNumber numberWithInt:( NSUnderlineStyleNone )] forKey:NSUnderlineStyleAttributeName]; + break; + case wxTEXT_ATTR_UNDERLINE_SOLID: + [dict setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle )] forKey:NSUnderlineStyleAttributeName]; + break; + + case wxTEXT_ATTR_UNDERLINE_DOUBLE: + [dict setObject:[NSNumber numberWithInt:( NSUnderlineStyleDouble )] forKey:NSUnderlineStyleAttributeName]; + break; + + case wxTEXT_ATTR_UNDERLINE_WAVE: + [dict setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle | NSUnderlinePatternDot )] forKey:NSUnderlineStyleAttributeName]; + break; + } + wxColour colour = style.GetUnderlineColour(); + if ( colour.IsOk() ) + { + [dict setValue:colour.OSXGetNSColor() forKey:NSUnderlineColorAttributeName]; + } [storage addAttributes:dict range:range]; [dict release]; } From e62f86f3c3747bab11ddb0e3c2d87d27c0eac2ac Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sun, 7 Jul 2019 14:18:30 +0200 Subject: [PATCH 3/7] Remove trailing white-space --- src/osx/cocoa/textctrl.mm | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/osx/cocoa/textctrl.mm b/src/osx/cocoa/textctrl.mm index d1f8e3d4c7..17c6da0741 100644 --- a/src/osx/cocoa/textctrl.mm +++ b/src/osx/cocoa/textctrl.mm @@ -128,7 +128,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil; @implementation wxTextEntryFormatter -- (id)init +- (id)init { if ( self = [super init] ) { @@ -138,7 +138,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil; return self; } -- (void) setMaxLength:(int) maxlen +- (void) setMaxLength:(int) maxlen { maxLength = maxlen; } @@ -155,13 +155,13 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil; return [NSString stringWithString:anObject]; } -- (BOOL)getObjectValue:(id *)obj forString:(NSString *)string errorDescription:(NSString **)error +- (BOOL)getObjectValue:(id *)obj forString:(NSString *)string errorDescription:(NSString **)error { *obj = [NSString stringWithString:string]; return YES; } -- (BOOL)isPartialStringValid:(NSString **)partialStringPtr proposedSelectedRange:(NSRangePointer)proposedSelRangePtr +- (BOOL)isPartialStringValid:(NSString **)partialStringPtr proposedSelectedRange:(NSRangePointer)proposedSelRangePtr originalString:(NSString *)origString originalSelectedRange:(NSRange)origSelRange errorDescription:(NSString **)error { if ( maxLength > 0 ) @@ -226,9 +226,9 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil; - (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySelector:(SEL)commandSelector { wxUnusedVar(textView); - + BOOL handled = NO; - + wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( control ); if ( impl ) { @@ -322,7 +322,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil; } } } - + return handled; } @@ -406,7 +406,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil; BOOL r = [super becomeFirstResponder]; if ( impl != NULL && r ) impl->DoNotifyFocusSet(); - + return r; } @@ -653,11 +653,11 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil; { wxUnusedVar(textView); wxUnusedVar(control); - + BOOL handled = NO; // send back key events wx' common code knows how to handle - + wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self ); if ( impl ) { @@ -681,7 +681,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil; } } } - + return handled; } @@ -740,7 +740,7 @@ wxNSTextViewControl::wxNSTextViewControl( wxTextCtrl *wxPeer, WXWidget w, long s [tv setVerticallyResizable:YES]; [tv setHorizontallyResizable:hasHScroll]; [tv setAutoresizingMask:NSViewWidthSizable]; - + if ( hasHScroll ) { [[tv textContainer] setContainerSize:NSMakeSize(MAX_WIDTH, MAX_WIDTH)]; @@ -1036,14 +1036,14 @@ void wxNSTextViewControl::SetFont( const wxFont & font , const wxColour& WXUNUSE bool wxNSTextViewControl::GetStyle(long position, wxTextAttr& style) { if (m_textView && position >=0) - { + { NSFont* font = NULL; NSColor* bgcolor = NULL; NSColor* fgcolor = NULL; // NOTE: It appears that other platforms accept GetStyle with the position == length // but that NSTextStorage does not accept length as a valid position. // Therefore we return the default control style in that case. - if (position < (long) [[m_textView string] length]) + if (position < (long) [[m_textView string] length]) { NSTextStorage* storage = [m_textView textStorage]; font = [storage attribute:NSFontAttributeName atIndex:position effectiveRange:NULL]; @@ -1057,13 +1057,13 @@ bool wxNSTextViewControl::GetStyle(long position, wxTextAttr& style) bgcolor = [attrs objectForKey:NSBackgroundColorAttributeName]; fgcolor = [attrs objectForKey:NSForegroundColorAttributeName]; } - + if (font) style.SetFont(wxFont(font)); - + if (bgcolor) style.SetBackgroundColour(wxColour(bgcolor)); - + if (fgcolor) style.SetTextColour(wxColour(fgcolor)); return true; @@ -1161,7 +1161,7 @@ void wxNSTextViewControl::SetStyle(long start, [dict release]; } } - + if ( style.HasAlignment() ) { switch ( style.GetAlignment() ) @@ -1565,7 +1565,7 @@ wxWidgetImplType* wxWidgetImpl::CreateTextControl( wxTextCtrl* wxpeer, { [v setAlignment:NSCenterTextAlignment]; } - + NSTextFieldCell* cell = [v cell]; [cell setWraps:NO]; [cell setScrollable:YES]; From f248f82aa9a60581051433c0afb6eb2d524fd5a1 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Wed, 10 Jul 2019 20:19:31 +0200 Subject: [PATCH 4/7] Update wxTextAttr underline documentation --- interface/wx/textctrl.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/interface/wx/textctrl.h b/interface/wx/textctrl.h index 9f70fbce03..c26277e553 100644 --- a/interface/wx/textctrl.h +++ b/interface/wx/textctrl.h @@ -220,7 +220,7 @@ enum wxTextAttrLineSpacing /** - The values that can be used with SetFontUnderline + Underline types that can be used in wxTextAttr::SetFontUnderline(). @since 3.1.3 */ @@ -436,14 +436,14 @@ public: bool GetFontUnderlined() const; /** - Returns the underline type, which is one of the @wxTextAttrUnderlineType values + Returns the underline type, which is one of the @wxTextAttrUnderlineType values. @since 3.1.3 */ - wxTextAttrUnderlineType GetUnderlinedType() const; + wxTextAttrUnderlineType GetUnderlineType() const; /** - Returns the underline color used + Returns the underline color used. wxNullColour when the text colour is used. @since 3.1.3 */ @@ -631,14 +631,6 @@ public: */ bool HasFontUnderlined() const; - /** - Returns @true if the attribute object specifies different underline types - and color - - @since 3.1.3 - */ - bool HasFontUnderline() const; - /** Returns @true if the attribute object specifies font weight (bold, light or normal). @@ -838,16 +830,24 @@ public: void SetFontStyle(wxFontStyle fontStyle); /** - Sets the font underlining. + Sets the font underlining (solid line, using text colour). */ void SetFontUnderlined(bool underlined); /** - Set the different underline type and the underline color + Sets the font underlining with a wxTextAttrUnderlineType and wxColour. + Specifying wxNullColour will use the text colour. + + @note On wxMSW, wxTEXT_ATTR_UNDERLINE_DOUBLE is shown as wxTEXT_ATTR_UNDERLINE_SOLID. There is only a limited number of colours supported, + the RGB values are listed here. + + @note On wxGTK, underline colour is only supported by wxGTK3. GTK might overrule the colour of wxTEXT_ATTR_UNDERLINE_WAVE. + + @note On wxOSX, wxTEXT_ATTR_UNDERLINE_WAVE is shown as a dotted line. @since 3.1.3 */ - void SetFontUnderline(wxTextAttrUnderlineType type = wxTEXT_ATTR_UNDERLINE_SOLID, wxColour colour = *wxBLACK); + void SetFontUnderlined(wxTextAttrUnderlineType type, const wxColour& colour = wxNullColour); /** Sets the font weight. From f5b3b6a84db37f8b9af7359c32706b7b741cff8b Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Thu, 11 Jul 2019 00:50:38 +0200 Subject: [PATCH 5/7] Determine underline type and colour in wxTextCtrl::GetStyle --- src/gtk/textctrl.cpp | 41 +++++++++++++++++++++++++++-- src/msw/textctrl.cpp | 55 +++++++++++++++++++++++++++++++++++++++ src/osx/cocoa/textctrl.mm | 32 +++++++++++++++++++++++ 3 files changed, 126 insertions(+), 2 deletions(-) diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index ba2d043c53..a61369ec02 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -1912,8 +1912,45 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style) if ( font.SetNativeFontInfo(wxString(pangoFontString)) ) style.SetFont(font); - if ( pattr->appearance.underline != PANGO_UNDERLINE_NONE ) - style.SetFontUnderlined(true); + wxTextAttrUnderlineType underlineType = wxTEXT_ATTR_UNDERLINE_NONE; + switch ( pattr->appearance.underline ) + { + case PANGO_UNDERLINE_SINGLE: + underlineType = wxTEXT_ATTR_UNDERLINE_SOLID; + break; + case PANGO_UNDERLINE_DOUBLE: + underlineType = wxTEXT_ATTR_UNDERLINE_DOUBLE; + break; + case PANGO_UNDERLINE_ERROR: + underlineType = wxTEXT_ATTR_UNDERLINE_WAVE; + break; + } + + wxColour underlineColour = wxNullColour; +#ifdef __WXGTK3__ + GSList* tags = gtk_text_iter_get_tags(&positioni); + for ( GSList* tagp = tags; tagp != NULL; tagp = tagp->next ) + { + GtkTextTag* tag = static_cast(tagp->data); + gboolean underlineSet = FALSE; + g_object_get(tag, "underline-rgba-set", &underlineSet, NULL); + if ( underlineSet ) + { + GdkRGBA* gdkColour = NULL; + g_object_get(tag, "underline-rgba", &gdkColour, NULL); + if ( gdkColour ) + underlineColour = wxColour(*gdkColour); + gdk_rgba_free(gdkColour); + break; + } + } + if ( tags ) + g_slist_free(tags); +#endif + + if ( underlineType != wxTEXT_ATTR_UNDERLINE_NONE ) + style.SetFontUnderlined(underlineType, underlineColour); + if ( pattr->appearance.strikethrough ) style.SetFontStrikethrough(true); diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 42ea91176e..b77446a5dd 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -3259,6 +3259,61 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style) } #endif // wxUSE_RICHEDIT2 + wxTextAttrUnderlineType underlineType = wxTEXT_ATTR_UNDERLINE_NONE; + switch ( cf.bUnderlineType ) + { + case CFU_UNDERLINE: + underlineType = wxTEXT_ATTR_UNDERLINE_SOLID; + break; + case CFU_UNDERLINEDOUBLE: + underlineType = wxTEXT_ATTR_UNDERLINE_DOUBLE; + break; + case CFU_UNDERLINEWAVE: + underlineType = wxTEXT_ATTR_UNDERLINE_WAVE; + break; + } + + wxColour underlineColour = wxNullColour; +#if _RICHEDIT_VER >= 0x0800 + if ( cf.bUnderlineColor == 0 ) + underlineColour = wxNullColour; + else if ( cf.bUnderlineColor == 1 ) + underlineColour = wxTheColourDatabase->Find("BLACK"); + else if ( cf.bUnderlineColor == 2 ) + underlineColour = wxTheColourDatabase->Find("BLUE"); + else if ( cf.bUnderlineColor == 3 ) + underlineColour = wxTheColourDatabase->Find("CYAN"); + else if ( cf.bUnderlineColor == 4 ) + underlineColour = wxTheColourDatabase->Find("GREEN"); + else if ( cf.bUnderlineColor == 5 ) + underlineColour = wxTheColourDatabase->Find("MAGENTA"); + else if ( cf.bUnderlineColor == 6 ) + underlineColour = wxTheColourDatabase->Find("RED"); + else if ( cf.bUnderlineColor == 7 ) + underlineColour = wxTheColourDatabase->Find("YELLOW"); + else if ( cf.bUnderlineColor == 8 ) + underlineColour = wxTheColourDatabase->Find("WHITE"); + else if ( cf.bUnderlineColor == 9 ) + underlineColour = wxColour(0, 0, 128); // navy + else if ( cf.bUnderlineColor == 10 ) + underlineColour = wxTheColourDatabase->Find("TEAL"); + else if ( cf.bUnderlineColor == 11 ) + underlineColour = wxTheColourDatabase->Find("LIGHT GREEN"); + else if ( cf.bUnderlineColor == 12 ) + underlineColour = wxColour(128, 0, 128); // purple + else if ( cf.bUnderlineColor == 13 ) + underlineColour = wxColour(128, 0, 0); // maroon + else if ( cf.bUnderlineColor == 14 ) + underlineColour = wxTheColourDatabase->Find("OLIVE"); + else if ( cf.bUnderlineColor == 15 ) + underlineColour = wxTheColourDatabase->Find("GREY"); + else if ( cf.bUnderlineColor == 16 ) + underlineColour = wxTheColourDatabase->Find("LIGHT GREY"); +#endif + + if ( underlineType != wxTEXT_ATTR_UNDERLINE_NONE ) + style.SetFontUnderlined(underlineType, underlineColour); + // now get the paragraph formatting PARAFORMAT2 pf; wxZeroMemory(pf); diff --git a/src/osx/cocoa/textctrl.mm b/src/osx/cocoa/textctrl.mm index 17c6da0741..344142bd9e 100644 --- a/src/osx/cocoa/textctrl.mm +++ b/src/osx/cocoa/textctrl.mm @@ -1040,6 +1040,8 @@ bool wxNSTextViewControl::GetStyle(long position, wxTextAttr& style) NSFont* font = NULL; NSColor* bgcolor = NULL; NSColor* fgcolor = NULL; + NSNumber* ultype = NULL; + NSColor* ulcolor = NULL; // NOTE: It appears that other platforms accept GetStyle with the position == length // but that NSTextStorage does not accept length as a valid position. // Therefore we return the default control style in that case. @@ -1049,6 +1051,8 @@ bool wxNSTextViewControl::GetStyle(long position, wxTextAttr& style) font = [storage attribute:NSFontAttributeName atIndex:position effectiveRange:NULL]; bgcolor = [storage attribute:NSBackgroundColorAttributeName atIndex:position effectiveRange:NULL]; fgcolor = [storage attribute:NSForegroundColorAttributeName atIndex:position effectiveRange:NULL]; + ultype = [storage attribute:NSUnderlineStyleAttributeName atIndex:position effectiveRange:NULL]; + ulcolor = [storage attribute:NSUnderlineColorAttributeName atIndex:position effectiveRange:NULL]; } else { @@ -1056,6 +1060,8 @@ bool wxNSTextViewControl::GetStyle(long position, wxTextAttr& style) font = [attrs objectForKey:NSFontAttributeName]; bgcolor = [attrs objectForKey:NSBackgroundColorAttributeName]; fgcolor = [attrs objectForKey:NSForegroundColorAttributeName]; + ultype = [attrs objectForKey:NSUnderlineStyleAttributeName]; + ulcolor = [attrs objectForKey:NSUnderlineColorAttributeName]; } if (font) @@ -1066,6 +1072,32 @@ bool wxNSTextViewControl::GetStyle(long position, wxTextAttr& style) if (fgcolor) style.SetTextColour(wxColour(fgcolor)); + + wxTextAttrUnderlineType underlineType = wxTEXT_ATTR_UNDERLINE_NONE; + if ( ultype ) + { + NSInteger ulval = [ultype integerValue]; + switch ( ulval ) + { + case NSUnderlineStyleSingle: + underlineType = wxTEXT_ATTR_UNDERLINE_SOLID; + break; + case NSUnderlineStyleDouble: + underlineType = wxTEXT_ATTR_UNDERLINE_DOUBLE; + break; + case NSUnderlineStyleSingle | NSUnderlinePatternDot: + underlineType = wxTEXT_ATTR_UNDERLINE_WAVE; + break; + } + } + + wxColour underlineColour = wxNullColour; + if ( ulcolor ) + underlineColour = wxColour(ulcolor); + + if ( underlineType != wxTEXT_ATTR_UNDERLINE_NONE ) + style.SetFontUnderlined(underlineType, underlineColour); + return true; } From d2d11dc20575b1a026181f9868ae1d0d77e3d199 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Thu, 18 Jul 2019 22:36:40 +0200 Subject: [PATCH 6/7] Use array to look-up wxMSW underline colours Remove previously added colours from wxColourDatabase. --- src/common/gdicmn.cpp | 3 -- src/msw/textctrl.cpp | 107 ++++++++++++++---------------------------- 2 files changed, 36 insertions(+), 74 deletions(-) diff --git a/src/common/gdicmn.cpp b/src/common/gdicmn.cpp index a7d8980501..0b2d514408 100644 --- a/src/common/gdicmn.cpp +++ b/src/common/gdicmn.cpp @@ -328,7 +328,6 @@ void wxColourDatabase::Initialize() {wxT("INDIAN RED"), 79, 47, 47}, {wxT("KHAKI"), 159, 159, 95}, {wxT("LIGHT BLUE"), 191, 216, 216}, - {wxT("LIGHT GREEN"), 0, 128, 0}, {wxT("LIGHT GREY"), 192, 192, 192}, {wxT("LIGHT STEEL BLUE"), 143, 143, 188}, {wxT("LIME GREEN"), 50, 204, 50}, @@ -348,7 +347,6 @@ void wxColourDatabase::Initialize() {wxT("MEDIUM VIOLET RED"), 219, 112, 147}, {wxT("MIDNIGHT BLUE"), 47, 47, 79}, {wxT("NAVY"), 35, 35, 142}, - {wxT("OLIVE"), 128, 128, 0}, {wxT("ORANGE"), 204, 50, 50}, {wxT("ORANGE RED"), 255, 0, 127}, {wxT("ORCHID"), 219, 112, 219}, @@ -365,7 +363,6 @@ void wxColourDatabase::Initialize() {wxT("SPRING GREEN"), 0, 255, 127}, {wxT("STEEL BLUE"), 35, 107, 142}, {wxT("TAN"), 219, 147, 112}, - {wxT("TEAL"), 0, 128, 128}, {wxT("THISTLE"), 216, 191, 216}, {wxT("TURQUOISE"), 173, 234, 234}, {wxT("VIOLET"), 79, 47, 79}, diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index b77446a5dd..8933f7b803 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -2812,6 +2812,30 @@ bool wxTextCtrl::SetFont(const wxFont& font) // styling support for rich edit controls // ---------------------------------------------------------------------------- +#if _RICHEDIT_VER >= 0x0800 +static const wxColour gs_underlineColourMap[] = +{ + // The colours are coming from https://docs.microsoft.com/en-us/windows/desktop/api/tom/nf-tom-itextdocument2-geteffectcolor. + wxNullColour, // text colour + wxColour(0, 0, 0 ), // black + wxColour(0, 0, 255), // blue + wxColour(0, 255, 255), // cyan + wxColour(0, 255, 0 ), // green + wxColour(255, 0, 255), // magenta + wxColour(255, 0, 0 ), // red + wxColour(255, 255, 0 ), // yellow + wxColour(255, 255, 255), // white + wxColour(0, 0, 128), // navy + wxColour(0, 128, 128), // teal + wxColour(0, 128, 0 ), // light green + wxColour(128, 0, 128), // purple + wxColour(128, 0, 0 ), // maroon + wxColour(128, 128, 0 ), // olive + wxColour(128, 128, 128), // grey + wxColour(192, 192, 192), // light grey +}; +#endif + bool wxTextCtrl::MSWSetCharFormat(const wxTextAttr& style, long start, long end) { // initialize CHARFORMAT struct @@ -2903,43 +2927,16 @@ bool wxTextCtrl::MSWSetCharFormat(const wxTextAttr& style, long start, long end) } #if _RICHEDIT_VER >= 0x0800 - // The colours are coming from https://docs.microsoft.com/en-us/windows/desktop/api/tom/nf-tom-itextdocument2-geteffectcolor. BYTE colour = 0; - wxColour col = style.GetUnderlineColour(); - if ( col == wxNullColour ) - colour = 0; - else if ( col == wxTheColourDatabase->Find("BLACK") ) - colour = 1; - else if ( col == wxTheColourDatabase->Find("BLUE") ) - colour = 2; - else if ( col == wxTheColourDatabase->Find("CYAN") ) - colour = 3; - else if ( col == wxTheColourDatabase->Find("GREEN") ) - colour = 4; - else if ( col == wxTheColourDatabase->Find("MAGENTA") ) - colour = 5; - else if ( col == wxTheColourDatabase->Find("RED") ) - colour = 6; - else if ( col == wxTheColourDatabase->Find("YELLOW") ) - colour = 7; - else if ( col == wxTheColourDatabase->Find("WHITE") ) - colour = 8; - else if ( col == wxColour(0, 0, 128) ) // navy - colour = 9; - else if ( col == wxTheColourDatabase->Find("TEAL") ) - colour = 10; - else if ( col == wxTheColourDatabase->Find("LIGHT GREEN") ) - colour = 11; - else if ( col == wxColour(128, 0, 128) ) // purple - colour = 12; - else if ( col == wxColour(128, 0, 0) ) // maroon - colour = 13; - else if ( col == wxTheColourDatabase->Find("OLIVE") ) - colour = 14; - else if ( col == wxTheColourDatabase->Find("GREY") ) - colour = 15; - else if ( col == wxTheColourDatabase->Find("LIGHT GREY") ) - colour = 16; + const wxColour& col = style.GetUnderlineColour(); + for ( size_t c = 0; c < WXSIZEOF(gs_underlineColourMap); ++c ) + { + if ( col == gs_underlineColourMap[c] ) + { + colour = static_cast(c); + break; + } + } cf.bUnderlineColor = colour; #endif } @@ -3273,42 +3270,10 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style) break; } - wxColour underlineColour = wxNullColour; + wxColour underlineColour; #if _RICHEDIT_VER >= 0x0800 - if ( cf.bUnderlineColor == 0 ) - underlineColour = wxNullColour; - else if ( cf.bUnderlineColor == 1 ) - underlineColour = wxTheColourDatabase->Find("BLACK"); - else if ( cf.bUnderlineColor == 2 ) - underlineColour = wxTheColourDatabase->Find("BLUE"); - else if ( cf.bUnderlineColor == 3 ) - underlineColour = wxTheColourDatabase->Find("CYAN"); - else if ( cf.bUnderlineColor == 4 ) - underlineColour = wxTheColourDatabase->Find("GREEN"); - else if ( cf.bUnderlineColor == 5 ) - underlineColour = wxTheColourDatabase->Find("MAGENTA"); - else if ( cf.bUnderlineColor == 6 ) - underlineColour = wxTheColourDatabase->Find("RED"); - else if ( cf.bUnderlineColor == 7 ) - underlineColour = wxTheColourDatabase->Find("YELLOW"); - else if ( cf.bUnderlineColor == 8 ) - underlineColour = wxTheColourDatabase->Find("WHITE"); - else if ( cf.bUnderlineColor == 9 ) - underlineColour = wxColour(0, 0, 128); // navy - else if ( cf.bUnderlineColor == 10 ) - underlineColour = wxTheColourDatabase->Find("TEAL"); - else if ( cf.bUnderlineColor == 11 ) - underlineColour = wxTheColourDatabase->Find("LIGHT GREEN"); - else if ( cf.bUnderlineColor == 12 ) - underlineColour = wxColour(128, 0, 128); // purple - else if ( cf.bUnderlineColor == 13 ) - underlineColour = wxColour(128, 0, 0); // maroon - else if ( cf.bUnderlineColor == 14 ) - underlineColour = wxTheColourDatabase->Find("OLIVE"); - else if ( cf.bUnderlineColor == 15 ) - underlineColour = wxTheColourDatabase->Find("GREY"); - else if ( cf.bUnderlineColor == 16 ) - underlineColour = wxTheColourDatabase->Find("LIGHT GREY"); + if ( cf.bUnderlineColor < WXSIZEOF(gs_underlineColourMap) ) + underlineColour = gs_underlineColourMap[cf.bUnderlineColor]; #endif if ( underlineType != wxTEXT_ATTR_UNDERLINE_NONE ) From cd7e21ad2b8504933bbb5effdd32f91857199557 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Thu, 18 Jul 2019 23:08:00 +0200 Subject: [PATCH 7/7] Apply wxTextCtrl underline review suggestions --- include/wx/textctrl.h | 2 +- interface/wx/textctrl.h | 25 +++++++++++++++------- samples/text/text.cpp | 2 +- src/gtk/textctrl.cpp | 15 +++++++------ src/msw/textctrl.cpp | 21 +++++++++++------- src/osx/cocoa/textctrl.mm | 45 ++++++++++++++++++++------------------- 6 files changed, 64 insertions(+), 46 deletions(-) diff --git a/include/wx/textctrl.h b/include/wx/textctrl.h index 693529bab4..22792af375 100644 --- a/include/wx/textctrl.h +++ b/include/wx/textctrl.h @@ -275,7 +275,7 @@ enum wxTextAttrUnderlineType wxTEXT_ATTR_UNDERLINE_NONE, wxTEXT_ATTR_UNDERLINE_SOLID, wxTEXT_ATTR_UNDERLINE_DOUBLE, - wxTEXT_ATTR_UNDERLINE_WAVE + wxTEXT_ATTR_UNDERLINE_SPECIAL }; // ---------------------------------------------------------------------------- diff --git a/interface/wx/textctrl.h b/interface/wx/textctrl.h index c26277e553..1b2d509d70 100644 --- a/interface/wx/textctrl.h +++ b/interface/wx/textctrl.h @@ -229,7 +229,7 @@ enum wxTextAttrUnderlineType wxTEXT_ATTR_UNDERLINE_NONE, wxTEXT_ATTR_UNDERLINE_SOLID, wxTEXT_ATTR_UNDERLINE_DOUBLE, - wxTEXT_ATTR_UNDERLINE_WAVE + wxTEXT_ATTR_UNDERLINE_SPECIAL }; /** @@ -830,20 +830,29 @@ public: void SetFontStyle(wxFontStyle fontStyle); /** - Sets the font underlining (solid line, using text colour). + Sets the font underlining (solid line, text colour). */ void SetFontUnderlined(bool underlined); /** - Sets the font underlining with a wxTextAttrUnderlineType and wxColour. - Specifying wxNullColour will use the text colour. + Sets the font underlining. - @note On wxMSW, wxTEXT_ATTR_UNDERLINE_DOUBLE is shown as wxTEXT_ATTR_UNDERLINE_SOLID. There is only a limited number of colours supported, - the RGB values are listed here. + @param type Type of underline. - @note On wxGTK, underline colour is only supported by wxGTK3. GTK might overrule the colour of wxTEXT_ATTR_UNDERLINE_WAVE. + @param colour Colour to use for underlining, text colour is used by + default. - @note On wxOSX, wxTEXT_ATTR_UNDERLINE_WAVE is shown as a dotted line. + @note On wxMSW, wxTEXT_ATTR_UNDERLINE_DOUBLE is shown as + wxTEXT_ATTR_UNDERLINE_SOLID. There is only a limited number of colours + supported, the RGB values are listed + here. + wxTEXT_ATTR_UNDERLINE_SPECIAL is shown as a waved line. + + @note On wxGTK, underline colour is only supported by wxGTK3. + wxTEXT_ATTR_UNDERLINE_SPECIAL is shown as a waved line. GTK might + overrule the colour of wxTEXT_ATTR_UNDERLINE_SPECIAL. + + @note On wxOSX, wxTEXT_ATTR_UNDERLINE_SPECIAL is shown as a dotted line. @since 3.1.3 */ diff --git a/samples/text/text.cpp b/samples/text/text.cpp index f5df4e4045..f4ee6f9038 100644 --- a/samples/text/text.cpp +++ b/samples/text/text.cpp @@ -1237,7 +1237,7 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h ) attr.SetFontUnderlined(false); m_textrich->SetDefaultStyle(attr); m_textrich->AppendText(" is a "); - attr.SetFontUnderlined(wxTEXT_ATTR_UNDERLINE_WAVE, *wxRED); + attr.SetFontUnderlined(wxTEXT_ATTR_UNDERLINE_SPECIAL, *wxRED); m_textrich->SetDefaultStyle(attr); m_textrich->AppendText("mispeled"); attr.SetFontUnderlined(false); diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index a61369ec02..149d00f880 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -126,21 +126,21 @@ static void wxGtkTextApplyTagsFromAttr(GtkWidget *text, if ( attr.HasFontUnderlined() ) { - PangoUnderline pangoUnderlineStyle; + PangoUnderline pangoUnderlineStyle = PANGO_UNDERLINE_NONE; switch ( attr.GetUnderlineType() ) { - case wxTEXT_ATTR_UNDERLINE_NONE: - pangoUnderlineStyle = PANGO_UNDERLINE_NONE; - break; case wxTEXT_ATTR_UNDERLINE_SOLID: pangoUnderlineStyle = PANGO_UNDERLINE_SINGLE; break; case wxTEXT_ATTR_UNDERLINE_DOUBLE: pangoUnderlineStyle = PANGO_UNDERLINE_DOUBLE; break; - case wxTEXT_ATTR_UNDERLINE_WAVE: + case wxTEXT_ATTR_UNDERLINE_SPECIAL: pangoUnderlineStyle = PANGO_UNDERLINE_ERROR; break; + default: + pangoUnderlineStyle = PANGO_UNDERLINE_NONE; + break; } g_snprintf(buf, sizeof(buf), "WXFONTUNDERLINESTYLE %u", @@ -1922,7 +1922,10 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style) underlineType = wxTEXT_ATTR_UNDERLINE_DOUBLE; break; case PANGO_UNDERLINE_ERROR: - underlineType = wxTEXT_ATTR_UNDERLINE_WAVE; + underlineType = wxTEXT_ATTR_UNDERLINE_SPECIAL; + break; + default: + underlineType = wxTEXT_ATTR_UNDERLINE_NONE; break; } diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 8933f7b803..4156aa7bcd 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -2910,21 +2910,23 @@ bool wxTextCtrl::MSWSetCharFormat(const wxTextAttr& style, long start, long end) if ( style.HasFontUnderlined() ) { cf.dwMask |= CFM_UNDERLINETYPE; + BYTE underlineType = CFU_UNDERLINENONE; switch ( style.GetUnderlineType() ) { - case wxTEXT_ATTR_UNDERLINE_NONE: - cf.bUnderlineType = CFU_UNDERLINENONE; - break; case wxTEXT_ATTR_UNDERLINE_SOLID: - cf.bUnderlineType = CFU_UNDERLINE; + underlineType = CFU_UNDERLINE; break; case wxTEXT_ATTR_UNDERLINE_DOUBLE: - cf.bUnderlineType = CFU_UNDERLINEDOUBLE; + underlineType = CFU_UNDERLINEDOUBLE; break; - case wxTEXT_ATTR_UNDERLINE_WAVE: - cf.bUnderlineType = CFU_UNDERLINEWAVE; + case wxTEXT_ATTR_UNDERLINE_SPECIAL: + underlineType = CFU_UNDERLINEWAVE; + break; + default: + underlineType = CFU_UNDERLINENONE; break; } + cf.bUnderlineType = underlineType; #if _RICHEDIT_VER >= 0x0800 BYTE colour = 0; @@ -3266,7 +3268,10 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style) underlineType = wxTEXT_ATTR_UNDERLINE_DOUBLE; break; case CFU_UNDERLINEWAVE: - underlineType = wxTEXT_ATTR_UNDERLINE_WAVE; + underlineType = wxTEXT_ATTR_UNDERLINE_SPECIAL; + break; + default: + underlineType = wxTEXT_ATTR_UNDERLINE_NONE; break; } diff --git a/src/osx/cocoa/textctrl.mm b/src/osx/cocoa/textctrl.mm index 344142bd9e..27581dae19 100644 --- a/src/osx/cocoa/textctrl.mm +++ b/src/osx/cocoa/textctrl.mm @@ -1086,12 +1086,15 @@ bool wxNSTextViewControl::GetStyle(long position, wxTextAttr& style) underlineType = wxTEXT_ATTR_UNDERLINE_DOUBLE; break; case NSUnderlineStyleSingle | NSUnderlinePatternDot: - underlineType = wxTEXT_ATTR_UNDERLINE_WAVE; + underlineType = wxTEXT_ATTR_UNDERLINE_SPECIAL; + break; + default: + underlineType = wxTEXT_ATTR_UNDERLINE_NONE; break; } } - wxColour underlineColour = wxNullColour; + wxColour underlineColour; if ( ulcolor ) underlineColour = wxColour(ulcolor); @@ -1123,24 +1126,23 @@ void wxNSTextViewControl::SetStyle(long start, [attrs setValue:style.GetTextColour().OSXGetNSColor() forKey:NSForegroundColorAttributeName]; if ( style.HasFontUnderlined() ) { + int underlineStyle = NSUnderlineStyleNone; switch ( style.GetUnderlineType() ) { - case wxTEXT_ATTR_UNDERLINE_NONE: - [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleNone )] forKey:NSUnderlineStyleAttributeName]; - break; - case wxTEXT_ATTR_UNDERLINE_SOLID: - [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle )] forKey:NSUnderlineStyleAttributeName]; + underlineStyle = NSUnderlineStyleSingle; break; - case wxTEXT_ATTR_UNDERLINE_DOUBLE: - [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleDouble )] forKey:NSUnderlineStyleAttributeName]; + underlineStyle = NSUnderlineStyleDouble; break; - - case wxTEXT_ATTR_UNDERLINE_WAVE: - [attrs setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle | NSUnderlinePatternDot )] forKey:NSUnderlineStyleAttributeName]; + case wxTEXT_ATTR_UNDERLINE_SPECIAL: + underlineStyle = NSUnderlineStyleSingle | NSUnderlinePatternDot; + break; + default: + underlineStyle = NSUnderlineStyleNone; break; } + [attrs setObject:[NSNumber numberWithInt:( underlineStyle )] forKey:NSUnderlineStyleAttributeName]; wxColour colour = style.GetUnderlineColour(); if ( colour.IsOk() ) { @@ -1166,24 +1168,23 @@ void wxNSTextViewControl::SetStyle(long start, if( style.HasFontUnderlined() ) { NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; + int underlineStyle = NSUnderlineStyleNone; switch ( style.GetUnderlineType() ) { - case wxTEXT_ATTR_UNDERLINE_NONE: - [dict setObject:[NSNumber numberWithInt:( NSUnderlineStyleNone )] forKey:NSUnderlineStyleAttributeName]; - break; - case wxTEXT_ATTR_UNDERLINE_SOLID: - [dict setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle )] forKey:NSUnderlineStyleAttributeName]; + underlineStyle = NSUnderlineStyleSingle; break; - case wxTEXT_ATTR_UNDERLINE_DOUBLE: - [dict setObject:[NSNumber numberWithInt:( NSUnderlineStyleDouble )] forKey:NSUnderlineStyleAttributeName]; + underlineStyle = NSUnderlineStyleDouble; break; - - case wxTEXT_ATTR_UNDERLINE_WAVE: - [dict setObject:[NSNumber numberWithInt:( NSUnderlineStyleSingle | NSUnderlinePatternDot )] forKey:NSUnderlineStyleAttributeName]; + case wxTEXT_ATTR_UNDERLINE_SPECIAL: + underlineStyle = NSUnderlineStyleSingle | NSUnderlinePatternDot; + break; + default: + underlineStyle = NSUnderlineStyleNone; break; } + [dict setObject:[NSNumber numberWithInt:( underlineStyle )] forKey:NSUnderlineStyleAttributeName]; wxColour colour = style.GetUnderlineColour(); if ( colour.IsOk() ) {