diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2018-02-09 18:46:40 +0100 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2018-02-09 18:46:40 +0100 |
| commit | 49c7adb31d17bfc9f5349f8c8343a4ca6318d3aa (patch) | |
| tree | 2b9b882a9451d97fc635016f98f9b3c2ba90506c /src | |
| parent | 829d1de43b5a9b39ace2f01eeecae5255f01ed1f (diff) | |
Squashed commit devel branch:
commit 7f91f7c2e83f7cfb2922ea83586f156f03f88a59
Author: Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
Date: Fri Feb 9 18:13:59 2018 +0100
go back to OpenTK-2, waiting for an official release
commit 125f32758a584c4976d3536eab3702fd37a8a7a9
Author: Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
Date: Fri Feb 9 17:26:00 2018 +0100
LoadInterface replaced by AddWidget overload, [ide] property view item templates in separate template file
commit 7c48cd2f0332d2ec82006edb755fcd37ab1f2b4a
Author: Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
Date: Fri Feb 9 12:10:13 2018 +0100
Tooltips, CrowIDE improvements, Fetch subdata when test not eq TypeOf, debug listener in basicTest, RemoveWidget in iface
modifié : Crow.ControlsLib/Crow.ControlsLib.csproj
modifié : Crow.csproj
modifié : Crow.sln
modifié : CrowIDE/CrowIDE.csproj
modifié : CrowIDE/src/CrowIDE.cs
modifié : CrowIDE/src/ImlVisualEditor.cs
nouveau fichier : CrowIDE/src/Project.cs
nouveau fichier : CrowIDE/src/Solution.cs
nouveau fichier : CrowIDE/src/VerticalLine.cs
nouveau fichier : CrowIDE/ui/ProjectProperties.crow
nouveau fichier : CrowIDE/ui/ProjectTree.template
nouveau fichier : CrowIDE/ui/TreeExpandable.template
modifié : CrowIDE/ui/imlEditor.crow
modifié : Default.style
nouveau fichier : Icons/assembly.svg
nouveau fichier : Templates/Tooltip.template
modifié : Tests/BasicTests.cs
modifié : Tests/HelloWorld.cs
modifié : Tests/Interfaces/Divers/0.crow
modifié : Tests/Interfaces/Divers/testShape.crow
modifié : Tests/Interfaces/Divers/welcome.crow
modifié : Tests/Tests.csproj
modifié : src/CompilerServices/CompilerServices.cs
modifié : src/GraphicObjects/FileDialog.cs
modifié : src/GraphicObjects/GraphicObject.cs
modifié : src/GraphicObjects/MessageBox.cs
modifié : src/Instantiator.cs
modifié : src/Interface.cs
modifié : src/ItemTemplate.cs
Diffstat (limited to 'src')
| -rw-r--r-- | src/CompilerServices/CompilerServices.cs | 60 | ||||
| -rw-r--r-- | src/GraphicObjects/FileDialog.cs | 3 | ||||
| -rw-r--r-- | src/GraphicObjects/GraphicObject.cs | 11 | ||||
| -rw-r--r-- | src/GraphicObjects/MessageBox.cs | 5 | ||||
| -rw-r--r-- | src/GraphicObjects/Popper.cs | 2 | ||||
| -rw-r--r-- | src/Instantiator.cs | 2 | ||||
| -rw-r--r-- | src/Interface.cs | 84 | ||||
| -rw-r--r-- | src/ItemTemplate.cs | 38 |
8 files changed, 167 insertions, 38 deletions
diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs index cb8b75b5..16d28490 100644 --- a/src/CompilerServices/CompilerServices.cs +++ b/src/CompilerServices/CompilerServices.cs @@ -67,6 +67,7 @@ namespace Crow.IML internal static MethodInfo miGetValWithRefx = typeof(CompilerServices).GetMethod("getValueWithReflexion", BindingFlags.Static | BindingFlags.NonPublic); internal static MethodInfo miCreateDel = typeof(CompilerServices).GetMethod ("createDel", BindingFlags.Static | BindingFlags.NonPublic); internal static MethodInfo miGetImplOp = typeof(CompilerServices).GetMethod ("getImplicitOp", BindingFlags.Static | BindingFlags.NonPublic); + internal static MethodInfo miGetDataTypeAndFetch = typeof(CompilerServices).GetMethod("getDataTypeAndFetch", BindingFlags.Static | BindingFlags.NonPublic); internal static MethodInfo miGoUpLevels = typeof(CompilerServices).GetMethod("goUpNbLevels", BindingFlags.Static | BindingFlags.NonPublic); @@ -92,7 +93,7 @@ namespace Crow.IML internal static MethodInfo miGetITempFromDic = typeof(Dictionary<string, ItemTemplate>).GetMethod ("get_Item", new Type[] { typeof(string) }); internal static FieldInfo fldItemTemplates = typeof(TemplatedGroup).GetField("ItemTemplates"); internal static MethodInfo miCreateExpDel = typeof(ItemTemplate).GetMethod ("CreateExpandDelegate"); - + internal static FieldInfo fiFetchMethodName = typeof(ItemTemplate).GetField("fetchMethodName", BindingFlags.Instance | BindingFlags.NonPublic); #region tree handling methods internal static FieldInfo fiChild = typeof(PrivateContainer).GetField ("child", BindingFlags.Instance | BindingFlags.NonPublic); internal static MethodInfo miSetChild = typeof (Container).GetMethod ("SetChild"); @@ -330,22 +331,27 @@ namespace Crow.IML Type dstType = null; if (mi == null) return null; - if (mi.MemberType == MemberTypes.Property) { - PropertyInfo pi = mi as PropertyInfo; - tmp = pi.GetValue (instance); - dstType = pi.PropertyType; - } - if (mi.MemberType == MemberTypes.Field) { - FieldInfo fi = mi as FieldInfo; - tmp = fi.GetValue (instance); - dstType = fi.FieldType; - } - if (tmp != null) - return tmp; - if (dstType == typeof(string) || dstType == CompilerServices.TObject)//TODO:object should be allowed to return null and not "" + try { + if (mi.MemberType == MemberTypes.Property) { + PropertyInfo pi = mi as PropertyInfo; + tmp = pi.GetValue (instance); + dstType = pi.PropertyType; + } + if (mi.MemberType == MemberTypes.Field) { + FieldInfo fi = mi as FieldInfo; + tmp = fi.GetValue (instance); + dstType = fi.FieldType; + } + if (tmp != null) + return tmp; + if (dstType == typeof(string) || dstType == CompilerServices.TObject)//TODO:object should be allowed to return null and not "" + return ""; + if (dstType.IsValueType) + return Activator.CreateInstance (dstType); + } catch (Exception ex) { + Debug.WriteLine (ex.ToString ()); return ""; - if (dstType.IsValueType) - return Activator.CreateInstance (dstType); + } return null; } @@ -863,6 +869,28 @@ namespace Crow.IML } return null; } + + internal static object getDataTypeAndFetch (object data, string fetchMethod){ + Type dataType = data.GetType(); + MethodInfo miGetDatas = dataType.GetMethod (fetchMethod, new Type[] {}); + if (miGetDatas == null) + miGetDatas = CompilerServices.SearchExtMethod (dataType, fetchMethod); + + if (miGetDatas == null) {//in last resort, search among properties + PropertyInfo piDatas = dataType.GetProperty (fetchMethod); + if (piDatas == null) { + FieldInfo fiDatas = dataType.GetField (fetchMethod); + if (fiDatas == null)//and among fields + throw new Exception ("Fetch data member not found in ItemTemplate: " + fetchMethod); + return fiDatas.GetValue (data); + } + miGetDatas = piDatas.GetGetMethod (); + if (miGetDatas == null) + throw new Exception ("Read only property for fetching data in ItemTemplate: " + fetchMethod); + } + object tmp = miGetDatas.Invoke (data, null); + return tmp; + } } } diff --git a/src/GraphicObjects/FileDialog.cs b/src/GraphicObjects/FileDialog.cs index a5ba7b20..285ca253 100644 --- a/src/GraphicObjects/FileDialog.cs +++ b/src/GraphicObjects/FileDialog.cs @@ -52,6 +52,9 @@ namespace Crow public event EventHandler OkClicked; #endregion + public string SelectedFileFullPath { + get { return Path.Combine (SelectedDirectory, SelectedFile); } + } [XmlAttributeAttribute][DefaultValue("/home")] public virtual string CurrentDirectory { get { return curDir; } diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index 3da8330d..e24e9b28 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -808,6 +808,17 @@ namespace Crow NotifyValueChanged ("Style", style); } } + string tooltip; + [XmlAttributeAttribute] + public virtual string Tooltip { + get { return tooltip; } + set { + if (tooltip == value) + return; + tooltip = value; + NotifyValueChanged("Tooltip", tooltip); + } + } #endregion #region Default and Style Values loading diff --git a/src/GraphicObjects/MessageBox.cs b/src/GraphicObjects/MessageBox.cs index 277a7e11..7f945810 100644 --- a/src/GraphicObjects/MessageBox.cs +++ b/src/GraphicObjects/MessageBox.cs @@ -120,7 +120,6 @@ namespace Crow NotifyValueChanged ("MsgIcon", "#Crow.Images.Icons.exit.svg"); Caption = "Error"; OkMessage = "Ok"; - CancelMessage = "Cancel"; break; } } @@ -136,7 +135,7 @@ namespace Crow close (); } public static MessageBox Show (Type msgBoxType, string message, string okMsg = "", string cancelMsg = ""){ - lock (Interface.CurrentInterface.UpdateMutex) { + //lock (Interface.CurrentInterface.UpdateMutex) { MessageBox mb = new MessageBox (Interface.CurrentInterface); mb.CurrentInterface.AddWidget (mb); mb.MsgType = msgBoxType; @@ -146,7 +145,7 @@ namespace Crow if (!string.IsNullOrEmpty(cancelMsg)) mb.CancelMessage = cancelMsg; return mb; - } + //} } } } diff --git a/src/GraphicObjects/Popper.cs b/src/GraphicObjects/Popper.cs index 5316a5a7..41210dc5 100644 --- a/src/GraphicObjects/Popper.cs +++ b/src/GraphicObjects/Popper.cs @@ -224,7 +224,7 @@ namespace Crow if (Content != null) { Content.Visible = true; if (Content.Parent == null) - CurrentInterface.AddWidget (Content, true); + CurrentInterface.AddWidget (Content); if (Content.LogicalParent != this) Content.LogicalParent = this; CurrentInterface.PutOnTop (Content, true); diff --git a/src/Instantiator.cs b/src/Instantiator.cs index b79fbc82..297337ed 100644 --- a/src/Instantiator.cs +++ b/src/Instantiator.cs @@ -560,7 +560,7 @@ namespace Crow.IML System.Reflection.Emit.Label finish = il.DefineLabel (); il.Emit (OpCodes.Br, finish); il.MarkLabel (cancel); - il.EmitWriteLine (string.Format ("Handler method '{0}' for '{1}' not found in new dataSource ", bindingDef.TargetMember, sourceEvent.Name)); + il.EmitWriteLine (string.Format ("Handler method '{0}' for '{1}' not found in new dataSource", bindingDef.TargetMember, sourceEvent.Name)); il.MarkLabel (finish); il.Emit (OpCodes.Ret); diff --git a/src/Interface.cs b/src/Interface.cs index ab78e42d..992ff6f6 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -88,6 +88,8 @@ namespace Crow public Interface(){ CurrentInterface = this; CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture; + + initTooltip (); } #endregion @@ -100,6 +102,8 @@ namespace Crow public static bool FocusOnHover = false; /// <summary> Threshold to catch borders for sizing </summary> public static int BorderThreshold = 5; + /// <summary> delay before tooltip appear </summary> + public static int ToolTipDelay = 500; /// <summary>Double click threshold in milisecond</summary> public static int DoubleClick = 200;//max duration between two mouse_down evt for a dbl clk in milisec. /// <summary> Time to wait in millisecond before starting repeat loop</summary> @@ -313,9 +317,12 @@ namespace Crow return tmp; } } - /// <summary>Create an instance of a GraphicObject and add it to the GraphicTree - /// of this Interface</summary> - public GraphicObject LoadInterface (string path) + /// <summary> + /// Create an instance of a GraphicObject and add it to the GraphicTree of this Interface + /// </summary> + /// <returns>new instance of graphic object created</returns> + /// <param name="path">path of the iml file to load</param> + public GraphicObject AddWidget (string path) { lock (UpdateMutex) { GraphicObject tmp = Load (path); @@ -323,8 +330,11 @@ namespace Crow return tmp; } } - /// <summary>Create an instance of a GraphicObject linked to this interface but - /// not added to the GraphicTree</summary> + /// <summary> + /// Create an instance of a GraphicObject linked to this interface but not added to the GraphicTree + /// </summary> + /// <returns>new instance of graphic object created</returns> + /// <param name="path">path of the iml file to load</param> public GraphicObject Load (string path) { try { @@ -333,7 +343,11 @@ namespace Crow throw new Exception ("Error loading <" + path + ">:", ex); } } - /// <summary>Fetch instantiator it from cache or create it</summary> + /// <summary> + /// Fetch instantiator from cache or create it. + /// </summary> + /// <returns>new Instantiator</returns> + /// <param name="path">path of the iml file to load</param> public static Instantiator GetInstantiator(string path){ if (!Instantiators.ContainsKey(path)) Instantiators [path] = new Instantiator(path); @@ -626,7 +640,7 @@ namespace Crow #region GraphicTree handling /// <summary>Add widget to the Graphic tree of this interface and register it for layouting</summary> - public void AddWidget(GraphicObject g, bool isOverlay = false) + public void AddWidget(GraphicObject g) { g.Parent = this; int ptr = 0; @@ -648,7 +662,7 @@ namespace Crow g.RegisteredLayoutings = LayoutingType.None; g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren); } - /// <summary>Set visible state of widget to false and remove if from the graphic tree</summary> + /// <summary>Set visible state of widget to false and delete if from the graphic tree</summary> public void DeleteWidget(GraphicObject g) { lock (UpdateMutex) { @@ -658,6 +672,15 @@ namespace Crow g.Dispose (); } } + /// <summary>Set visible state of widget to false and remove if from the graphic tree</summary> + public void RemoveWidget(GraphicObject g) + { + lock (UpdateMutex) { + RegisterClip (g.ScreenCoordinates (g.LastPaintedSlot)); + GraphicTree.Remove (g); + g.Parent = null; + } + } /// <summary> Remove all Graphic objects from top container </summary> public void ClearInterface() { @@ -770,6 +793,7 @@ namespace Crow } if (HoverWidget != null) { + resetTooltip (); //check topmost graphicobject first GraphicObject tmp = HoverWidget; GraphicObject topc = null; @@ -947,6 +971,50 @@ namespace Crow } #endregion + #region Tooltip handling + Stopwatch tooltipTimer = new Stopwatch(); + GraphicObject ToolTipContainer = null; + volatile bool tooltipVisible = false; + + void initTooltip () { + ToolTipContainer = Load ("#Crow.Tooltip.template"); + Thread t = new Thread (toolTipThreadFunc); + t.IsBackground = true; + t.Start (); + } + void toolTipThreadFunc () + { + while(true) { + if (tooltipTimer.ElapsedMilliseconds > ToolTipDelay) { + if (!tooltipVisible) { + GraphicObject g = _hoverWidget; + while (g != null) { + if (!string.IsNullOrEmpty (g.Tooltip)) { + AddWidget (ToolTipContainer); + ToolTipContainer.DataSource = g; + ToolTipContainer.Top = Mouse.Y + 10; + ToolTipContainer.Left = Mouse.X + 10; + tooltipVisible = true; + break; + } + g = g.LogicalParent as GraphicObject; + } + } + } + Thread.Sleep (200); + } + + } + void resetTooltip () { + if (tooltipVisible) { + //ToolTipContainer.DataSource = null; + RemoveWidget (ToolTipContainer); + tooltipVisible = false; + } + tooltipTimer.Restart (); + } + #endregion + #region Device Repeat Events volatile bool mouseRepeatOn, keyboardRepeatOn; volatile int mouseRepeatCount, keyboardRepeatCount; diff --git a/src/ItemTemplate.cs b/src/ItemTemplate.cs index 915aafd8..52bd5207 100644 --- a/src/ItemTemplate.cs +++ b/src/ItemTemplate.cs @@ -97,11 +97,14 @@ namespace Crow /// </summary> /// <param name="host">Host.</param> public void CreateExpandDelegate (TemplatedGroup host){ - Type dataType = CompilerServices.tryGetType(strDataType); - if (dataType == null) { - Debug.WriteLine ("ItemTemplate error: DataType not found: {0}.", strDataType); - return; - } + Type dataType = null; + //if (host.DataTest == "TypeOf"){ + dataType = CompilerServices.tryGetType(strDataType); +// if (dataType == null) { +// Debug.WriteLine ("ItemTemplate error: DataType not found: {0}.", strDataType); +// return; +// } +// } Type tmpGrpType = typeof(TemplatedGroup); Type evtType = typeof(EventHandler); @@ -153,9 +156,16 @@ namespace Crow il.Emit (OpCodes.Ldarg_1);//get the dataSource of the sender il.Emit (OpCodes.Callvirt, CompilerServices.miGetDataSource); - if (fetchMethodName != "self")//special keyword self allows the use of recurent list<<< - emitGetSubData(il, dataType); + if (fetchMethodName != "self") {//special keyword self allows the use of recurent list<<< + if (dataType == null) { + //dataTest was not = TypeOF, so we have to get the type of data + //dynamically and fetch + il.Emit (OpCodes.Ldstr, fetchMethodName); + il.Emit (OpCodes.Callvirt, CompilerServices.miGetDataTypeAndFetch); + }else + emitGetSubData(il, dataType); + } //set 'return' from the fetch method as 'data' of the list il.Emit (OpCodes.Callvirt, piData.GetSetMethod ()); @@ -175,8 +185,16 @@ namespace Crow il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Callvirt, CompilerServices.miGetDataSource); - if (fetchMethodName != "self") - emitGetSubData(il, dataType); + if (fetchMethodName != "self") {//special keyword self allows the use of recurent list<<< + if (dataType == null) { + //dataTest was not = TypeOF, so we have to get the type of data + //dynamically and fetch + + il.Emit (OpCodes.Ldstr, fetchMethodName); + il.Emit (OpCodes.Callvirt, CompilerServices.miGetDataTypeAndFetch); + }else + emitGetSubData(il, dataType); + } il.Emit (OpCodes.Callvirt, CompilerServices.miGetColCount); il.Emit (OpCodes.Ldc_I4_0); @@ -185,6 +203,8 @@ namespace Crow HasSubItems = (BooleanTestOnInstance)dm.CreateDelegate (typeof(BooleanTestOnInstance)); #endregion } + + //data is on the stack void emitGetSubData(ILGenerator il, Type dataType){ MethodInfo miGetDatas = dataType.GetMethod (fetchMethodName, new Type[] {}); if (miGetDatas == null) |