#320 Textare is finished 4.x-dev

Mon, 07 Jun 2021 20:56:13 +0300

author
cemkalyoncu
date
Mon, 07 Jun 2021 20:56:13 +0300
branch
4.x-dev
changeset 1693
b7e471ab6eed
parent 1692
f666ff6c4671
child 1694
81a7134f0140

#320 Textare is finished

Source/Gorgon/Widgets/Textarea.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Textarea.h file | annotate | diff | comparison | revisions
Testing/Source/Manual/UI_WidgetTest.cpp file | annotate | diff | comparison | revisions
--- a/Source/Gorgon/Widgets/Textarea.cpp	Sun Jun 06 17:44:07 2021 +0300
+++ b/Source/Gorgon/Widgets/Textarea.cpp	Mon Jun 07 20:56:13 2021 +0300
@@ -9,6 +9,7 @@
         ScrollingWidget(temp),
         PropType(helper),
         AutoSelectAll(this),
+        WordWrap(this),
         Readonly(this)
     {
         overscroll = temp.GetSpacing() * 4;
@@ -36,6 +37,8 @@
         repeater.Register(Input::Keyboard::Keycodes::Right);
         repeater.Register(Input::Keyboard::Keycodes::Down);
         repeater.Register(Input::Keyboard::Keycodes::Up);
+        repeater.Register(Input::Keyboard::Keycodes::PageDown);
+        repeater.Register(Input::Keyboard::Keycodes::PageUp);
         repeater.Register(Input::Keyboard::Keycodes::Backspace);
         repeater.Register(Input::Keyboard::Keycodes::Delete);
         repeater.Register(Input::Keyboard::Keycodes::Enter);
@@ -150,6 +153,26 @@
 
                     updateselection();
                 }
+                else if(key == Input::Keyboard::Keycodes::PageUp) {
+                    glyphbyte selprev = selstart;
+                    sellen = {0, 0};
+                    
+                    moveselpageup();
+                    sellen = {selstart.glyph - selprev.glyph, selstart.byte - selprev.byte};
+                    selstart = selprev;
+
+                    updateselection();
+                }
+                else if(key == Input::Keyboard::Keycodes::PageDown) {
+                    glyphbyte selprev = selstart;
+                    sellen = {0, 0};
+                    
+                    moveselpagedown();
+                    sellen = {selstart.glyph - selprev.glyph, selstart.byte - selprev.byte};
+                    selstart = selprev;
+
+                    updateselection();
+                }
             }
             else if(Input::Keyboard::CurrentModifier == Modifier::None) {
 
@@ -216,6 +239,14 @@
                         moveseldown();
                         updateselection();
                     }
+                    else if(key == Keycodes::PageUp) {
+                        moveselpageup();
+                        updateselection();
+                    }
+                    else if(key == Keycodes::PageDown) {
+                        moveselpagedown();
+                        updateselection();
+                    }
                 }
             }
         });
@@ -289,6 +320,16 @@
                     SelectAll();
 
                     return true;
+                    
+                case Keycodes::Home: 
+                    selstart = {0, 0};
+                    updateselection();
+                    return true;
+                    
+                case Keycodes::End:
+                    selstart = selstart = {Length(), (int)text.size()};
+                    updateselection();
+                    return true;
 
                 case Keycodes::C: {
                     std::string s = GetSelectedText();
@@ -377,7 +418,7 @@
         std::cout << selstart.glyph << " : " << sellen.glyph << std::endl;
         updatecursor();
         
-        if(sellen.byte != 0) {
+        if(sellen.byte != 0 && IsFocused()) {
             auto s = selstart.byte;
             auto e = s + sellen.byte;
             
@@ -391,7 +432,7 @@
             nw += text.substr(e);
             stack.SetData(UI::ComponentTemplate::Text, nw);
             selectionin = true;
-        }        
+        }
         else if(selectionin) {
             stack.SetData(UI::ComponentTemplate::Text, text);
             selectionin = false;
@@ -418,6 +459,8 @@
                 dirty = false;
             }
         }
