diff options
23 files changed, 186 insertions, 131 deletions
diff --git a/Crow/Default.style b/Crow/Default.style index 16d64f57..e89da49f 100644 --- a/Crow/Default.style +++ b/Crow/Default.style @@ -7,6 +7,8 @@ ControlCaptionHoverColor = "White"; ControlCornerRadius = "0"; ControlInsideMargin = "1"; +ButtonCaptionMargin = "6"; + IconSize = "11"; IconMargin = "1"; ToggleIconSize = "16"; @@ -77,6 +79,14 @@ Button { Height = "Fit"; Width = "Fit"; } +ButtonBorder { + BorderWidth="1"; + Foreground="Transparent"; + MouseEnter="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}"; + MouseLeave="{Foreground=Transparent}"; + MouseDown="{Foreground=vgradient|0:Black|0.05:Grey|0.85:Grey|1:White}"; + MouseUp="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}"; +} Label { Height = "Fit"; Width = "Fit"; diff --git a/Crow/Templates/Button.template b/Crow/Templates/Button.template index daa09c6a..9ad621d9 100644 --- a/Crow/Templates/Button.template +++ b/Crow/Templates/Button.template @@ -1,9 +1,4 @@ <?xml version="1.0"?> -<Border Background="{./Background}" Name="Content" - Foreground="Transparent" CornerRadius="{../CornerRadius}" BorderWidth="1" - MouseEnter="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}" - MouseLeave="{Foreground=Transparent}" - MouseDown="{Foreground=vgradient|0:Black|0.05:Grey|0.85:Grey|1:White}" - MouseUp="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}" > - <Label Font="{./Font}" Name="caption" Margin="6" Foreground="{./Foreground}" Text="{./Caption}"/> +<Border Style="ButtonBorder" Background="{./Background}" Name="Content" CornerRadius="{../CornerRadius}" > + <Label Font="{./Font}" Name="caption" Margin="${ButtonCaptionMargin}" Foreground="{./Foreground}" Text="{./Caption}"/> </Border> diff --git a/Crow/Templates/DefaultItem.template b/Crow/Templates/DefaultItem.template index f2d7102d..c05a3def 100644 --- a/Crow/Templates/DefaultItem.template +++ b/Crow/Templates/DefaultItem.template @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<ListItem Height="Fit" Margin="0" Focusable="true" HorizontalAlignment="Left" +<ListItem Height="Fit" Margin="0" Focusable="true" HorizontalAlignment="Left" Selected = "{Background=${ControlHighlight}}" Unselected = "{Background=Transparent}"> <Label Text="{}" HorizontalAlignment="Left" /> diff --git a/Crow/Templates/Expandable.template b/Crow/Templates/Expandable.template index efa24b92..fc660644 100644 --- a/Crow/Templates/Expandable.template +++ b/Crow/Templates/Expandable.template @@ -5,7 +5,7 @@ <Image Style="Icon" MouseDown="./onClickForExpand" MouseEnter="{Background=White}" MouseLeave="{Background=Transparent}" Background="{./Background}" - Path="#Crow.Icons.expandable.svg" Visible="{./IsExpandable}" SvgSub="{./IsExpanded}" /> + Path="#Crow.Icons.expandable.svg" Visible="{./IsExpandable}" SvgSub="{./IsExpanded}" /> <Label Style="ControlCaption" Text="{./Caption}"/> </HorizontalStack> <Container Name="Content" Visible="false"/> diff --git a/Crow/Templates/WindowButton.template b/Crow/Templates/WindowButton.template index 19ce8f90..f03caf67 100644 --- a/Crow/Templates/WindowButton.template +++ b/Crow/Templates/WindowButton.template @@ -3,7 +3,7 @@ <Template> <Border Style="WindowIconBorder" IsVisible="{./IsEnabled}"> <Image Path="{./Icon}" Tooltip="{./Caption}"/> - </Border> + </Border> </Template> </Button> diff --git a/Crow/Templates/imgItem.template b/Crow/Templates/imgItem.template index 9dbf23d5..a0861fdb 100644 --- a/Crow/Templates/imgItem.template +++ b/Crow/Templates/imgItem.template @@ -1,5 +1,5 @@ <?xml version="1.0"?> - <VerticalStack Width="0" Height="-1" Focusable="true" + <VerticalStack Width="0" Height="-1" Focusable="true" MouseEnter="{Background=RoyalBlue}" MouseLeave="{Background=Transparent}"> <Image Width="-1" Height="-1" Path="{FullName}" MaximumSize="80,80"/> diff --git a/Crow/src/IML/Instantiator.cs b/Crow/src/IML/Instantiator.cs index 7a2472ae..087d4f97 100644 --- a/Crow/src/IML/Instantiator.cs +++ b/Crow/src/IML/Instantiator.cs @@ -26,14 +26,14 @@ namespace Crow.IML { public delegate object InstanciatorInvoker(Interface iface); /// <summary> - /// Reflexion being very slow, the settings of the starting values for widgets are set by a dynamic method. + /// Reflection being very slow, the settings of the starting values for widgets are set by a dynamic method. /// This method is created on the first instacing and is recalled for further widget instancing. - /// + /// /// It includes: /// - XML values setting /// - Default values (appearing as attribute in C#) loading /// - Styling - /// + /// /// Their are stored in the Interface with their path as key, and inlined template /// and itemtemplate are stored with a generated uuid /// </summary> @@ -62,7 +62,7 @@ namespace Crow.IML { #endif #region CTOR - static XmlReaderSettings xmlReaderSettings; + static XmlReaderSettings xmlReaderSettings; static string NT_template, NT_iTemp, NT_style, NT_name, NT_dataSource, NT_dataSourceType; static Instantiator () { NameTable names = new NameTable (); @@ -76,13 +76,13 @@ namespace Crow.IML { xmlReaderSettings = new XmlReaderSettings (); xmlReaderSettings.NameTable = names; - + } /// <summary> /// Initializes a new instance of the Instantiator class. /// </summary> public Instantiator (Interface _iface, string path) : this (_iface, _iface.GetStreamFromPath(path), path) { - + } /// <summary> /// Initializes a new instance of the Instantiator class. @@ -231,7 +231,7 @@ namespace Crow.IML { ctx.curLine += li.LineNumber - 1; #endif - string tmpXml = reader.ReadOuterXml (); + string tmpXml = reader.ReadOuterXml (); if (ctx.nodesStack.Peek().HasTemplate) emitTemplateLoad (ctx, tmpXml); @@ -246,7 +246,7 @@ namespace Crow.IML { /// <returns>the string triplet dataType, itemTmpID read as attribute of this tag</returns> /// <param name="reader">current xml text reader</param> /// <param name="itemTemplatePath">file containing the templates if its a dedicated one</param> - string[] parseItemTemplateTag (IMLContext ctx, XmlReader reader, string itemTemplatePath = "") { + string[] parseItemTemplateTag (XmlReader reader, string itemTemplatePath = "") { string dataType = "default", datas = "", path = "", dataTest = "TypeOf"; while (reader.MoveToNextAttribute ()) { if (reader.Name == "DataType") @@ -270,7 +270,7 @@ namespace Crow.IML { } else { if (!reader.IsEmptyElement) throw new Exception ("ItemTemplate with Path attribute set may not include sub nodes"); - itemTmpID += path+dataType+datas; + itemTmpID += $"{path}{dataType}{datas}"; if (!iface.ItemTemplates.ContainsKey (itemTmpID)) iface.ItemTemplates [itemTmpID] = new ItemTemplate (iface, path, dataTest, dataType, datas); @@ -308,7 +308,7 @@ namespace Crow.IML { reader.Read (); readChildren (reader, ctx, -1); } else if (reader.Name == NT_iTemp) - itemTemplateIds.Add (parseItemTemplateTag (ctx, reader)); + itemTemplateIds.Add (parseItemTemplateTag (reader)); } if (!inlineTemplate) {//load from path or default template @@ -331,7 +331,7 @@ namespace Crow.IML { using (Stream stream = iface.GetStreamFromPath (itemTemplatePath)) { //itemtemplate files may have multiple root nodes XmlReaderSettings itrSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment }; - using (XmlReader itr = XmlReader.Create (stream, itrSettings)) { + using (XmlReader itr = XmlReader.Create (stream, itrSettings)) { while (itr.Read ()) { if (!itr.IsStartElement ()) continue; @@ -343,7 +343,7 @@ namespace Crow.IML { itemTemplateIds.Add (new string [] { "default", itemTemplatePath, "", "TypeOf" }); break;//we should be at the end of the file } - itemTemplateIds.Add (parseItemTemplateTag (ctx, itr, itemTemplatePath)); + itemTemplateIds.Add (parseItemTemplateTag (itr, itemTemplatePath)); } } } @@ -356,7 +356,7 @@ namespace Crow.IML { //add the default item template if no default is defined if (!itemTemplateIds.Any(ids=>ids[0] == "default")) itemTemplateIds.Add (new string [] { "default", "#Crow.DefaultItem.template", "", "TypeOf"}); - //get item templates + //get item templates foreach (string [] iTempId in itemTemplateIds) { ctx.il.Emit (OpCodes.Ldloc_0);//load TempControl ref ctx.il.Emit (OpCodes.Ldfld, CompilerServices.fldItemTemplates);//load ItemTemplates dic field @@ -433,12 +433,12 @@ namespace Crow.IML { #endif } //check for dataSourceType, if set, datasource bindings will use direct setter/getter - //instead of reflexion + //instead of reflection string dataSourceType = reader.GetAttribute (NT_dataSourceType); if (string.IsNullOrEmpty (dataSourceType)) { //if not set but dataSource is not null, reset dsType to null string ds = reader.GetAttribute (NT_dataSource); - if (!string.IsNullOrEmpty (ds)) + if (!string.IsNullOrEmpty (ds)) ctx.SetDataSourceTypeForCurrentNode (null); } else ctx.SetDataSourceTypeForCurrentNode(CompilerServices.getTypeFromName (dataSourceType)); @@ -447,7 +447,6 @@ namespace Crow.IML { ctx.il.Emit (OpCodes.Call, CompilerServices.miLoadDefaultVals); #endregion - #region Attributes reading if (reader.HasAttributes) { @@ -477,7 +476,7 @@ namespace Crow.IML { if (string.IsNullOrEmpty (cstId) || !iface.StylingConstants.ContainsKey (cstId)) throw new Exception ("undefined constant id: " + cstId); styledValue.Append (iface.StylingConstants [cstId]); - continue; + continue; } } styledValue.Append (imlValue [vPtr++]); @@ -552,10 +551,10 @@ namespace Crow.IML { if (t == null) throw new Exception (reader.Name + " type not found"); ConstructorInfo ci = t.GetConstructor ( - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, + BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Type.EmptyTypes, null); if (ci == null) - throw new Exception ("No default parameterless constructor found in " + t.Name); + throw new Exception ("No default parameterless constructor found in " + t.Name); ctx.il.Emit (OpCodes.Newobj, ci); ctx.il.Emit (OpCodes.Stloc_0);//child is now loc_0 CompilerServices.emitSetCurInterface (ctx.il); @@ -804,7 +803,7 @@ namespace Crow.IML { il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS); il.Emit (OpCodes.Ldstr, bindingDef.TargetMember);//load handler method name il.Emit (OpCodes.Call, CompilerServices.miGetMethInfoWithRefx); - il.Emit (OpCodes.Stloc_0);//save MethodInfo + il.Emit (OpCodes.Stloc_0);//save MethodInfo il.Emit (OpCodes.Ldloc_0);//push mi for test if null il.Emit (OpCodes.Brfalse, cancel);//cancel if null @@ -821,19 +820,19 @@ namespace Crow.IML { il.Emit (OpCodes.Call, CompilerServices.miCreateBoundDel); il.Emit (OpCodes.Callvirt, sourceEvent.AddMethod);//call add event - + System.Reflection.Emit.Label finish = il.DefineLabel (); il.Emit (OpCodes.Br, finish); il.MarkLabel (cancel); - //#if DEBUG_BINDING - //TODO: try to print datasource type in the error message + //#if DEBUG_BINDING + //TODO: try to print datasource type in the error message il.EmitWriteLine (string.Format ("Handler method '{0}' for '{1}' NOT FOUND in new dataSource", bindingDef.TargetMember, sourceEvent.Name)); //#endif il.MarkLabel (finish); #if DEBUG_BINDING il.EmitWriteLine (string.Format ("Handler method '{0}' for '{1}' FOUND in new dataSource", bindingDef.TargetMember, sourceEvent.Name)); #endif - + il.Emit (OpCodes.Ret); //store dschange delegate in instatiator instance for access while instancing graphic object @@ -1314,10 +1313,10 @@ namespace Crow.IML { } /// <summary> - /// create the valuechanged handler and the datasourcechanged handler and return the + /// create the valuechanged handler and the datasourcechanged handler and return the /// DataSourceChange delegate /// </summary> - public Delegate emitDataSourceBindings (PropertyInfo piSource, BindingDefinition bindingDef){ + public Delegate emitDataSourceBindings (PropertyInfo piSource, BindingDefinition bindingDef){ #if DEBUG_BINDING_FUNC_CALLS Console.WriteLine ($"emitDataSourceBindings: {bindingDef}"); @@ -1431,7 +1430,7 @@ namespace Crow.IML { il.Emit (OpCodes.Ldloc_2);//load datasource il.Emit (OpCodes.Ldloc_3);//load first memberInfo il.Emit (OpCodes.Call, CompilerServices.miGetValWithRefx);//get first member level - } + } il.Emit (OpCodes.Ldstr, bindingDef.TargetMember);//load member name il.Emit (OpCodes.Call, CompilerServices.miGetMembIinfoWithRefx); il.Emit (OpCodes.Stloc_1);//save memberInfo diff --git a/Crow/src/IToggle.cs b/Crow/src/IToggle.cs index 54564be4..6a47b404 100644 --- a/Crow/src/IToggle.cs +++ b/Crow/src/IToggle.cs @@ -11,7 +11,7 @@ namespace Crow event EventHandler ToggleOn; event EventHandler ToggleOff; BooleanTestOnInstance IsToggleable { get; set; } - + bool IsToggled { get; set; diff --git a/Crow/src/ItemTemplate.cs b/Crow/src/ItemTemplate.cs index dc8e29c0..9fcbd7fb 100644 --- a/Crow/src/ItemTemplate.cs +++ b/Crow/src/ItemTemplate.cs @@ -22,16 +22,16 @@ namespace Crow /// <summary> /// Derived from Instantiator with sub data fetching facilities for hierarchical data access. - /// + /// /// ItemTemplate stores the dynamic method for instantiating the control tree defined in a valid IML file. - /// + /// /// </summary> public class ItemTemplate : Instantiator { #if DESIGN_MODE - public void getIML (System.Xml.XmlDocument doc, System.Xml.XmlNode parentElem){ + public void getIML (System.Xml.XmlDocument doc, System.Xml.XmlNode parentElem){ if (sourcePath == "#Crow.DefaultItem.template") return; - + XmlElement xe = doc.CreateElement("ItemTemplate"); XmlAttribute xa = null; @@ -62,10 +62,10 @@ namespace Crow xa.Value = fetchMethodName; xe.Attributes.Append (xa); } - + parentElem.AppendChild (xe); - + } #endif @@ -137,14 +137,14 @@ namespace Crow //DM is bound to templatedGroup root (arg0) //arg1 is the sender of the expand event DynamicMethod dm = new DynamicMethod ("dyn_expand_" + fetchMethodName, - typeof (void), args, typeof(TemplatedGroup), true); + typeof (void), args, typeof(TemplatedGroup), true); System.Reflection.Emit.Label gotoEnd; System.Reflection.Emit.Label ifDataIsNull; System.Reflection.Emit.Label gotoItemsContainerNotFound; - ILGenerator il = dm.GetILGenerator (256); - + ILGenerator il = dm.GetILGenerator (256); + il.DeclareLocal(typeof(Widget)); il.DeclareLocal(typeof(IEnumerable)); @@ -182,7 +182,7 @@ namespace Crow il.Emit (OpCodes.Ldstr, fetchMethodName); il.Emit (OpCodes.Call, CompilerServices.miGetDataTypeAndFetch); }else - emitGetSubData(il, dataType); + emitGetSubData(il, dataType); } il.Emit (OpCodes.Stloc_1);//save and reload datas IEnumerable for registering IObsList il.Emit (OpCodes.Ldloc_1); @@ -220,7 +220,7 @@ namespace Crow //dm is unbound, arg0 is instance of Item container to expand dm = new DynamicMethod ("dyn_count_" + fetchMethodName, typeof (bool), new Type[] {typeof(object)}, true); - il = dm.GetILGenerator (256); + il = dm.GetILGenerator (256); System.Reflection.Emit.Label end = il.DefineLabel (); System.Reflection.Emit.Label test = il.DefineLabel (); @@ -236,18 +236,18 @@ namespace Crow il.Emit (OpCodes.Ldstr, fetchMethodName); il.Emit (OpCodes.Call, CompilerServices.miGetDataTypeAndFetch); }else - emitGetSubData(il, dataType); - } + emitGetSubData(il, dataType); + } il.Emit (OpCodes.Isinst, typeof(System.Collections.ICollection)); il.Emit (OpCodes.Dup);//duplicate children for testing if it's a collection for childs counting il.Emit (OpCodes.Brtrue, test);//if true, jump to perform count il.Emit (OpCodes.Pop);//pop null - il.Emit (OpCodes.Ldc_I4_0);//push false + il.Emit (OpCodes.Ldc_I4_0);//push false il.Emit (OpCodes.Br, end); il.MarkLabel (test); - il.Emit (OpCodes.Callvirt, CompilerServices.miGetColCount); + il.Emit (OpCodes.Callvirt, CompilerServices.miGetColCount); il.Emit (OpCodes.Ldc_I4_0); il.Emit (OpCodes.Cgt); diff --git a/Crow/src/Widgets/DockWindow.cs b/Crow/src/Widgets/DockWindow.cs index 763da1aa..326bfce4 100644 --- a/Crow/src/Widgets/DockWindow.cs +++ b/Crow/src/Widgets/DockWindow.cs @@ -102,7 +102,7 @@ namespace Crow NotifyValueChangedAuto (floatingGroup); } } - + bool tryGetTargetDockStack (DockWindow dw, out DockStack ds) { if (dw.Parent is DockStack dwp) ds = dwp; @@ -114,12 +114,12 @@ namespace Crow } bool dockParentParent = false; public override void onDrag (object sender, MouseMoveEventArgs e) - { + { if (!freezeDockState && isDocked) checkUndock (e.Position); else moveAndResize (e.XDelta, e.YDelta, currentDirection); - + base.onDrag (sender, e); if (freezeDockState || isDocked) @@ -146,7 +146,7 @@ namespace Crow } else { dwCb = r; dwCb.Inflate (-4,-4); - + if (tryGetTargetDockStack (dw, out DockStack targetStack)) { Console.WriteLine ($"exterior: {!dwCb.ContainsOrIsEqual (m)} targetStack.Parent: {targetStack.Parent.GetType()}"); if (dwCb.ContainsOrIsEqual (m)) { @@ -157,7 +157,7 @@ namespace Crow r = targetStack.ScreenCoordinates (targetStack.LastPaintedSlot); } else r = dw.ScreenCoordinates (dw.LastPaintedSlot); - + targetStack.onDragMouseMove (this, e); } else System.Diagnostics.Debugger.Break (); @@ -241,7 +241,7 @@ namespace Crow else if (tryGetTargetDockStack (dw, out DockStack targetStack)) { if (dockParentParent) targetStack = targetStack.Parent as DockStack; - Dock (targetStack); + Dock (targetStack); }else System.Diagnostics.Debugger.Break (); }else @@ -274,8 +274,8 @@ namespace Crow } else if (Parent is DockStack ds) { ds.Undock (this); } else - throw new Exception ("docking error"); - + throw new Exception ("docking error"); + IFace.AddWidget (this); Left = IFace.MousePosition.X - 10; @@ -335,11 +335,11 @@ namespace Crow target.NotifyValueChanged ("IsDockedInStack", false); IsDocked = true; - } + } } } void Dock (DockStack target){ - lock (IFace.UpdateMutex) { + lock (IFace.UpdateMutex) { dock (); target.Dock (this); @@ -356,7 +356,6 @@ namespace Crow internal string GetDockConfigString () => string.Format($"WIN;{Name};{Width};{Height};{DockingPosition};{savedSlot};{wasResizable};"); - public string FloatingConfigString => $"{Name};{Left};{Top};{Width};{Height};{FreezeDockState};{Resizable}"; public static DockWindow CreateFromFloatingConfigString (Interface iface, ReadOnlySpan<char> conf, object datasource = null) { @@ -374,7 +373,7 @@ namespace Crow dw.Height = Measure.Parse (conf.Slice(0, i).ToString()); conf = conf.Slice (i + 1); i = conf.IndexOf (';'); dw.FreezeDockState = bool.Parse (conf.Slice(0, i).ToString()); - + dw.Resizable = bool.Parse (conf.Slice (i + 1).ToString()); dw.DataSource = datasource; diff --git a/Crow/src/Widgets/GroupBase.cs b/Crow/src/Widgets/GroupBase.cs index 13d99f0a..8c98d0b6 100644 --- a/Crow/src/Widgets/GroupBase.cs +++ b/Crow/src/Widgets/GroupBase.cs @@ -37,7 +37,7 @@ namespace Crow return; base.getIML (doc, parentElem); foreach (Widget g in Children) { - g.getIML (doc, parentElem.LastChild); + g.getIML (doc, parentElem.LastChild); } } #endif @@ -94,7 +94,7 @@ namespace Crow return; } childrenRWLock.EnterWriteLock (); - try { + try { g.Parent = this; Children.Insert (idx, g); } finally { @@ -129,7 +129,7 @@ namespace Crow try { foreach (Widget g in Children) { if (g.localDataSourceIsNull & g.localLogicalParentIsNull) - g.OnDataSourceChanged (g, e); + g.OnDataSourceChanged (g, e); } } finally { childrenRWLock.ExitReadLock (); @@ -161,7 +161,7 @@ namespace Crow } } finally { childrenRWLock.ExitWriteLock (); - } + } } #region GraphicObject overrides @@ -186,7 +186,7 @@ namespace Crow childrenRWLock.ExitReadLock (); } } - public override T FindByType<T> () + public override T FindByType<T> () { if (this is T t) return t; @@ -224,7 +224,7 @@ namespace Crow { DbgLogger.StartEvent (DbgEvtType.GODraw, this); - base.onDraw (gr); + base.onDraw (gr); if (ClipToClientRect) { gr.Save (); @@ -236,7 +236,7 @@ namespace Crow childrenRWLock.EnterReadLock (); try { - for (int i = 0; i < Children.Count; i++) + for (int i = 0; i < Children.Count; i++) Children[i].Paint (gr); } finally { childrenRWLock.ExitReadLock (); @@ -256,7 +256,7 @@ namespace Crow gr.Rectangle(Clipping.GetRectangle(i)); gr.ClipPreserve(); gr.Operator = Operator.Clear; - gr.Fill(); + gr.Fill(); gr.Operator = Operator.Over; base.onDraw (gr); @@ -291,7 +291,7 @@ namespace Crow Console.WriteLine("GROUP REPAINT WITH EMPTY CLIPPING");*/ //paintCache (ctx, Slot + Parent.ClientRectangle.Position); base.UpdateCache (ctx); - DbgLogger.EndEvent(DbgEvtType.GOUpdateCache); + DbgLogger.EndEvent(DbgEvtType.GOUpdateCache); } #endregion diff --git a/Crow/src/Widgets/TemplatedControl.cs b/Crow/src/Widgets/TemplatedControl.cs index 4a1c320a..a50352ee 100644 --- a/Crow/src/Widgets/TemplatedControl.cs +++ b/Crow/src/Widgets/TemplatedControl.cs @@ -88,7 +88,7 @@ namespace Crow /// <param name="gr">Backend context</param> protected override void onDraw (Context gr) { - DbgLogger.StartEvent (DbgEvtType.GODraw, this); + DbgLogger.StartEvent (DbgEvtType.GODraw, this); if (ClipToClientRect) { //clip to client zone @@ -96,7 +96,7 @@ namespace Crow CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); gr.Clip (); } - + child?.Paint (gr); if (ClipToClientRect) @@ -108,6 +108,7 @@ namespace Crow /// <summary> /// Loads the template. Each TemplatedControl MUST provide a default template + /// or have an inlined template in iml. /// It must be an embedded ressource with ID = fullTypeName.template /// Entry assembly is search first, then the one where the type is defined /// </summary> @@ -116,11 +117,11 @@ namespace Crow { if (this.child != null)//template change, bindings has to be reset this.ClearTemplateBinding(); - + if (template == null) { string defTmpId = this.GetType ().FullName + ".template"; if (!IFace.DefaultTemplates.ContainsKey (defTmpId)) { - + Stream s = IFace.GetStreamFromPath ("#" + defTmpId); if (s == null) throw new Exception (string.Format ("No default template found for '{0}'", this.GetType ().FullName)); diff --git a/Crow/src/Widgets/TemplatedGroup.cs b/Crow/src/Widgets/TemplatedGroup.cs index 11a206e9..9ec8cb5e 100644 --- a/Crow/src/Widgets/TemplatedGroup.cs +++ b/Crow/src/Widgets/TemplatedGroup.cs @@ -22,12 +22,12 @@ namespace Crow { base.getIML (doc, parentElem); if (string.IsNullOrEmpty(_itemTemplate)) { - foreach (ItemTemplate it in ItemTemplates.Values) - it.getIML (doc, parentElem.LastChild); + foreach (ItemTemplate it in ItemTemplates.Values) + it.getIML (doc, parentElem.LastChild); } foreach (Widget g in Items) { - g.getIML (doc, parentElem.LastChild); + g.getIML (doc, parentElem.LastChild); } } #endif @@ -84,13 +84,13 @@ namespace Crow { internal List<Widget> nodes = new List<Widget>();//TODO:close time tracking /// <summary> /// Item templates file path, on disk or embedded. - /// + /// /// ItemTemplate file may contains either a single template without the /// ItemTemplate enclosing tag, or several item templates each enclosed /// in a separate tag. - /// </summary> + /// </summary> public string ItemTemplate { - get { return _itemTemplate; } + get => _itemTemplate; set { if (value == _itemTemplate) return; @@ -150,7 +150,7 @@ namespace Crow { set { if (selectedItem == value) return; - + if (selectedItem is ISelectable oldItem) oldItem.IsSelected = false; @@ -195,7 +195,7 @@ namespace Crow { ol.ListRemove -= Ol_ListRemove; ol.ListEdit -= Ol_ListEdit; ol.ListClear -= Ol_ListClear; - + } data = value; @@ -218,11 +218,11 @@ namespace Crow { if (data is ICollection c) { if (c.Count == 0) { - NotifyValueChanged ("HasItems", false); + NotifyValueChanged ("HasItems", false); return; } } - + if (useLoadingThread) { loadingThread = new CrowThread (this, loading); loadingThread.Finished += (object sender, EventArgs e) => (sender as TemplatedGroup).Loaded.Raise (sender, e); @@ -260,7 +260,7 @@ namespace Crow { } else loadItem (e.Element, itemsContainer, dataTest); } - void Ol_ListEdit (object sender, ListChangedEventArg e) { + void Ol_ListEdit (object sender, ListChangedEventArg e) { if (this.isPaged) { throw new NotImplementedException (); } else if (e.Index<itemsContainer.Children.Count) @@ -268,7 +268,7 @@ namespace Crow { } void Ol_ListClear (object sender, ListClearEventArg e) { - cancelLoadingThread (); + cancelLoadingThread (); if (this.isPaged) { throw new NotImplementedException (); } else { @@ -281,13 +281,13 @@ namespace Crow { SelectedItemChanged.Raise (this, new SelectionChangeEventArgs (SelectedItem)); } public virtual void AddItem(Widget g){ - + itemsContainer.AddChild (g); g.LogicalParent = this; NotifyValueChanged ("HasChildren", true); } public virtual void RemoveItem(Widget g, bool disposeChild = true) - { + { if (disposeChild) itemsContainer.DeleteChild (g); else @@ -367,7 +367,7 @@ namespace Crow { } catch (Exception ex) { /* while (Monitor.IsEntered (IFace.UpdateMutex)) Monitor.Exit (IFace.UpdateMutex); - while (Monitor.IsEntered (IFace.LayoutMutex)) + while (Monitor.IsEntered (IFace.LayoutMutex)) Monitor.Exit (IFace.LayoutMutex);*/ System.Diagnostics.Debug.WriteLine ("loading thread aborted: " + ex.ToString()); } finally { @@ -401,7 +401,7 @@ namespace Crow { while (Monitor.IsEntered (IFace.LayoutMutex)) { Monitor.Exit (IFace.LayoutMutex); layoutMx++; - }*/ + }*/ loadingThread.Cancel (); @@ -411,7 +411,7 @@ namespace Crow { Monitor.Enter (IFace.UpdateMutex);*/ loadingThread = null; - + DbgLogger.EndEvent (DbgEvtType.TGCancelLoadingThread); } void loadPage(IEnumerable _data, Group page, string _dataTest) @@ -464,7 +464,7 @@ namespace Crow { string itempKey = dataType.FullName; //if item template selection is not done depending on the type of item - //dataTest must contains a member name of the item + //dataTest must contains a member name of the item if (_dataTest != "TypeOf") { try { itempKey = CompilerServices.getValue (dataType, o, _dataTest)?.ToString (); @@ -499,7 +499,7 @@ namespace Crow { Thread.Sleep(1); } } - + try { g = iTemp.CreateInstance(); #if DESIGN_MODE @@ -518,11 +518,11 @@ namespace Crow { if (iTemp.Expand != null) { IToggle toggle = g as IToggle; - + if (toggle == null) toggle = g.FindByType<IToggle> (); - - if (toggle != null) { + + if (toggle != null) { toggle.ToggleOn += iTemp.Expand; toggle.IsToggleable = iTemp.HasSubItems; } @@ -591,7 +591,7 @@ namespace Crow { } internal virtual void itemClick(object sender, MouseButtonEventArgs e){ //SelectedIndex = (int)((IList)data)?.IndexOf((sender as Widget).DataSource); - + if (sender is ISelectable nli) { nli.IsSelected = true; return; @@ -599,7 +599,7 @@ namespace Crow { selectedItemContainer = sender as Widget; if (selectedItemContainer == null) return; - SelectedItem = selectedItemContainer.DataSource; + SelectedItem = selectedItemContainer.DataSource; } bool emitHelperIsAlreadyExpanded (Widget go){ @@ -642,11 +642,11 @@ namespace Crow { ol.ListEdit += (sender, e) => itemsContainer.Children [e.Index].DataSource = e.Element; ol.ListClear += (sender, e) => { lock (IFace.UpdateMutex) itemsContainer.ClearChildren ();}; - + }*/ } void onDatasChanged (object sender, ValueChangeEventArgs e) { - + } public override void onKeyDown(object sender, KeyEventArgs e) diff --git a/Crow/src/styling/StyleReader.cs b/Crow/src/styling/StyleReader.cs index 46931edf..2df90a22 100644 --- a/Crow/src/styling/StyleReader.cs +++ b/Crow/src/styling/StyleReader.cs @@ -134,7 +134,7 @@ namespace Crow if (c == '$') { if (PeekChar () == '{') { ReadChar (); - //constant replacement + //constant replacement while (!EndOfStream) { c = ReadChar (); if (c == '}') diff --git a/Samples/Directory.Build.props b/Samples/Directory.Build.props index 3cdb4a64..8e2a39cd 100644 --- a/Samples/Directory.Build.props +++ b/Samples/Directory.Build.props @@ -3,13 +3,13 @@ <TargetFrameworks>netcoreapp3.1</TargetFrameworks> <!--<TargetFrameworks>net5</TargetFrameworks>--> <OutputType>WinExe</OutputType> - + <SolutionDir>$(MSBuildThisFileDirectory)..\</SolutionDir> <OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath> <IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)\</IntermediateOutputPath> - + <!--<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>--> - + <License>MIT</License> <Authors>Jean-Philippe Bruyère</Authors> @@ -17,7 +17,7 @@ <SamplesDir>$(MSBuildThisFileDirectory)\</SamplesDir> <AppConfig>$(SolutionDir)Crow\App.config</AppConfig> </PropertyGroup> - + <ItemGroup> <ProjectReference Include="$(SolutionDir)Crow\Crow.csproj" /> </ItemGroup> diff --git a/Samples/ShowCase/ShowCase.csproj b/Samples/ShowCase/ShowCase.csproj index bee99267..2bc30765 100644 --- a/Samples/ShowCase/ShowCase.csproj +++ b/Samples/ShowCase/ShowCase.csproj @@ -3,6 +3,6 @@ <ItemGroup> <EmbeddedResource Include="ui\*.*"> <LogicalName>ShowCase.%(Filename)%(Extension)</LogicalName> - </EmbeddedResource> + </EmbeddedResource> </ItemGroup> </Project>
\ No newline at end of file diff --git a/Samples/ShowCase/ui/CheckBox2.imlt b/Samples/ShowCase/ui/CheckBox2.imlt new file mode 100644 index 00000000..84ec22b3 --- /dev/null +++ b/Samples/ShowCase/ui/CheckBox2.imlt @@ -0,0 +1,7 @@ +<Label Font="{./Font}" Text="{./Caption}" Width="Stretched" + Margin="5" + Background="{./Background}" + Foreground="DimGrey" + TextAlignment="Center" + MouseEnter="{Foreground=White}" + MouseLeave="{Foreground=DimGrey}"/>
\ No newline at end of file diff --git a/Samples/ShowCase/ui/ShowCase.style b/Samples/ShowCase/ui/ShowCase.style index ce7572ab..b37b0d8e 100644 --- a/Samples/ShowCase/ui/ShowCase.style +++ b/Samples/ShowCase/ui/ShowCase.style @@ -3,5 +3,6 @@ Background = "Onyx"; } CheckBox2 { + Template = "#ShowCase.CheckBox2.imlt"; Width = "200"; }
\ No newline at end of file diff --git a/Samples/ShowCase/ui/showcase.crow b/Samples/ShowCase/ui/showcase.crow index 409ddd9d..de32059e 100644 --- a/Samples/ShowCase/ui/showcase.crow +++ b/Samples/ShowCase/ui/showcase.crow @@ -3,16 +3,16 @@ <VerticalStack Width="25%"> <HorizontalStack Height="Fit" Margin="2" Background="Onyx"> <Image Margin="2" Width="16" Height="16" Path="#Crow.Icons.level-up.svg" MouseClick="./goUpDirClick" - Background="Jet" MouseEnter="{Background=Grey}" MouseLeave="{Background=Jet}" /> + Background="Jet" MouseEnter="{Background=Grey}" MouseLeave="{Background=Jet}" /> <TextBox Text="{²CurrentDir}" Margin="2"/> - </HorizontalStack> + </HorizontalStack> <DirectoryView Margin="1" Name="dv" CurrentDirectory="{CurrentDir}" SelectedItemChanged="Dv_SelectedItemChanged"> <Template> <TreeView IsRoot="true" Name="treeView" Data="{./FileSystemEntries}" Background="{./Background}" SelectedItemChanged="./onSelectedItemChanged"> <ItemTemplate DataType="System.IO.FileInfo"> <ListItem CornerRadius="2" Margin="0" Height="Fit" Width="Stretched" - ContextCommands="{GetCommands}" + ContextCommands="{GetCommands}" Selected="{Background=${ControlHighlight}}" Unselected="{Background=Transparent}"> <HorizontalStack> @@ -55,7 +55,7 @@ </ListItem> </ItemTemplate> </TreeView> - </Template> + </Template> </DirectoryView> </VerticalStack> <Splitter Width="6" /> @@ -87,12 +87,12 @@ <Button Style="IcoButton" Command="{CMDCopy}" /> <Button Style="IcoButton" Command="{CMDPaste}" />--> <Popper RootDataLevel="true" IsVisible="{DebugLoggingEnabled}" Fit="true"> - <Template> + <Template> <CheckBox IsChecked="{²./IsPopped}"> <Template> <HorizontalStack Background="Onyx" Margin="5" Spacing="10"> <Widget Background="Red" IsVisible="{DebugLogRecording}" CornerRadius="10" Width="12" Height="12"/> - <Label Text="Debug Logging" /> + <Label Text="Debug Logging" /> </HorizontalStack> </Template> </CheckBox> @@ -112,11 +112,11 @@ <Label Text="{../../../Caption}" Width="Stretched"/> <Label Background="SeaGreen" Text="{../../../EnumValue}" Margin="3"/> </HorizontalStack> - </Template> - <Wrapper Name="Content" Height="Fit" Width="{../PopWidth}" Background="Jet" /> + </Template> + <Wrapper Name="Content" Height="Fit" Width="{../PopWidth}" Background="Jet" /> </Popper> </Template> - </EnumSelector> + </EnumSelector> <EnumSelector RadioButtonStyle="CheckBox2" EnumValue="{²DiscardedEvents}" Width="Stretched" BitFieldExcludeMask="255" Caption="Discarded Events"> <Template> @@ -126,17 +126,17 @@ <Label Text="{../../../Caption}" Width="Stretched"/> <Label Background="SeaGreen" Text="{../../../EnumValue}" Margin="3"/> </HorizontalStack> - </Template> - <Wrapper Name="Content" Height="Fit" Width="{../PopWidth}" Background="Jet" /> + </Template> + <Wrapper Name="Content" Height="Fit" Width="{../PopWidth}" Background="Jet" /> </Popper> </Template> - </EnumSelector> + </EnumSelector> <Label Text="Press 'F6' to start/stop recording"/> </VerticalStack> </Popper> </HorizontalStack> <HorizontalStack> - <Editor Name="tb" Text="{Source}" Multiline="true" Font="consolas, 12" Focusable="true" Height="Stretched" Width="Stretched" + <Editor Name="tb" Text="{Source}" Multiline="true" Font="consolas, 12" Focusable="true" Height="Stretched" Width="Stretched" TextChanged="onTextChanged" KeyDown="textView_KeyDown" ContextCommands="{EditorCommands}" Foreground="DarkGrey" Background="White" MouseWheelSpeed="20"/> <!--SelectionChanged="onSelectedTextChanged"--> @@ -166,7 +166,7 @@ </CheckBox> </Template> <Label Text="{ErrorMessage}" Background="DarkRed" Foreground="White" Width="Stretched" Margin="2" Multiline="true"/> - </Popper> + </Popper> </VerticalStack> </VerticalStack> </HorizontalStack> diff --git a/Samples/common/samples.style b/Samples/common/samples.style index 6f78b149..fe188ebd 100644 --- a/Samples/common/samples.style +++ b/Samples/common/samples.style @@ -21,10 +21,10 @@ HStackMeasure { Background = "DimGrey"; } CheckBox2 { - Template= "Interfaces/CheckBox2.imlt"; + //Template= "Interfaces/CheckBox2.imlt"; Background = "Jet"; Checked="{Background=MediumSeaGreen}"; - Unchecked = "{Background=Jet}"; + Unchecked = "{Background=Jet}"; } CheckBox3 { Template= "Interfaces/CheckBox2.imlt"; @@ -105,7 +105,7 @@ allWidgetNamedCell { } allWidgetCell2 { Template = "Interfaces/grpBox2.tmp"; - Width = "20%"; + Width = "20%"; } allWidgetHS { Width = "20%"; diff --git a/Samples/common/src/SampleBase.cs b/Samples/common/src/SampleBase.cs index 5b33444a..fa6d1cde 100644 --- a/Samples/common/src/SampleBase.cs +++ b/Samples/common/src/SampleBase.cs @@ -49,7 +49,7 @@ namespace Samples static void showMsgBox (object sender) { Widget w = sender as Widget; Command cmd = w.DataSource as Command; - MessageBox.ShowModal(w.IFace, MessageBox.Type.Information, $"{cmd.Caption} CLICKED"); + MessageBox.ShowModal(w.IFace, MessageBox.Type.Information, $"{cmd?.Caption} CLICKED"); } #region Test values for Binding @@ -62,13 +62,14 @@ namespace Samples new Command("Subedit command 1", (sender) => showMsgBox (sender)), new Command("Subedit command 2 a bit longer", (sender) => showMsgBox (sender), null, false), new Command("Subedit command three", (sender) => showMsgBox (sender)) - ) + ) ); public CommandGroup FileCommands = new CommandGroup("File Commands", - new Command("File command 1", (sender) => showMsgBox (sender)), + new Command("File command 1", (sender) => showMsgBox (sender), "#Icons.gavel.svg"), new Command("File command 2 a bit longer", (sender) => showMsgBox (sender)), new Command("File command three", (sender) => showMsgBox (sender)) ); + public Command SingleCommand => new Command("Single command 1", (sender) => showMsgBox (sender), "#Icons.gavel.svg"); void initCommands() { diff --git a/Samples/common/ui/Interfaces/Experimental/icobut.crow b/Samples/common/ui/Interfaces/Experimental/icobut.crow new file mode 100644 index 00000000..68730dcf --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/icobut.crow @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<HorizontalStack Height="Fit"> + <Button Command="{SingleCommand}" Background="DimGrey" CornerRadius="15"> + <Template> + <Border Background="{./Background}" Name="Content" Margin="8" Tooltip="{./Caption}" + Foreground="Transparent" CornerRadius="{../CornerRadius}" BorderWidth="1" + MouseEnter="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}" + MouseLeave="{Foreground=Transparent}" + MouseDown="{Foreground=vgradient|0:Black|0.05:Grey|0.85:Grey|1:White};{Background=${ControlHighlight}}" + MouseUp="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black};{Background=DimGrey}"> + <Image Name="caption" Width="32" Height="32" Path="{./Icon}" /> + </Border> + </Template> + </Button> + + <Button Command="{SingleCommand}"> + <Template> + <Border Background="{./Background}" MinimumSize="50,20" Name="Content" + Foreground="Transparent" CornerRadius="{../CornerRadius}" BorderWidth="1" + MouseEnter="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black};{caption.Foreground=White}" + MouseLeave="{Foreground=Transparent};{caption.Foreground=LightGrey}" + MouseDown="{Foreground=vgradient|0:Black|0.05:Grey|0.85:Grey|1:White}" + MouseUp="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}"> + <HorizontalStack Margin="2"> + <Image Style="Icon" Path="{./Icon}"/> + <Label Font="{./Font}" Name="caption" Margin="3" Foreground="LightGrey" Text="{./Caption}"/> + </HorizontalStack> + </Border> + </Template> + </Button> +</HorizontalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Experimental/templatedControlMargin.crow b/Samples/common/ui/Interfaces/Experimental/templatedControlMargin.crow new file mode 100644 index 00000000..fcd4d29e --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/templatedControlMargin.crow @@ -0,0 +1,11 @@ +<HorizontalStack Margin="10" Height="Stretched" Visible="{ProgressVisible}" Background="SaddleBrown"> + <ProgressBar Value="50" Maximum="100" Caption="Progress caption" Width="Stretched" Height="Stretched" Margin="0"> + <Template> + <Group Background="Red" Margin="1" Height="Stretched" Width="Stretched"> + <Gauge Background="DarkGrey" Foreground="RoyalBlue" Height="Stretched" + Orientation="{./Orientation}" Minimum="{./Minimum}" Maximum="{./Maximum}" Value="{./Value}"/> + <Label Foreground="White" Text="{./Caption}" Width="Stretched" Margin="3" Background="Transparent" Height="Fit"/> + </Group> + </Template> + </ProgressBar> +</HorizontalStack>
\ No newline at end of file |