From 97de613b61e9a1684aa6e8ec6d14fd7e6080aa4b Mon Sep 17 00:00:00 2001 From: cxl Date: Thu, 28 Mar 2013 10:11:49 +0000 Subject: [PATCH] CtrlLib: EditField ShowSpaces, WhenHighlight, RichEdit: SpellCheck made public git-svn-id: svn://ultimatepp.org/upp/trunk@5930 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CtrlLib/EditCtrl.h | 14 +++++++---- uppsrc/CtrlLib/EditField.cpp | 29 +++++++++++++--------- uppsrc/CtrlLib/src.tpp/EditField$en-us.tpp | 20 ++++++++++++++- uppsrc/RichEdit/RichEdit.h | 3 ++- uppsrc/RichEdit/Speller.cpp | 9 +++++-- 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/uppsrc/CtrlLib/EditCtrl.h b/uppsrc/CtrlLib/EditCtrl.h index 00ce331ab..ddb0ca13c 100644 --- a/uppsrc/CtrlLib/EditCtrl.h +++ b/uppsrc/CtrlLib/EditCtrl.h @@ -97,8 +97,9 @@ public: struct Highlight : Moveable { Color ink; Color paper; + bool error; - bool operator!=(const Highlight& b) const { return ink != b.ink || paper != b.paper; } + bool operator!=(const Highlight& b) const { return ink != b.ink || paper != b.paper || error != b.error; } }; protected: @@ -138,6 +139,7 @@ protected: bool nobg:1; bool alignright:1; bool errorbg:1; + bool showspaces:1; bool FrameIsEdge(); void SetEdge(int i); @@ -146,7 +148,7 @@ protected: int GetCharWidth(int c) const { return font[c < 32 ? LowChar(c) : c]; } int GetTextCx(const wchar *text, int n, bool password, Font fnt) const; void Paints(Draw& w, int& x, int fcy, const wchar *&txt, - Color ink, Color paper, int n, bool pwd, Font fnt); + Color ink, Color paper, int n, bool pwd, Font fnt, bool error, bool showspaces); int GetStringCx(const wchar *text, int n); int GetCaret(int cursor) const; int GetCursor(int posx); @@ -161,9 +163,10 @@ protected: virtual void HighlightText(Vector& hl); public: - Callback1 WhenBar; - Callback WhenEnter; - Callback1 WhenPasteFilter; + Callback1 WhenBar; + Callback WhenEnter; + Callback1 WhenPasteFilter; + Callback1&> WhenHighlight; static const Style& StyleDefault(); EditField& SetStyle(const Style& s); @@ -241,6 +244,7 @@ public: EditField& AlignRight(bool b = true) { alignright = b; Refresh(); return *this; } bool IsNoBackground() const { return nobg; } bool IsAlignRight() const { return alignright; } + EditField& ShowSpaces(bool b = true) { showspaces = b; Refresh(); return *this; } CharFilter GetFilter() const { return filter; } const Convert& GetConvert() const { return *convert; } diff --git a/uppsrc/CtrlLib/EditField.cpp b/uppsrc/CtrlLib/EditField.cpp index 9afa75949..8ee1a54bc 100644 --- a/uppsrc/CtrlLib/EditField.cpp +++ b/uppsrc/CtrlLib/EditField.cpp @@ -255,10 +255,11 @@ int EditField::GetTy() const void EditField::HighlightText(Vector& hl) { + WhenHighlight(hl); } void EditField::Paints(Draw& w, int& x, int fcy, const wchar *&txt, - Color ink, Color paper, int n, bool password, Font fnt) + Color ink, Color paper, int n, bool password, Font fnt, bool error, bool showspaces) { if(n < 0) return; int cx = GetTextCx(txt, n, password, font); @@ -280,7 +281,18 @@ void EditField::Paints(Draw& w, int& x, int fcy, const wchar *&txt, *t++ = *q < 32 ? LowChar(*q) : *q; txts = ~h; } + if(error) + w.DrawRect(x, fnt.GetAscent() + 1, cx, 1, LtRed()); w.DrawText(x, 0, txts, fnt, ink, n); + if(showspaces) { + int xx = x; + Size sz = GetTextSize(" ", fnt) / 2; + for(const wchar *q = txts; q < e; q++) { + if(*q == ' ') + w.DrawRect(xx + sz.cx, sz.cy, 2, 2, Blend(SColorHighlight(), SColorPaper())); + xx += fnt[*q]; + } + } } txt += n; x += cx; @@ -313,7 +325,7 @@ void EditField::Paint(Draw& w) w.DrawImage(x, (fcy - nullicon.GetHeight()) / 2, nullicon); x += icx + 4; } - Paints(w, x, fcy, txt, nullink, paper, nulltext.GetLength(), false, nullfont); + Paints(w, x, fcy, txt, nullink, paper, nulltext.GetLength(), false, nullfont, false, false); } else { const wchar *txt = text; @@ -327,6 +339,7 @@ void EditField::Paint(Draw& w) for(int i = 0; i < len; i++) { hl[i].ink = ink; hl[i].paper = paper; + hl[i].error = false; } HighlightText(hl); len = hl.GetCount(); @@ -341,18 +354,9 @@ void EditField::Paint(Draw& w) int b = 0; for(int i = 0; i <= len; i++) if((i == len || hl[i] != hl[b]) && b < len) { - Paints(w, x, fcy, txt, hl[b].ink, hl[b].paper, i - b, password, font); + Paints(w, x, fcy, txt, hl[b].ink, hl[b].paper, i - b, password, font, hl[b].error, showspaces); b = i; } -/* if(GetSelection(l, h)) { - Paints(w, x, fcy, txt, ink, paper, l, password, font); - Paints(w, x, fcy, txt, enabled ? style->selectedtext : paper, - enabled ? style->selected : ink, h - l, password, font); - Paints(w, x, fcy, txt, ink, paper, text.GetLength() - h, password, font); - } - else - Paints(w, x, fcy, txt, ink, paper, text.GetLength(), password, font); -*/ } if(!ar) w.DrawRect(x, 0, 9999, fcy, paper); @@ -1022,6 +1026,7 @@ void EditField::Reset() SetStyle(StyleDefault()); SetFrame(edge); font = StdFont(); + showspaces = false; } EditField& EditField::SetFont(Font _font) diff --git a/uppsrc/CtrlLib/src.tpp/EditField$en-us.tpp b/uppsrc/CtrlLib/src.tpp/EditField$en-us.tpp index e24591597..2bc27906a 100644 --- a/uppsrc/CtrlLib/src.tpp/EditField$en-us.tpp +++ b/uppsrc/CtrlLib/src.tpp/EditField$en-us.tpp @@ -44,6 +44,13 @@ t]([_^Font^ Font]_[*@3 font]_`=_StdFont())&] used for edited text, including the standard static frame.&] [s3; &] [s4; &] +[s5;:EditField`:`:HighlightText`(Vector``&`): [@(0.0.255) virt +ual] [@(0.0.255) void]_[* HighlightText]([_^Vector^ Vector]<[_^EditField`:`:Highlight^ Hi +ghlight]>`&_[*@3 hl])&] +[s2;%% Provides a chance to change the text color and background +for individual characters.&] +[s3; &] +[s4; &] [s5;:EditField`:`:WhenBar: [_^Callback1^ Callback1]_[* WhenBar]&] [s2;%% This callback represents the context menu of EditField. The default is StdBar.&] @@ -62,6 +69,13 @@ and can be used to alter the text to be pasted. Default is no change to the text.&] [s3; &] [s4; &] +[s5;:EditField`:`:WhenHighlight: [_^Callback1^ Callback1]<[_^Vector^ Vector]<[_^EditField`:`:Highlight^ H +ighlight]>`&>_[* WhenHighlight]&] +[s2;%% Called by default implementation of HighlightText. Provides +a chance to change the text color and background for individual +characters.&] +[s3; &] +[s4; &] [s5;:EditField`:`:Insert`(int`,const WString`&`): [@(0.0.255) int]_[* Insert]([@(0.0.255) i nt]_[*@3 pos], [@(0.0.255) const]_[_^WString^ WString][@(0.0.255) `&]_[*@3 text])&] [s2;%% [%- Inserts ][%-*@3 text] at [%-*@3 pos].&] @@ -367,6 +381,11 @@ onst]&] [s2;%% Returns true if AlignRight is active.&] [s3; &] [s4; &] +[s5;:EditField`:`:ShowSpaces`(bool`): [@(0.0.255) bool]_[* ShowSpaces]([@(0.0.255) bool]_[*@3 b +]_`=_[@(0.0.255) true])&] +[s2;%% When active, EditField paints blue dots to show spaces.&] +[s3;%% &] +[s4; &] [s5;:EditField`:`:GetChar`(int`)const: [@(0.0.255) virtual] [@(0.0.255) int]_[* GetChar]([@(0.0.255) i nt]_[*@3 i])_[@(0.0.255) const]&] [s2;%% Returns the character at [%-*@3 i] index.&] @@ -398,5 +417,4 @@ tyle][@(0.0.255) `&]_[* StyleDefault]()&] [s1;:EditField`:`:Style`:`:struct: [@(0.0.255)3 struct][3 _][*3 Style][3 _:_][@(0.0.255)3 public ][3 _][*@3;3 ChStyle][@(0.0.255)3 <][*3 Style][@(0.0.255)3 >][3 _]&] [s9;%% This structure defines the visual style of an EditField.&] -[s3; &] [s0; ]] \ No newline at end of file diff --git a/uppsrc/RichEdit/RichEdit.h b/uppsrc/RichEdit/RichEdit.h index 150369207..3aece8cf2 100644 --- a/uppsrc/RichEdit/RichEdit.h +++ b/uppsrc/RichEdit/RichEdit.h @@ -189,6 +189,8 @@ public: }; bool SpellWordRaw(const WString& wrd, int lang, Vector *withdia = NULL); +bool SpellWord(const wchar *ws, int len, int lang); +bool SpellWord(const WString& ws, int lang); class RichEdit : public Ctrl, private TextArrayOps { public: @@ -614,7 +616,6 @@ private: void UserAction(); Callback User(Callback cb); - static bool SpellWord(const wchar *wrd, int len, int lang); static void SpellerAdd(const WString& w, int lang); static int CompareStyle(const Value& a, const Value& b); diff --git a/uppsrc/RichEdit/Speller.cpp b/uppsrc/RichEdit/Speller.cpp index db5a3bc7f..d1007dda4 100644 --- a/uppsrc/RichEdit/Speller.cpp +++ b/uppsrc/RichEdit/Speller.cpp @@ -258,15 +258,20 @@ struct SpellMaker : LRUCache::Maker { static LRUCache speller_cache; -bool RichEdit::SpellWord(const wchar *ws, int len, int lang) +bool SpellWord(const WString& ws, int lang) { speller_cache.Shrink(2000); SpellMaker m; m.k.lang = lang; - m.k.wrd = WString(ws, len); + m.k.wrd = ws; return speller_cache.Get(m); } +bool SpellWord(const wchar *ws, int len, int lang) +{ + return SpellWord(WString(ws, len), lang); +} + void RichEdit::SpellerAdd(const WString& w, int lang) { if(!SpellWord(w, w.GetCount(), lang)) {