+        
+        updateselection();
     }
     
     void Textarea::mousedown(UI::ComponentTemplate::Tag, Geometry::Point location, Input::Mouse::Button button) { 
@@ -532,7 +575,7 @@
     void Textarea::moveselup() {
         auto bounds = stack.TagBounds(UI::ComponentTemplate::ContentsTag);
         selstart.glyph = printer->GetCharacterIndex(
-            text, bounds.GetSize().Width, Geometry::Point{cursorlocation.X, cursorlocation.Y-1} + ScrollOffset(), wrap
+            text, bounds.GetSize().Width, Geometry::Point{cursorlocation.X, cursorlocation.Y-1}, wrap
         );
         selstart.byte = getbyteoffset(selstart.glyph);
         sellen = {0, 0};
@@ -542,7 +585,7 @@
     void Textarea::moveseldown() {
         auto bounds = stack.TagBounds(UI::ComponentTemplate::ContentsTag);
         selstart.glyph = printer->GetCharacterIndex(
-            text, bounds.GetSize().Width, Geometry::Point{cursorlocation.X, cursorlocation.Y+1+printer->GetHeight()} + ScrollOffset(), wrap
+            text, bounds.GetSize().Width, Geometry::Point{cursorlocation.X, cursorlocation.Y+1+printer->GetHeight()}, wrap
         );
         selstart.byte = getbyteoffset(selstart.glyph);
         sellen = {0, 0};
@@ -550,6 +593,27 @@
     }
 
 
+    void Textarea::moveselpageup() {
+        auto bounds = stack.TagBounds(UI::ComponentTemplate::ContentsTag);
+        auto mysize = stack.TagBounds(UI::ComponentTemplate::ViewPortTag).GetSize();
+        selstart.glyph = printer->GetCharacterIndex(
+            text, bounds.GetSize().Width, Geometry::Point{cursorlocation.X, cursorlocation.Y+1+printer->GetHeight()-mysize.Height}, wrap
+        );
+        selstart.byte = getbyteoffset(selstart.glyph);
+        sellen = {0, 0};
+        updateselection();
+    }
+
+    void Textarea::moveselpagedown() {
+        auto bounds = stack.TagBounds(UI::ComponentTemplate::ContentsTag);
+        auto mysize = stack.TagBounds(UI::ComponentTemplate::ViewPortTag).GetSize();
+        selstart.glyph = printer->GetCharacterIndex(
+            text, bounds.GetSize().Width, Geometry::Point{cursorlocation.X, cursorlocation.Y-printer->GetHeight()+mysize.Height}, wrap
+        );
+        selstart.byte = getbyteoffset(selstart.glyph);
+        sellen = {0, 0};
+        updateselection();
+    }
 
     void Textarea::SetReadonly(const bool& value) {
         if(value == readonly)
@@ -566,9 +630,6 @@
     }
 
     bool Textarea::Done() {
-        if(autoselectall)
-            SelectAll();
-        
         if(!dirty)
             return true;
 
@@ -627,24 +688,23 @@
         else
             pos += sellen.glyph;
         
-        auto pcurloc = cursorlocation;
         if(text == "") {
             cursorlocation = {0, 0};
         }
         else {
-            cursorlocation = printer->GetPosition(text, stack.TagBounds(UI::ComponentTemplate::ContentsTag).Width(), pos, wrap).TopLeft() - scrolloffset;
+            cursorlocation = printer->GetPosition(text, stack.TagBounds(UI::ComponentTemplate::ContentsTag).Width(), pos, wrap).TopLeft();
         }
         
         if(text == "") {
             stack.RemoveTagLocation(UI::ComponentTemplate::CaretTag);
         }
         else {
-            stack.SetTagLocation(UI::ComponentTemplate::CaretTag, {cursorlocation.X, cursorlocation.Y});
+            stack.SetTagLocation(UI::ComponentTemplate::CaretTag, Geometry::Point{cursorlocation.X, cursorlocation.Y} - scrolloffset);
         }
         
         if(pos != curcursorpos) {
             curcursorpos = pos;
-            ensurevisible({cursorlocation + scrolloffset, 0, printer->GetHeight()});
+            ensurevisible({cursorlocation, 0, printer->GetHeight()});
         }
     }
     
@@ -682,4 +742,24 @@
         return byte;
     }
 
+
+    void Textarea::SetWordWrap(const bool &value) {
+        if(wrap == value)
+            return;
+        
+        wrap = value;
+        if(wrap) {
+            stack.EnableTagWrap(UI::ComponentTemplate::ContentsTag);
+        }
+        else
+            stack.DisableTagWrap(UI::ComponentTemplate::ContentsTag);
+        
+        enablescroll(true, !wrap);
+        updateselection();
+        updatebars();
+        
+        if(wrap)
+            ScrollTo(0, ScrollOffset().Y);
+    }
+
 } }
--- a/Source/Gorgon/Widgets/Textarea.h	Sun Jun 06 17:44:07 2021 +0300
+++ b/Source/Gorgon/Widgets/Textarea.h	Mon Jun 07 20:56:13 2021 +0300
@@ -219,6 +219,13 @@
             return readonly;
         }
         
+        void SetWordWrap(const bool &value);
+        
+        
+        bool GetWordWrap() const {
+            return wrap;
+        }
+        
 
         /// Controls if the inputbox will be auto selected recieving focus
         /// or right after the user is done with editing. Default is false.
@@ -226,6 +233,12 @@
                         &Textarea::GetAutoSelectAll, 
                         &Textarea::SetAutoSelectAll> AutoSelectAll;
         
+        /// Controls if the text in the text area will be wrapped. Disabling wordwrap will enable
+        /// horizontal scroll
+        BooleanProperty< Textarea, bool, 
+                        &Textarea::GetWordWrap, 
+                        &Textarea::SetWordWrap> WordWrap;
+        
         /// When set to true, the value contained in the inputbox cannot be edited
         /// by the user. Default is false.
         BooleanProperty< Textarea, bool, 
@@ -265,6 +278,10 @@
         void moveselup();
         
         void moveseldown();
+        
+        void moveselpageup();
+        
+        void moveselpagedown();
 
         void eraseselected();
         
--- a/Testing/Source/Manual/UI_WidgetTest.cpp	Sun Jun 06 17:44:07 2021 +0300
+++ b/Testing/Source/Manual/UI_WidgetTest.cpp	Mon Jun 07 20:56:13 2021 +0300
@@ -6,6 +6,7 @@
 #include <Gorgon/UI/Organizers/Flow.h>
 #include <Gorgon/Widgets/Window.h>
 #include <Gorgon/Widgets/Textarea.h>
+#include <Gorgon/Widgets/Checkbox.h>
 
 std::string helptext =
     "Key list:\n"
@@ -20,8 +21,13 @@
     auto &org = app.wind.CreateOrganizer<UI::Organizers::Flow>();
     
     Widgets::Textarea wgt1("Hello world\nI am a text area\n1\n2\n3\n4\n5");
+    Widgets::Checkbox wrap("Wrap", true);
+    wrap.ChangedEvent.Register([&]{
+        wgt1.WordWrap = (bool)wrap;
+    });
     
     org 
+        << wrap << org.Break
         << wgt1 ;
         
     wgt1.SetText(wgt1.GetText() + "A lot more text is written in here...");

mercurial