]> O.S.I.I.S - jp/crow.git/commitdiff
TextRun
authorjpbruyere <jp.bruyere@hotmail.com>
Fri, 11 Sep 2015 21:05:09 +0000 (23:05 +0200)
committerjpbruyere <jp.bruyere@hotmail.com>
Fri, 11 Sep 2015 21:05:09 +0000 (23:05 +0200)
GOLib.csproj
Tests/GOLIBTests.cs
Tests/Interfaces/testLabel.goml
src/GraphicObjects/GraphicObject.cs
src/GraphicObjects/TextRun.cs [new file with mode: 0755]

index 92896b0f36eef11443aece5228be49bfb2d61f33..e785acac0807dfd740f4350f4930ce4bc38c2385 100644 (file)
     <Compile Include="src\ReflexionExtensions.cs" />\r
     <Compile Include="src\XCursor.cs" />\r
     <Compile Include="src\GraphicObjects\Grid.cs" />\r
+    <Compile Include="src\GraphicObjects\TextRun.cs" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Reference Include="System" />\r
index 29cfc9fd7094d5011ff3406a0a633858c3793293..5a8dd181dcf29e944281b99feafd36b23e4c606c 100644 (file)
@@ -31,13 +31,13 @@ namespace test
                int frameCpt = 0;\r
                int idx = 0;\r
                string[] testFiles = {\r
+                       "testLabel.goml",\r
                        "testGrid.goml",\r
                        "test1.goml",\r
                        "test1.1.goml",\r
                        "test1.2.goml",\r
                        "test1.3.goml",\r
                        "test2.goml",\r
-                       "testLabel.goml",\r
                        "testContainer.goml",\r
                        "test_stack.goml",\r
                        "testHStack.goml",\r
index a640002a1f48016ff0d9eac4bc132a7398d607e0..d394e32cab2cbd77af284bd04b42d4c816df2337 100755 (executable)
@@ -1,3 +1,6 @@
 <?xml version="1.0"?>\r
-                               <Label Name="labFps" Text="{fps}" Font="droid bold, 12"\r
-                                       TextAlignment="Center" Background="AoEnglish" />\r
+<VerticalStack>\r
+       <TextRun Multiline="true" WordWrap="true" Width="0" Height="100" Background="DimGray"\r
+               Text="This is a long text to test text wrapping, and so here is another statement to add to this meaningless text only designed to make a small test" />\r
+       <Label Name="labFps" Text="{fps}" Font="droid bold, 12" TextAlignment="Center" Background="AoEnglish" />\r
+</VerticalStack>
\ No newline at end of file
index b6ebeb149ce0ceaba0db68ad432a68b92494025a..7437c31aa7466428f057e35b7928ff8ce2178fbd 100644 (file)
@@ -48,6 +48,7 @@ namespace go
                string _name;\r
                Color _background;\r
                Color _foreground;\r
+               Font _font;\r
                double _cornerRadius;\r
                int _margin;\r
                bool _focusable = false;\r
@@ -231,6 +232,11 @@ namespace go
                                registerForGraphicUpdate ();\r
                        }\r
                }\r
