diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2019-08-03 19:49:15 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2019-08-03 19:49:15 +0200 |
| commit | e6030fa04a8de3fdae1dc19d081bf5feb3d3d73c (patch) | |
| tree | 89f392cd974d1109a203ade305da467bd378ee48 /Samples/CrowIDE/src/Editors/ImlVisualEditor.cs | |
| parent | cad504c62d45952b4651603579f34df0d230841e (diff) | |
sample directory
Diffstat (limited to 'Samples/CrowIDE/src/Editors/ImlVisualEditor.cs')
| -rw-r--r-- | Samples/CrowIDE/src/Editors/ImlVisualEditor.cs | 908 |
1 files changed, 908 insertions, 0 deletions
diff --git a/Samples/CrowIDE/src/Editors/ImlVisualEditor.cs b/Samples/CrowIDE/src/Editors/ImlVisualEditor.cs new file mode 100644 index 00000000..75d8206b --- /dev/null +++ b/Samples/CrowIDE/src/Editors/ImlVisualEditor.cs @@ -0,0 +1,908 @@ +// +// ImlVisualEditor.cs +// +// Author: +// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> +// +// Copyright (c) 2016 jp +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +using System; +using Crow; +using System.Threading; +using System.Xml.Serialization; +using System.ComponentModel; +using System.IO; +using System.Collections.Generic; +using Crow.IML; +using System.Text; +using System.Xml; +using System.Diagnostics; +using vkvg; + +namespace Crow.Coding +{ + public class ImlVisualEditor : Editor + { + #region CTOR + public ImlVisualEditor () : base() + { + //imlVE = new DesignInterface (Interface.de); + initCommands (); + } + #endregion + + protected override void onInitialized (object sender, EventArgs e) + { + initIcons (); + base.onInitialized (sender, e); + } + DesignInterface imlVE; + Widget selectedItem; + ImlProjectItem imlProjFile; + + bool editorIsDirty = false;//needed when tree is empty + bool drawGrid, snapToGrid; + int gridSpacing, zoom = 100; + Measure designWidth, designHeight; + bool updateEnabled; + + Picture icoMove, icoStyle; + Rectangle rIcons = default(Rectangle); + Size iconSize = new Size(11,11); + + public List<Crow.Command> Commands; + Crow.Command cmdDelete; + + void initCommands () { + cmdDelete = new Crow.Command (new Action (() => deleteObject (SelectedItem))) + { Caption = "Delete", Icon = new SvgPicture ("#CrowIDE.icons.save.svg"), CanExecute = true }; + Commands = new List<Crow.Command> (new Crow.Command[] { cmdDelete }); + } + + void initIcons () { + icoMove = new SvgPicture ("#CrowIDE.icons.move-arrows.svg"); + + // icoStyle = new SvgPicture (); + // icoStyle.Load (IFace, "#CrowIDE.icons.palette.svg"); + } + + [DefaultValue(true)] + public bool DrawGrid { + get { return drawGrid; } + set { + if (drawGrid == value) + return; + drawGrid = value; + NotifyValueChanged ("DrawGrid", drawGrid); + RegisterForRedraw (); + } + } + [DefaultValue(true)] + public bool SnapToGrid { + get { return snapToGrid; } + set { + if (snapToGrid == value) + return; + snapToGrid = value; + NotifyValueChanged ("SnapToGrid", snapToGrid); + } + } + [DefaultValue(10)] + public int GridSpacing { + get { return gridSpacing; } + set { + if (gridSpacing == value) + return; + gridSpacing = value; + NotifyValueChanged ("GridSpacing", gridSpacing); + RegisterForRedraw (); + } + } + [DefaultValue(100)] + public int Zoom { + get { return zoom; } + set { + if (zoom == value) + return; + + zoom = value; + NotifyValueChanged ("Zoom", zoom); + Width = (int)(designWidth * zoom / 100.0); + Height = (int)(designHeight * zoom / 100.0); + } + } + [DefaultValue("512")] + public Measure DesignWidth { + get { return designWidth; } + set { + if (designWidth == value) + return; + designWidth = value; + NotifyValueChanged ("DesignWidth", designWidth); + Width = (int)(designWidth * zoom / 100.0); + } + } + [DefaultValue("400")] + public Measure DesignHeight { + get { return designHeight; } + set { + if (designHeight == value) + return; + designHeight = value; + NotifyValueChanged ("DesignHeight", designHeight); + Height = (int)(designHeight * zoom / 100.0); + } + } + + public Widget SelectedItem { + get { return selectedItem; } + set { + if (selectedItem == value) + return; + selectedItem = value; + + if (selectedItem == null) + cmdDelete.CanExecute = false; + else + cmdDelete.CanExecute = true; + + NotifyValueChanged ("SelectedItem", selectedItem); + RegisterForGraphicUpdate (); + } + } + /// <summary>PoinprojFilever the widget</summary> + public virtual Widget HoverWidget + { + get { return imlVE.HoverWidget; } + set { + if (HoverWidget == value) + return; + + imlVE.HoverWidget = value; + + NotifyValueChanged ("HoverWidget", HoverWidget); + } + } + /// <summary> + /// use to disable update if tab is not the visible one + /// </summary> + public bool UpdateEnabled { + get { return updateEnabled; } + set { + if (value == updateEnabled) + return; + updateEnabled = value; + NotifyValueChanged ("UpdateEnabled", updateEnabled); + } + } + + public List<Widget> GraphicTree { + get { return imlVE.GraphicTree; } + } + + [XmlIgnore]public List<LQIList> LQIs { + get { return imlVE.LQIs; } + } + + #region editor overrides + public override ProjectFile ProjectNode { + get { + return base.ProjectNode; + } + set { + base.ProjectNode = value; + imlProjFile = projFile as ImlProjectItem; + imlVE.ProjFile = imlProjFile; + } + } + + protected override bool EditorIsDirty { + get { return imlProjFile == null ? false : + imlProjFile.Instance == null ? editorIsDirty : + imlProjFile.Instance.design_HasChanged | editorIsDirty; } + set { + editorIsDirty = value; + if (GraphicTree.Count == 0) + return; + if (GraphicTree [0] != null) + GraphicTree [0].design_HasChanged = value; + } + } + protected override bool IsReady { + get { return updateEnabled && imlVE != null && imlProjFile != null; } + } + + protected override void updateProjFileFromEditor () + { + Debug.WriteLine("\t\tImlEditor updateProjFileFromEditor"); + try { + if (imlProjFile.Instance == null) + projFile.UpdateSource(this, @"<?xml version=""1.0""?>"); + else + projFile.UpdateSource(this, imlProjFile.Instance.GetIML()); + } catch (Exception ex) { + Error = ex.InnerException; + if (Monitor.IsEntered(imlVE.UpdateMutex)) + Monitor.Exit (imlVE.UpdateMutex); + } + } + protected override void updateEditorFromProjFile () { + Debug.WriteLine("\t\tImlEditor updateEditorFromProjFile"); + try { + string selItemDesignID = null; + if (SelectedItem!=null) + selItemDesignID = SelectedItem.design_id; + imlVE.ClearInterface(); + Instantiator.NextInstantiatorID = 0; + imlVE.Styling = projFile.Project.solution.Styling; + imlVE.DefaultValuesLoader.Clear(); + //imlVE.DefaultTemplates = projFile.Project.solution.DefaultTemplates; + imlVE.Instantiators = new Dictionary<string, Instantiator>(); + + //prevent error on empty file + bool emptyFile = true; + string src = projFile.Source; + using (Stream s = new MemoryStream (Encoding.UTF8.GetBytes (src))) { + using (XmlReader itr = XmlReader.Create (s)) { + while(itr.Read()){ + if (itr.NodeType == XmlNodeType.Element){ + emptyFile = false; + break; + } + } + } + } + Widget go = null; + Error = null; + + if (emptyFile){ + imlProjFile.Instance = null; + }else{ + imlVE.LoadIMLFragment(src); + imlProjFile.Instance = imlVE.GraphicTree[0]; + if (selItemDesignID!=null) + imlProjFile.Instance.FindByDesignID(selItemDesignID,out go); + + } + SelectedItem = go; + } catch (Exception ex) { + Error = ex; + } + } + protected override void updateCheckPostProcess () + { + if (Error != null) { + RegisterForRedraw (); + return; + } + imlVE.Update (); + bool isDirty = false; + + lock (imlVE.RenderMutex) + isDirty = imlVE.IsDirty; + + if (isDirty) { + lock (IFace.UpdateMutex) + RegisterForRedraw (); + } + } + #endregion + + #region GraphicObject overrides + public override void OnLayoutChanges (LayoutingType layoutType) + { + base.OnLayoutChanges (layoutType); + switch (layoutType) { + case LayoutingType.Width: + DesignWidth = Slot.Width * 100 / zoom; + imlVE.ProcessResize (new Size(designWidth,designHeight)); + break; + case LayoutingType.Height: + DesignHeight = Slot.Height * 100 / zoom; + imlVE.ProcessResize (new Size(designWidth,designHeight)); + break; + } + } + + public override void onMouseMove (object sender, MouseMoveEventArgs e) + { + base.onMouseMove (sender, e); + + Widget oldHW = HoverWidget; + Rectangle scr = this.ScreenCoordinates (this.getSlot ()); + ProcessMouseMove (e.X - scr.X, e.Y - scr.Y); + + Widget newHW = HoverWidget; + if (newHW == null) + return; + + if (draggedObj != null) { + if (draggedObj.Parent == null) { + if (tryAddObjectTo (newHW, draggedObj)) { + RegisterForRedraw (); + return; + } + } else if (newHW != draggedObj) { + //lock (imlVE.UpdateMutex) { + ILayoutable possibleParent = getPossibleParent (newHW, draggedObj); + if (possibleParent == null) { + Group g = newHW.Parent as Group; + if (g != null && g != draggedObj) { + removeObject (draggedObj); + g.InsertChild (g.Children.IndexOf (newHW), draggedObj); + RegisterForRedraw (); + return; + } + } else if (possibleParent != draggedObj.Parent) { + removeObject (draggedObj); + if (tryAddObjectTo (possibleParent, draggedObj)) { + RegisterForRedraw (); + return; + } + } + //} + } + } + + if (oldHW == newHW) + return; + //RegisterForRedraw (); + + } + public override void onMouseEnter (object sender, MouseMoveEventArgs e) + { + base.onMouseEnter (sender, e); + if (IFace.DragAndDropOperation != null && draggedObj == null) + return; + IFace.FocusedWidget = this; + } + public override void onMouseLeave (object sender, MouseMoveEventArgs e) + { + base.onMouseLeave (sender, e); +// IFace.FocusedWidget = null; + } + public override void onMouseDown (object sender, MouseButtonEventArgs e) + { + if (e.Mouse.RightButton == ButtonState.Pressed) { + base.onMouseDown (sender, e); + return; + } + SelectedItem = HoverWidget; + +// if (SelectedItem != null && projFile != null) { +// projFile.CurrentLine = SelectedItem.design_line; +// projFile.CurrentColumn = SelectedItem.design_column; +// } + + } + + protected override void onDraw (Context gr) + { + base.onDraw (gr); + + Rectangle cb = new Rectangle (0, 0, designWidth, designHeight); + + gr.Save (); + + double z = zoom / 100.0; + + gr.Scale (z, z); + + if (drawGrid) { + double gridLineWidth = 0.2 / z; + double glhw = gridLineWidth / 2.0; + int nbLines = cb.Width / gridSpacing; + double d = cb.Left + gridSpacing; + for (int i = 0; i < nbLines; i++) { + gr.MoveTo (d - glhw, cb.Y); + gr.LineTo (d - glhw, cb.Bottom); + d += gridSpacing; + } + nbLines = cb.Height / gridSpacing; + d = cb.Top + gridSpacing; + for (int i = 0; i < nbLines; i++) { + gr.MoveTo (cb.X, d - glhw); + gr.LineTo (cb.Right, d - glhw); + d += gridSpacing; + } + gr.LineWidth = gridLineWidth; + Foreground.SetAsSource (gr, cb); + gr.Stroke (); + } + + lock (imlVE.RenderMutex) { + gr.SetSourceSurface (imlVE.surf, cb.Left, cb.Top); + gr.Paint (); + imlVE.IsDirty = false; + } + /*if (Error == null) { + gr.SetSourceColor (Color.Black); + gr.Rectangle (cb, 1.0 / z); + } else { + gr.SetSourceColor (Color.LavenderBlush); + gr.Rectangle (cb, 2.0 / z); + string[] lerrs = Error.ToString ().Split ('\n'); + Point p = cb.Center; + p.Y -= lerrs.Length * 20; + foreach (string le in lerrs) { + drawCenteredTextLine(gr, p, le); + p.Y += 20; + + } + } + gr.Stroke ();*/ + + Rectangle hr; + + /* + if (SelectedItem?.Parent != null) { + + gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); + gr.SetFontSize (Font.Size); + gr.FontOptions = Interface.FontRenderingOptions; + gr.Antialias = Interface.Antialias; + + Widget g = SelectedItem; + hr = g.ScreenCoordinates (g.getSlot ()); + +// Rectangle rIcons = new Rectangle (iconSize); +// rIcons.Width *= 4; +// rIcons.Top = hr.Bottom; +// rIcons.Left = hr.Right - rIcons.Width + iconSize.Width; + Rectangle rIcoMove = new Rectangle (hr.BottomRight, iconSize); +// Rectangle rIcoStyle = rIcoMove; +// rIcoStyle.Left += iconSize.Width + 4; + + using (Surface mask = new ImageSurface (Format.Argb32, cb.Width, cb.Height)) { + using (Context ctx = new Context (mask)) { + ctx.Save(); + ctx.SetSourceRGBA(1.0,1.0,1.0,0.4); + ctx.Paint (); + ctx.Rectangle (hr); + ctx.Operator = Operator.Clear; + ctx.Fill (); + } + + gr.SetSourceSurface (mask, 0, 0); + gr.Paint (); + + using (Surface ol = new ImageSurface (Format.Argb32, cb.Width, cb.Height)) { + using (Context ctx = new Context (ol)) { + ctx.SetSourceColor (Color.Black); + drawDesignOverlay (ctx, g, cb, hr, 0.4 / z, 6.5); + } + + gr.SetSourceSurface (ol, 0, 0); + gr.Paint (); + } + + drawIcon (gr, icoMove, rIcoMove); + //drawIcon (gr, icoStyle, rIcoStyle); + + } + }*/ + if (HoverWidget != null) { + hr = HoverWidget.ScreenCoordinates (HoverWidget.getSlot ()); + gr.SetSourceColor (Color.SkyBlue); + //gr.SetDash (new double[]{ 5.0, 3.0 }, 0.0); + gr.Rectangle (hr, 0.4 / z); + } + gr.Restore (); + } + + void drawIcon (Context gr, Picture pic, Rectangle r) {/* +// gr.SetSourceColor (Color.Black); +// CairoHelpers.CairoRectangle (gr, r.Inflated (1), 2, 1.0); + gr.SetSourceColor (Color.White); + CairoHelpers.CairoRectangle (gr, r.Inflated (1), 2); + gr.Fill (); + gr.Operator = Operator.Clear; + pic.Paint (gr, r); + gr.Operator = Operator.Over;*/ + } + void drawDesignOverlay (Context gr, Widget g, Rectangle cb, Rectangle hr, double coteStroke, double space = 6.5){ + /* + double z = zoom / 100.0; + double coteW = 3, coteL = 5; + bool fill = true; + Crow.Cairo.PointD p1 = new Crow.Cairo.PointD (hr.X + 0.5, hr.Y - space); + Crow.Cairo.PointD p2 = new Crow.Cairo.PointD (hr.Right - 0.5, hr.Y - space); + + if (p1.Y < cb.Top) { + if (hr.Bottom > cb.Bottom - space) + p1.Y = p2.Y = hr.Bottom - space; + else + p1.Y = p2.Y = hr.Bottom + space; + } + + if (g.Width.IsFit) + gr.DrawCoteInverse (p1, p2, coteStroke, fill, coteW, coteL); + else if (g.Width.IsRelativeToParent) { + gr.DrawCote (p1, p2, coteStroke, fill, coteW, coteL); + if (g.Width.Value < 100) + drawCenteredTextLine (gr, p1.Add(p2.Substract(p1).Divide (2)), g.Width.ToString()); + }else if (g.Width.IsFixed) { + gr.DrawCoteFixed (p1, p2, coteStroke * 2.0, coteW); + drawCenteredTextLine (gr, p1.Add(p2.Substract(p1).Divide (2)), g.Width.Value.ToString()); + } + + p1 = new Crow.Cairo.PointD (hr.X - space, hr.Top + 0.5); + p2 = new Crow.Cairo.PointD (hr.X - space, hr.Bottom - 0.5); + + if (p1.X < cb.Left) { + if (hr.Right > cb.Right - space) + p1.X = p2.X = hr.Right - space; + else + p1.X = p2.X = hr.Right + space; + } + if (g.Height.IsFit) + gr.DrawCoteInverse (p1, p2, coteStroke, fill, coteW, coteL); + else if (g.Height.IsRelativeToParent){ + gr.DrawCote (p1, p2, coteStroke, fill, coteW, coteL); + if (g.Height.Value < 100) + drawCenteredTextLine (gr, p1.Add(p2.Substract(p1).Divide (2)), g.Height.ToString()); + }else if (g.Width.IsFixed) { + gr.DrawCoteFixed (p1, p2, coteStroke * 2.0, coteW); + drawCenteredTextLine (gr, p1.Add(p2.Substract(p1).Divide (2)), g.Height.Value.ToString()); + } + + // hr.Inflate (2); + //gr.SetDash (new double[]{ 1.0, 4.0 }, 0.0); + //gr.SetSourceColor (Color.Grey); +// gr.Rectangle (hr,coteStroke); +// gr.Stroke (); + gr.Operator = Operator.Over; + */ + } + + void drawCenteredTextLine (Context gr, Point center, string txt){ + drawCenteredTextLine (gr, new PointD(center.X,center.Y), txt); + } + void drawCenteredTextLine (Context gr, PointD center, string txt){ + if (string.IsNullOrEmpty(txt)) + return; + FontExtents fe = gr.FontExtents; + TextExtents te = gr.TextExtents (txt); + + Rectangle rText = new Rectangle( + (int)(center.X - te.Width / 2), (int)(center.Y - (fe.Ascent + fe.Descent) / 2), + (int)te.Width, (int)(fe.Ascent + fe.Descent)); + + gr.Operator = Operator.Clear; + Rectangle r = rText; + r.Inflate (2); + gr.Rectangle (r); + gr.Fill (); + gr.Operator = Operator.Over; + + gr.MoveTo (rText.X, rText.Y + fe.Ascent); + gr.ShowText (txt); + gr.Fill (); + + } + protected override void onDragEnter (object sender, DragDropEventArgs e) + { + base.onDragEnter (sender, e); + GraphicObjectDesignContainer godc = e.DragSource.DataSource as GraphicObjectDesignContainer; + if (godc == null) + return; + createDraggedObj (godc.CrowType); + } + protected override void onDragLeave (object sender, DragDropEventArgs e) + { + base.onDragLeave (sender, e); + GraphicObjectDesignContainer godc = e.DragSource.DataSource as GraphicObjectDesignContainer; + if (godc == null) + return; + ClearDraggedObj (); + } + + protected override void onStartDrag (object sender, DragDropEventArgs e) + { + base.onStartDrag (sender, e); + if (SelectedItem == null) + return; + + Widget dumy = new Widget (IFace); + dumy.EndDrag += dumyOnEndDrag; + dumy.Drop += dumyOnDrop; + dumy.IsDragged = true; + IFace.ActiveWidget = dumy; + e.DragSource.IsDragged = false; + IFace.DragAndDropOperation.DragSource = dumy; + draggedObj = SelectedItem; + int dragIconSize = 48; + lock (IFace.UpdateMutex) { + IFace.DragImageHeight = dragIconSize; + IFace.DragImageWidth = dragIconSize; + IFace.DragImage = draggedObj.CreateIcon(dragIconSize); + } + removeObject (draggedObj); + SelectedItem = null; + HoverWidget = null; + } + void dumyOnEndDrag (object sender, DragDropEventArgs e) + { + IFace.ClearDragImage (); + } + void dumyOnDrop (object sender, DragDropEventArgs e) + { + ClearDraggedObj (false); + IFace.ClearDragImage (); + } + #endregion + + + #region draggedObj handling + + public Widget draggedObj = null; + + void createDraggedObj (Type crowType) { + lock (imlVE.UpdateMutex) { + draggedObj = imlVE.CreateITorFromIMLFragment ("<" + crowType.Name + "/>").CreateInstance (); + } + } + + public void ClearDraggedObj (bool removeFromTree = true) { + if (removeFromTree) + deleteObject (draggedObj); + draggedObj = null; + } + #endregion + + void removeObject (Widget go) { + if (go == null) + return; + if (go.Parent == null) + return; +// lock (imlVE.UpdateMutex) { + Interface i = go.Parent as Interface; + if (i != null) { + i.RemoveWidget (go); + imlProjFile.Instance = null; + } else { + Container c = go.Parent as Container; + if (c != null) + c.SetChild (null); + else { + TemplatedContainer tc = go.Parent as TemplatedContainer; + if (tc != null) + tc.Content = null; + else { + Group g = go.Parent as Group; + if (g != null) + g.RemoveChild (go); + } + } + } + EditorIsDirty = true; + //} + } + void deleteObject (Widget go) { + if (go == null) + return; + //lock (imlVE.UpdateMutex) { + removeObject (go); + go.Dispose (); + //} + } + + ILayoutable getPossibleParent (ILayoutable parent, Widget go) { + if (go == null) + return null; +// lock (imlVE.UpdateMutex) { + + Interface i = null; + if (parent == null) + i = imlVE; + else + i = parent as Interface; + if (i != null) + return i.GraphicTree.Count > 0 ? null : i; + + Container c = parent as Container; + if (c != null) + return c.Child == null || c.Child == go ? c : null; + + TemplatedContainer tc = parent as TemplatedContainer; + if (tc != null) + return tc.Content == null || tc.Content == go? tc : null; + + return parent as Group; +// } + } + bool tryAddObjectTo (ILayoutable parent, Widget go) { + if (go == null) + return false; +// lock (imlVE.UpdateMutex) { + Interface i = null; + if (parent == null) + i = imlVE; + else + i = parent as Interface; + if (i != null) { + if (i.GraphicTree.Count > 0) + return false; + i.AddWidget (go); + imlProjFile.Instance = go; + EditorIsDirty = true; + return true; + } + Container c = parent as Container; + if (c != null) { + if (c.Child != null) + return false; + //return tryAddObjectTo (c.Parent, go); + c.SetChild (go); + EditorIsDirty = true; + return true; + } + TemplatedContainer tc = parent as TemplatedContainer; + if (tc != null) { + if (tc.Content != null) + return false; + //return tryAddObjectTo (c.Parent, go); + tc.Content = (go); + EditorIsDirty = true; + return true; + } + Group g = parent as Group; + if (g != null) { + g.AddChild (go); + EditorIsDirty = true; + return true; + } + return false;//tryAddObjectTo (parent.Parent, go); +// } + } + + + + void WidgetCheckOver (Widget go, MouseMoveEventArgs e){ + Type tGo = go.GetType(); + if (typeof(TemplatedGroup).IsAssignableFrom (tGo)) { + + } else if (typeof(TemplatedContainer).IsAssignableFrom (tGo)) { + TemplatedContainer c = go as TemplatedContainer; + if (c.Content?.MouseIsIn (e.Position) == true) { + WidgetCheckOver (c.Content, e); + return; + } + } else if (typeof(TemplatedControl).IsAssignableFrom (tGo)) { + } else if (typeof(Group).IsAssignableFrom (tGo)) { + Group c = go as Group; + for (int i = c.Children.Count -1; i >= 0; i--) { + if (c.Children[i].MouseIsIn (e.Position)) { + WidgetCheckOver (c.Children[i], e); + return; + } + } + } else if (typeof(Crow.Container).IsAssignableFrom (tGo)) { + Crow.Container c = go as Crow.Container; + if (c.Child?.MouseIsIn (e.Position)==true) { + WidgetCheckOver (c.Child, e); + return; + } + } + HoverWidget = go; + WidgetMouseEnter (go, e); + } + void WidgetMouseLeave (Widget go, MouseMoveEventArgs e){ + + } + void WidgetMouseEnter (Widget go, MouseMoveEventArgs e){ + + } + void WidgetMouseMove (Widget go, MouseMoveEventArgs e){} + + public bool ProcessMouseMove(int x, int y) + { + int deltaX = x - imlVE.Mouse.X; + int deltaY = y - imlVE.Mouse.Y; + imlVE.Mouse.X = x; + imlVE.Mouse.Y = y; + MouseMoveEventArgs e = new MouseMoveEventArgs (x, y, deltaX, deltaY); + e.Mouse = imlVE.Mouse; + + if (imlVE.ActiveWidget != null) { + //TODO, ensure object is still in the graphic tree + //send move evt even if mouse move outside bounds + WidgetMouseMove (imlVE.ActiveWidget, e); + return true; + } + + if (HoverWidget != null) { + //TODO, ensure object is still in the graphic tree + //check topmost graphicobject first + Widget tmp = HoverWidget; + Widget topc = null; + while (tmp is Widget) { + topc = tmp; + tmp = tmp.LogicalParent as Widget; + } + int idxhw = imlVE.GraphicTree.IndexOf (topc); + if (idxhw != 0) { + int i = 0; + while (i < idxhw) { + if (imlVE.GraphicTree [i].LogicalParent == imlVE.GraphicTree [i].Parent) { + if (imlVE.GraphicTree [i].MouseIsIn (e.Position)) { + while (imlVE.HoverWidget != null) { + WidgetMouseLeave (imlVE.HoverWidget, e); + imlVE.HoverWidget = imlVE.HoverWidget.LogicalParent as Widget; + } + + WidgetCheckOver (GraphicTree [i], e); + return true; + } + } + i++; + } + } + + + if (imlVE.HoverWidget.MouseIsIn (e.Position)) { + WidgetCheckOver (imlVE.HoverWidget, (e)); + return true; + } else { + WidgetMouseLeave (imlVE.HoverWidget, e); + //seek upward from last focused graph obj's + while (imlVE.HoverWidget.LogicalParent as Widget != null) { + imlVE.HoverWidget = imlVE.HoverWidget.LogicalParent as Widget; + if (imlVE.HoverWidget.MouseIsIn (e.Position)) { + WidgetCheckOver (imlVE.HoverWidget, e); + return true; + } else + WidgetMouseLeave (imlVE.HoverWidget, e); + } + } + } + + //top level graphic obj's parsing + lock (imlVE.GraphicTree) { + for (int i = 0; i < imlVE.GraphicTree.Count; i++) { + Widget g = imlVE.GraphicTree [i]; + if (g.MouseIsIn (e.Position)) { + WidgetCheckOver (g, e); + return true; + } + } + } + imlVE.HoverWidget = null; + return false; + + } + + void GTView_SelectedItemChanged (object sender, SelectionChangeEventArgs e) + { + SelectedItem = e.NewValue as Widget; + } + + + public override void onKeyDown (object sender, KeyEventArgs e) + { + + switch (e.Key) { + case Key.Delete: + if (selectedItem == null) + return; + deleteObject (selectedItem); + break; + case Key.Escape: + SelectedItem = null; + break; + } + } + } +} |