aboutsummaryrefslogtreecommitdiffstatsci
path: root/src
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2018-02-09 18:46:40 +0100
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2018-02-09 18:46:40 +0100
commit49c7adb31d17bfc9f5349f8c8343a4ca6318d3aa (patch)
tree2b9b882a9451d97fc635016f98f9b3c2ba90506c /src
parent829d1de43b5a9b39ace2f01eeecae5255f01ed1f (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.cs60
-rw-r--r--src/GraphicObjects/FileDialog.cs3
-rw-r--r--src/GraphicObjects/GraphicObject.cs11
-rw-r--r--src/GraphicObjects/MessageBox.cs5
-rw-r--r--src/GraphicObjects/Popper.cs2
-rw-r--r--src/Instantiator.cs2
-rw-r--r--src/Interface.cs84
-rw-r--r--src/ItemTemplate.cs38
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)