+               [XmlAttributeAttribute()][DefaultValue("droid,10")]\r
+               public virtual Font Font {\r
+                       get { return _font; }\r
+                       set { _font = value; }\r
+               }\r
                [XmlAttributeAttribute()][DefaultValue(2.0)]\r
                public virtual double CornerRadius {\r
                        get { return _cornerRadius; }\r
diff --git a/src/GraphicObjects/TextRun.cs b/src/GraphicObjects/TextRun.cs
new file mode 100755 (executable)
index 0000000..2dda5ac
--- /dev/null
@@ -0,0 +1,333 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using System.Diagnostics;\r
+using Cairo;\r
+using System.Text.RegularExpressions;\r
+using System.Xml.Serialization;\r
+using System.ComponentModel;\r
+using OpenTK.Input;\r
+\r
+namespace go\r
+{\r
+    [Serializable]\r
+    public class TextRun : GraphicObject\r
+    {\r
+               #region CTOR\r
+               public TextRun()\r
+               { \r
+\r
+               }\r
+               public TextRun(string _text)\r
+                       : base()\r
+               {\r
+                       Text = _text;\r
+               }\r
+               #endregion\r
+\r
+        //TODO:change protected to private\r
+        \r
+               #region private and protected fields\r
+               protected string _text = "label";\r
+        Alignment _textAlignment = Alignment.LeftCenter;        \r
+               bool _multiline;\r
+               bool wordWrap;\r
+        protected Rectangle rText;\r
+               protected float widthRatio = 1f;\r
+               protected float heightRatio = 1f;\r
+               protected FontExtents fe;\r
+               protected TextExtents te;\r
+               #endregion\r
+\r
+\r
+        [XmlAttributeAttribute()][DefaultValue(Alignment.LeftCenter)]\r
+               public Alignment TextAlignment\r
+        {\r
+            get { return _textAlignment; }\r
+            set { _textAlignment = value; }\r
+        }\r
+               [XmlAttributeAttribute()][DefaultValue("label")]\r
+        public string Text\r
+        {\r
+            get {                              \r
+                               return lines == null ? \r
+                                       _text : lines.Aggregate((i, j) => i + Interface.LineBreak + j);\r
+                       }\r
+            set\r
+            {\r
+                if (_text == value)\r
+                    return;\r
+                                                       \r
+                registerForGraphicUpdate();\r
+                               this.RegisterForLayouting ((int)LayoutingType.Sizing);\r
+\r
+\r
+                _text = value;\r
+\r
+                               if (string.IsNullOrEmpty(_text))\r
+                                       _text = "";\r
+\r
+                               lines = getLines;\r
+            }\r
+        }\r
+               [XmlAttributeAttribute()][DefaultValue(false)]\r
+               public bool Multiline\r
+               {\r
+                       get { return _multiline; }\r
+                       set\r
+                       {\r
+                               _multiline = value;\r
+                               registerForGraphicUpdate();\r
+                       }\r
+               }\r
+               [XmlAttributeAttribute()][DefaultValue(false)]\r
+               public bool WordWrap {\r
+                       get {\r
+                               return wordWrap;\r
+                       }\r
+                       set {\r
+                               if (wordWrap == value)\r
+                                       return;\r
+                               wordWrap = value;\r
+                               registerForGraphicUpdate();\r
+                       }\r
+               }\r
+\r
+               List<string> lines;\r
+               List<string> getLines {\r
+                       get {                           \r
+                               return _multiline ?\r
+                                       Regex.Split (_text, "\r\n|\r|\n").ToList() :\r
+                                       new List<string>(new string[] { _text });\r
+                       }\r
+               }\r
+\r
+               #region GraphicObject overrides\r
+               [XmlAttributeAttribute()][DefaultValue(-1)]\r
+               public override int Width {\r
+                       get { return base.Width; }\r
+                       set { base.Width = value; }\r
+               }\r
+               [XmlAttributeAttribute()][DefaultValue(-1)]\r
+               public override int Height {\r
+                       get { return base.Height; }\r
+                       set { base.Height = value; }\r
+               }\r
+               [XmlAttributeAttribute()][DefaultValue(2)]\r
+               public override int Margin {\r
+                       get { return base.Margin; }\r
+                       set { base.Margin = value; }\r
+               }\r
+\r
+               protected override Size measureRawSize()\r
+        {\r
+                       Size size;\r
+\r
+                       if (lines == null)\r
+                               lines = getLines;\r
+                               \r
+                       using (ImageSurface img = new ImageSurface (Format.Argb32, 10, 10)) {\r
+                               using (Context gr = new Context (img)) {\r
+                                       //Cairo.FontFace cf = gr.GetContextFontFace ();\r
+\r
+                                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);\r
+                                       gr.SetFontSize (Font.Size);\r
+\r
+                                       te = new TextExtents();\r
+\r
+                                       foreach (string s in lines) {\r
+                                               string l = s.Replace("\t", new String (' ', Interface.TabSize));\r
+\r
+#if _WIN32 || _WIN64\r
+                                               TextExtents tmp = gr.TextExtents(str.ToUtf8());\r
+#elif __linux__\r
+                                               TextExtents tmp = gr.TextExtents (l);\r
+#endif\r
+                                               if (tmp.XAdvance > te.XAdvance)\r
+                                                       te = tmp;\r
+                                       }\r
+                                       fe = gr.FontExtents;\r
+                                       int lc = lines.Count;\r
+                                       //ensure minimal height = text line height\r
+                                       if (lc == 0)\r
+                                               lc = 1; \r
+                                       size = new Size ((int)Math.Ceiling (te.XAdvance) + Margin * 2, (int)(fe.Height * lc) + Margin*2);\r
+                               }\r
+                       }\r
+\r
+            return size;;\r
+        }\r
+               protected override void onDraw (Context gr)\r
+               {\r
+                       base.onDraw (gr);\r
+\r
+                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);\r
+                       gr.SetFontSize (Font.Size);\r
+\r
+                       gr.Antialias = Antialias.Subpixel;\r
+                       //gr.FontOptions.Antialias = Antialias.Subpixel;\r
+                       //gr.FontOptions.HintMetrics = HintMetrics.On;\r
+\r
+                       rText = new Rectangle(measureRawSize());\r
+                       rText.Width -= 2 * Margin;\r
+                       rText.Height -= 2 * Margin;\r
+\r
+                       widthRatio = 1f;\r
+                       heightRatio = 1f;\r
+\r
+                       Rectangle cb = ClientRectangle;\r
+\r
+                       //ignore text alignment if size to content = true\r
+                       //or if text size is larger than client bounds\r
+                       if (Bounds.Size < 0 || rText.Width > cb.Width)\r
+                       {\r
+                               rText.X = cb.X;\r
+                               rText.Y = cb.Y;\r
+                       }else {\r
+                               \r
+                               switch (TextAlignment)\r
+                               {\r
+                               case Alignment.None:\r
+                                       break;\r
+                               case Alignment.TopLeft:     //ok\r
+                                       rText.X = cb.X;\r
+                                       rText.Y = cb.Y;\r
+                                       break;\r
+                               case Alignment.TopCenter:   //ok\r
+                                       rText.Y = cb.Y;\r
+                                       rText.X = cb.X + cb.Width / 2 - rText.Width / 2;\r
+                                       break;\r
+                               case Alignment.TopRight:    //ok\r
+                                       rText.X = cb.Right - rText.Width;\r
+                                       rText.Y = cb.Y;\r
+                                       break;\r
+                               case Alignment.TopStretch://ok\r
+                                       heightRatio = widthRatio = (float)cb.Width / rText.Width;\r
+                                       rText.X = cb.X;\r
+                                       rText.Y = cb.Y;\r
+                                       rText.Width = cb.Width;\r
+                                       rText.Height = (int)(rText.Height * heightRatio);\r
+                                       break;\r
+                               case Alignment.LeftCenter://ok\r
+                                       rText.X = cb.X;\r
+                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;\r
+                                       break;\r
+                               case Alignment.LeftStretch://ok\r
+                                       heightRatio = widthRatio = (float)cb.Height / rText.Height;\r
+                                       rText.X = cb.X;\r
+                                       rText.Y = cb.Y;\r
+                                       rText.Height = cb.Height;\r
+                                       rText.Width = (int)(widthRatio * cb.Width);\r
+                                       break;\r
+                               case Alignment.RightCenter://ok\r
+                                       rText.X = cb.X + cb.Width - rText.Width;\r
+                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;\r
+                                       break;\r
+                               case Alignment.RightStretch://ok\r
+                                       heightRatio = widthRatio = (float)cb.Height / rText.Height;\r
+                                       rText.Height = cb.Height;\r
+                                       rText.Width = (int)(widthRatio * cb.Width);\r
+                                       rText.X = cb.X;\r
+                                       rText.Y = cb.Y;\r
+                                       break;\r
+                               case Alignment.BottomCenter://ok\r
+                                       rText.X = cb.Width / 2 - rText.Width / 2;\r
+                                       rText.Y = cb.Height - rText.Height;\r
+                                       break;\r
+                               case Alignment.BottomStretch://ok\r
+                                       heightRatio = widthRatio = (float)cb.Width / rText.Width;\r
+                                       rText.Width = cb.Width;\r
+                                       rText.Height = (int)(rText.Height * heightRatio);\r
+                                       rText.Y = cb.Bottom - rText.Height;\r
+                                       rText.X = cb.X;\r
+                                       break;\r
+                               case Alignment.BottomLeft://ok\r
+                                       rText.X = cb.X;\r
+                                       rText.Y = cb.Bottom - rText.Height;\r
+                                       break;\r
+                               case Alignment.BottomRight://ok\r
+                                       rText.Y = cb.Bottom - rText.Height;\r
+                                       rText.X = cb.Right - rText.Width;\r
+                                       break;\r
+                               case Alignment.Center://ok\r
+                                       rText.X = cb.X + cb.Width / 2 - rText.Width / 2;\r
+                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;\r
+                                       break;\r
+                               case Alignment.Fit://ok, peut être mieu aligné                            \r
+                                       widthRatio = (float)cb.Width / rText.Width;\r
+                                       heightRatio = (float)cb.Height / rText.Height;\r
+                                       rText = cb;\r
+                                       break;\r
+                               case Alignment.HorizontalStretch://ok\r
+                                       heightRatio = widthRatio = (float)cb.Width / rText.Width;\r
+                                       rText.Width = cb.Width;\r
+                                       rText.Height = (int)(heightRatio * rText.Height);\r
+                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;\r
+                                       rText.X = cb.X;\r
+                                       break;\r
+                               case Alignment.VerticalStretch://ok\r
+                                       heightRatio = widthRatio = (float)cb.Height / rText.Height;\r
+                                       rText.Height = cb.Height;\r
+                                       rText.Width = (int)(widthRatio * rText.Width);\r
+                                       rText.X = cb.X + cb.Width / 2 - rText.Width / 2;\r
+                                       rText.Y = cb.Y;\r
+                                       break;\r
+                               default:\r
+                                       break;\r
+                               }\r
+                       }\r
+\r
+                       gr.FontMatrix = new Matrix(widthRatio * Font.Size, 0, 0, heightRatio * Font.Size, 0, 0);\r
+\r
+\r
+                       int curLineCount = 0;\r
+                       for (int i = 0;i < lines.Count;i++) {                           \r
+                               string l = lines [i].Replace ("\t", new String (' ', Interface.TabSize));\r
+                               List<string> wl = new List<string> ();\r
+                               int lineLength = (int)gr.TextExtents (l).XAdvance;\r
+\r
+                               if (wordWrap && lineLength > cb.Width) {\r
+                                       string tmpLine = "";\r
+                                       int curChar = 0;\r
+                                       while (curChar < l.Length) {\r
+                                               tmpLine += l [curChar];\r
+                                               if ((int)gr.TextExtents (tmpLine).XAdvance > cb.Width) {\r
+                                                       tmpLine = tmpLine.Remove (tmpLine.Length - 1);\r
+                                                       wl.Add (tmpLine);\r
+                                                       tmpLine = "";\r
+                                                       continue;\r
+                                               }\r
+                                               curChar++;\r
+                                       }\r
+                                       wl.Add (tmpLine);\r
+                               } else\r
+                                       wl.Add (l);\r
+\r
+                               foreach (string ll in wl) {\r
+                                       lineLength = (int)gr.TextExtents (ll).XAdvance;\r
+                                                                       \r
+\r
+                                       if (string.IsNullOrWhiteSpace (ll)) {\r
+                                               curLineCount++;\r
+                                               continue;\r
+                                       }\r
+\r
+                                       gr.Color = Foreground;                          \r
+                                       gr.MoveTo (rText.X, rText.Y + fe.Ascent + fe.Height * curLineCount);\r
+\r
+                                       #if _WIN32 || _WIN64\r
+                                       gr.ShowText(ll.ToUtf8());\r
+                                       #elif __linux__\r
+                                       gr.ShowText (ll);\r
+                                       #endif\r
+                                       gr.Fill ();\r
+\r
+                                       curLineCount++;\r
+                                               \r
+                               }\r
+                       }                                               \r
+               }\r
+               #endregion\r
+    }\r
+}\r