diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2018-02-15 14:58:36 +0100 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2018-02-15 14:58:36 +0100 |
| commit | c1b29a565bdbf37fd88d268588710ce8f4f84d5b (patch) | |
| tree | 37ec254f01bb8d2bad971c137fa787ca76a194d1 /src | |
| parent | 0efa7446134489edd303b349ae1220f1c4228e9a (diff) | |
CrowIDE WIP, context commands, tooltips, PointIsIn(ref point), configuration no longer static.
also:
- remove default null value for datasource
- dschange sender changed in group and privateContainer
- try closing menuItem, should debug
- Contains search also template in TemplatedContainer
- change in nodeAddress: expresion starting with '/' means current node
- MouseEventArgs CTOR with one source button
- RemoveWidget trigger check HoverWidget
- Orientation binding in Menu template
Diffstat (limited to 'src')
| -rw-r--r-- | src/Configuration.cs | 73 | ||||
| -rw-r--r-- | src/GraphicObjects/GraphicObject.cs | 77 | ||||
| -rw-r--r-- | src/GraphicObjects/Group.cs | 2 | ||||
| -rw-r--r-- | src/GraphicObjects/ILayoutable.cs | 2 | ||||
| -rw-r--r-- | src/GraphicObjects/MenuItem.cs | 17 | ||||
| -rw-r--r-- | src/GraphicObjects/Popper.cs | 6 | ||||
| -rw-r--r-- | src/GraphicObjects/PrivateContainer.cs | 2 | ||||
| -rw-r--r-- | src/GraphicObjects/Scroller.cs | 52 | ||||
| -rw-r--r-- | src/GraphicObjects/TemplatedContainer.cs | 7 | ||||
| -rw-r--r-- | src/GraphicObjects/TemplatedGroup.cs | 7 | ||||
| -rw-r--r-- | src/IML/NodeAddress.cs | 23 | ||||
| -rw-r--r-- | src/Input/MouseEventArgs.cs | 6 | ||||
| -rw-r--r-- | src/Interface.cs | 49 |
13 files changed, 229 insertions, 94 deletions
diff --git a/src/Configuration.cs b/src/Configuration.cs index 39c3c9cb..a6b0f0b0 100644 --- a/src/Configuration.cs +++ b/src/Configuration.cs @@ -71,9 +71,9 @@ namespace Crow /// /// ```csharp\n /// //storing\n - /// Configuration.Set ("Option1", 42);\n + /// Configuration.Global.Set ("Option1", 42);\n /// //loading\n - /// int op1 = Configuration.Get<int> ("Option1");\n + /// int op1 = Configuration.Global.Get<int> ("Option1");\n /// ```\n /// </summary> /// @@ -82,15 +82,28 @@ namespace Crow /// /// When running the application for the first time, some default options may be necessary. Their can be defined /// in a special embedded resource text file with the key '**appname.default.config**' - public static class Configuration + public class Configuration { - volatile static bool isDirty = false; - static string configPath, configFileName = "app.config"; - static Dictionary<string, ConfigItem> items; + volatile bool isDirty = false; + string configPath; + Dictionary<string, ConfigItem> items = new Dictionary<string, ConfigItem> (); + static Configuration globalConfig; + public static Configuration Global { get { return globalConfig; } } + + public Configuration (string path, Stream defaultConf = null) { + configPath = path; + if (File.Exists (configPath)) { + using (Stream s = new FileStream (configPath, FileMode.Open)) + load (s); + + } else if (defaultConf != null) { + load (defaultConf); + } + startSavingThread (); + } static Configuration () { - items = new Dictionary<string, ConfigItem> (); string configRoot = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), @@ -98,39 +111,29 @@ namespace Crow Assembly a = Assembly.GetEntryAssembly (); string appName = a.GetName().Name; + string globalConfigPath = Path.Combine (configRoot, appName); - configPath = Path.Combine (configRoot, appName); + if (!Directory.Exists (globalConfigPath)) + Directory.CreateDirectory (globalConfigPath); - if (!Directory.Exists(configPath)) - Directory.CreateDirectory (configPath); + globalConfigPath = Path.Combine (globalConfigPath, "global.config"); - string path = Path.Combine(configPath, configFileName); - - if (File.Exists (path)) { - using (Stream s = new FileStream (path, FileMode.Open)) - load (s); - } else { - string defaultConfigResID = appName + ".default.config"; - bool found = false; - foreach (string resIds in a.GetManifestResourceNames()) { - if (string.Equals (defaultConfigResID, resIds, StringComparison.OrdinalIgnoreCase)) { - using (Stream s = a.GetManifestResourceStream (defaultConfigResID)) - load (s); - found = true; - break; - } + string defaultConfigResID = appName + ".default.config"; + foreach (string resIds in a.GetManifestResourceNames()) { + if (string.Equals (defaultConfigResID, resIds, StringComparison.OrdinalIgnoreCase)) { + using (Stream s = a.GetManifestResourceStream (defaultConfigResID)) + globalConfig = new Configuration (globalConfigPath, s); + return; } - if (!found) - Console.WriteLine ("No Default Config found. ({0})", defaultConfigResID); } - startSavingThread (); + globalConfig = new Configuration (globalConfigPath); } - static void startSavingThread(){ + void startSavingThread(){ Thread t = new Thread (savingThread); t.IsBackground = true; t.Start (); } - static void savingThread(){ + void savingThread(){ while(true){ if (isDirty) { save (); @@ -143,7 +146,7 @@ namespace Crow /// retrive the value of the configuration key given in parameter /// </summary> /// <param name="key">option name</param> - public static T Get<T>(string key) + public T Get<T>(string key) { return !items.ContainsKey (key) ? default(T) : items [key].GetValue<T> (); } @@ -152,7 +155,7 @@ namespace Crow /// </summary> /// <param name="key">option name</param> /// <param name="value">value for that option</param> - public static void Set<T>(string key, T value) + public void Set<T>(string key, T value) { if (!items.ContainsKey (key)) { lock(items) @@ -161,8 +164,8 @@ namespace Crow items[key].Set (value); isDirty = true; } - static void save(){ - using (Stream s = new FileStream(Path.Combine(configPath, configFileName),FileMode.Create)){ + void save(){ + using (Stream s = new FileStream(configPath,FileMode.Create)){ using (StreamWriter sw = new StreamWriter (s)) { lock (items) { foreach (string key in items.Keys) { @@ -172,7 +175,7 @@ namespace Crow } } } - static void load(Stream s){ + void load(Stream s){ using (StreamReader sr = new StreamReader (s)) { while (!sr.EndOfStream) { string l = sr.ReadLine(); diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index ad02a544..ad9392b0 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -190,7 +190,8 @@ namespace Crow bool isDragged; bool allowDrag; bool allowDrop; - + string tooltip; + IList<Command> contextCommands; #endregion #region public fields @@ -764,7 +765,7 @@ namespace Crow /// Seek first logical tree upward if logicalParent is set, or seek graphic tree for /// a not null dataSource that will be active for all descendants having dataSource=null /// </summary> - [XmlAttributeAttribute][DefaultValue(null)] + [XmlAttributeAttribute]//[DefaultValue(null)] public virtual object DataSource { set { if (DataSource == value) @@ -774,6 +775,10 @@ namespace Crow dataSource = value; dse.NewDataSource = DataSource; + //prevent setting null causing stack overflow in specific case + if (dse.NewDataSource == dse.OldDataSource) + return; + OnDataSourceChanged (this, dse); NotifyValueChanged ("DataSource", DataSource); @@ -813,7 +818,6 @@ namespace Crow NotifyValueChanged ("Style", style); } } - string tooltip; [XmlAttributeAttribute] public virtual string Tooltip { get { return tooltip; } @@ -824,6 +828,16 @@ namespace Crow NotifyValueChanged("Tooltip", tooltip); } } + [XmlAttributeAttribute] + public IList<Command> ContextCommands { + get { return contextCommands; } + set { + if (contextCommands == value) + return; + contextCommands = value; + NotifyValueChanged("ContextCommands", contextCommands); + } + } #endregion #region Default and Style Values loading @@ -1499,24 +1513,45 @@ namespace Crow #endregion #region Mouse handling + public virtual bool PointIsIn(ref Point m) + { + if (!(Visible & isEnabled)||IsDragged) + return false; + ILayoutable tmp = Parent; + //while (tmp != null){ + if (!parent.PointIsIn(ref m)) + return false; + m -= (parent.getSlot().Position + parent.ClientRectangle.Position) ; + + return Slot.ContainsOrIsEqual (m); + } public virtual bool MouseIsIn(Point m) { - try { - if (!(Visible & isEnabled)||IsDragged) - return false; - if (ScreenCoordinates (Slot).ContainsOrIsEqual (m)) { - Scroller scr = Parent as Scroller; - if (scr == null) { - if (Parent is GraphicObject) - return (Parent as GraphicObject).MouseIsIn (m); - else return true; - } - return scr.MouseIsIn (scr.savedMousePos); - } - } catch (Exception ex) { - return false; - } - return false; + Point p = m; + return PointIsIn (ref m); +// try { +// if (!(Visible & isEnabled)||IsDragged) +// return false; +// ILayoutable tmp = Parent; +// //while (tmp != null){ +// if (!parent.MouseIsIn(m)) +// return false; +// m -= (parent.getSlot().Position + parent.ClientRectangle.Position) ; +// +// return slot.ContainsOrIsEqual (m); +//// Scroller scr = tmp as Scroller; +//// if (scr != null) { +//// m.Y += scr.ScrollY; +//// m.X += scr.ScrollX; +//// } +//// tmp = tmp.Parent; +// //} +// +// //} +// } catch (Exception ex) { +// return false; +// } + //return false; } public virtual void checkHoverWidget(MouseMoveEventArgs e) { @@ -1525,7 +1560,7 @@ namespace Crow onMouseEnter (this, e); } - this.onMouseMove (this, e);//without this, window border doesn't work, should be removed + //this.onMouseMove (this, e);//without this, window border doesn't work, should be removed } public virtual void onMouseMove(object sender, MouseMoveEventArgs e) { @@ -1553,6 +1588,8 @@ namespace Crow if (be.Focused == null) { be.Focused = this; CurrentInterface.FocusedWidget = this; + if (e.Button == MouseButton.Right && this.ContextCommands != null) + CurrentInterface.ShowContextMenu (this); } } //bubble event to the top diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index c944eba2..3802a4d9 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -147,7 +147,7 @@ namespace Crow lock (children) { foreach (GraphicObject g in children) if (g.localDataSourceIsNull & g.localLogicalParentIsNull) - g.OnDataSourceChanged (sender, e); + g.OnDataSourceChanged (g, e); } } public override GraphicObject FindByName (string nameToFind) diff --git a/src/GraphicObjects/ILayoutable.cs b/src/GraphicObjects/ILayoutable.cs index c0c1cf5c..c8aa38fb 100644 --- a/src/GraphicObjects/ILayoutable.cs +++ b/src/GraphicObjects/ILayoutable.cs @@ -45,7 +45,7 @@ namespace Crow void RegisterForLayouting(LayoutingType layoutType); void RegisterClip(Rectangle clip); bool UpdateLayout(LayoutingType layoutType); - + bool PointIsIn(ref Point m); Rectangle ContextCoordinates(Rectangle r); Rectangle ScreenCoordinates (Rectangle r); diff --git a/src/GraphicObjects/MenuItem.cs b/src/GraphicObjects/MenuItem.cs index ae27b013..5c9665fb 100644 --- a/src/GraphicObjects/MenuItem.cs +++ b/src/GraphicObjects/MenuItem.cs @@ -40,7 +40,6 @@ namespace Crow public event EventHandler Open; public event EventHandler Close; - string caption; Command command; Picture icon; bool isOpened; @@ -58,7 +57,8 @@ namespace Crow if (isOpened) { onOpen (this, null); - (LogicalParent as Menu).AutomaticOpenning = true; + if (LogicalParent is Menu) + (LogicalParent as Menu).AutomaticOpenning = true; }else onClose (this, null); } @@ -143,8 +143,10 @@ namespace Crow } void onMI_Click (object sender, MouseButtonEventArgs e) { - if (command != null) + if (command != null) { command.Execute (); + closeMenu (); + } if(!IsOpened) (LogicalParent as Menu).AutomaticOpenning = false; } @@ -152,6 +154,7 @@ namespace Crow Open.Raise (this, null); } protected virtual void onClose (object sender, EventArgs e){ + System.Diagnostics.Debug.WriteLine ("close: " + this.ToString()); Close.Raise (this, null); } public override bool MouseIsIn (Point m) @@ -170,6 +173,14 @@ namespace Crow IsOpened = false; base.onMouseLeave (this, e); } + + void closeMenu () { + MenuItem tmp = LogicalParent as MenuItem; + while (tmp != null) { + tmp.IsOpened = false; + tmp = tmp.LogicalParent as MenuItem; + } + } } } diff --git a/src/GraphicObjects/Popper.cs b/src/GraphicObjects/Popper.cs index 41210dc5..be4a19b8 100644 --- a/src/GraphicObjects/Popper.cs +++ b/src/GraphicObjects/Popper.cs @@ -192,6 +192,12 @@ namespace Crow base.onMouseLeave (this, e); IsPopped = false; } +// public override bool PointIsIn (ref Point m) +// { +// if (!base.PointIsIn (ref m)) +// return false; +// +// } public override bool MouseIsIn (Point m) { bool isInContent = false; diff --git a/src/GraphicObjects/PrivateContainer.cs b/src/GraphicObjects/PrivateContainer.cs index e76b57a8..8383a274 100644 --- a/src/GraphicObjects/PrivateContainer.cs +++ b/src/GraphicObjects/PrivateContainer.cs @@ -92,7 +92,7 @@ namespace Crow base.OnDataSourceChanged (this, e); if (child != null) if (child.localDataSourceIsNull & child.localLogicalParentIsNull) - child.OnDataSourceChanged (sender, e); + child.OnDataSourceChanged (child, e); } public override bool UpdateLayout (LayoutingType layoutType) { diff --git a/src/GraphicObjects/Scroller.cs b/src/GraphicObjects/Scroller.cs index ec3bc47d..a4e1b816 100644 --- a/src/GraphicObjects/Scroller.cs +++ b/src/GraphicObjects/Scroller.cs @@ -219,17 +219,39 @@ namespace Crow } #region Mouse handling - internal Point savedMousePos; - public override bool MouseIsIn (Point m) - { - return Visible ? base.ScreenCoordinates(Slot).ContainsOrIsEqual (m) : false; - } - public override void checkHoverWidget (MouseMoveEventArgs e) + //internal Point savedMousePos; + + public override bool PointIsIn (ref Point m) { - savedMousePos = e.Position; - Point m = e.Position - new Point (ScrollX, ScrollY); - base.checkHoverWidget (new MouseMoveEventArgs(m.X,m.Y,e.XDelta,e.YDelta)); +// if (!(Visible & IsEnabled)||IsDragged) +// return false; +// ILayoutable tmp = Parent; +// //while (tmp != null){ +// if (!Parent.PointIsIn(ref m)) +// return false; +// m -= (Parent.getSlot().Position + Parent.ClientRectangle.Position); +// if (!Slot.ContainsOrIsEqual (m) || child==null) +// return false; +// m += new Point (ScrollX, ScrollY); +// return true; + if (!base.PointIsIn(ref m)) + return false; + //m -= (Parent.getSlot().Position + Parent.ClientRectangle.Position); + if (!Slot.ContainsOrIsEqual (m) || child==null) + return false; + m += new Point (ScrollX, ScrollY); + return true; } +// public override bool MouseIsIn (Point m) +// { +// return Visible ? base.ScreenCoordinates(Slot).ContainsOrIsEqual (m) : false; +// } +// public override void checkHoverWidget (MouseMoveEventArgs e) +// { +// savedMousePos = e.Position; +// Point m = e.Position - new Point (ScrollX, ScrollY); +// base.checkHoverWidget (new MouseMoveEventArgs(m.X,m.Y,e.XDelta,e.YDelta)); +// } public override void onMouseWheel (object sender, MouseWheelEventArgs e) { if (Child == null) @@ -240,12 +262,12 @@ namespace Crow if (HorizontalScrolling ) ScrollX -= e.Delta * ScrollSpeed; } - public override void onMouseMove (object sender, MouseMoveEventArgs e) - { - savedMousePos.X += e.XDelta; - savedMousePos.Y += e.YDelta; - base.onMouseMove (sender, new MouseMoveEventArgs(savedMousePos.X,savedMousePos.Y,e.XDelta,e.YDelta)); - } +// public override void onMouseMove (object sender, MouseMoveEventArgs e) +// { +// savedMousePos.X += e.XDelta; +// savedMousePos.Y += e.YDelta; +// base.onMouseMove (sender, new MouseMoveEventArgs(savedMousePos.X,savedMousePos.Y,e.XDelta,e.YDelta)); +// } public override void RegisterClip (Rectangle clip) { base.RegisterClip (clip - new Point(ScrollX,ScrollY)); diff --git a/src/GraphicObjects/TemplatedContainer.cs b/src/GraphicObjects/TemplatedContainer.cs index 31bbc436..3e0dd801 100644 --- a/src/GraphicObjects/TemplatedContainer.cs +++ b/src/GraphicObjects/TemplatedContainer.cs @@ -77,12 +77,11 @@ namespace Crow } public override bool Contains (GraphicObject goToFind) { - if (Content == null) - return base.Contains (goToFind); - if (Content == goToFind) return true; - return Content.Contains (goToFind); + if (Content?.Contains (goToFind) == true) + return true; + return base.Contains (goToFind); } #endregion } diff --git a/src/GraphicObjects/TemplatedGroup.cs b/src/GraphicObjects/TemplatedGroup.cs index 069303dd..ef099f93 100644 --- a/src/GraphicObjects/TemplatedGroup.cs +++ b/src/GraphicObjects/TemplatedGroup.cs @@ -344,7 +344,9 @@ namespace Crow #endif Group page; - if (typeof(TabView).IsAssignableFrom (items.GetType ())||typeof(Wrapper).IsAssignableFrom (items.GetType ())) { + if (typeof(TabView).IsAssignableFrom (items.GetType ())|| + typeof(Menu).IsAssignableFrom (this.GetType())|| + typeof(Wrapper).IsAssignableFrom (items.GetType ())) { page = items; itemPerPage = int.MaxValue; } else if (typeof(GenericStack).IsAssignableFrom (items.GetType ())) { @@ -425,7 +427,8 @@ namespace Crow lock (CurrentInterface.LayoutMutex) { g = iTemp.CreateInstance(CurrentInterface); page.AddChild (g); - //g.LogicalParent = this; +// if (isPaged) +// g.LogicalParent = this; registerItemClick (g); } diff --git a/src/IML/NodeAddress.cs b/src/IML/NodeAddress.cs index b9f8b902..450a9d2d 100644 --- a/src/IML/NodeAddress.cs +++ b/src/IML/NodeAddress.cs @@ -54,18 +54,21 @@ namespace Crow.IML if (splitedExp.Length < 2)//dataSource binding return null; - if (string.IsNullOrEmpty (splitedExp [0]) || splitedExp [0] == ".") {//search template root - ptr--; - while (ptr >= 0) { - if (typeof(TemplatedControl).IsAssignableFrom (this [ptr].CrowType)) - break; + if (!string.IsNullOrEmpty (splitedExp [0])) {//else bind on current node + //return new NodeAddress (this.Take(ptr+1).ToArray()); + if (splitedExp [0] == ".") {//search template root ptr--; + while (ptr >= 0) { + if (typeof(TemplatedControl).IsAssignableFrom (this [ptr].CrowType)) + break; + ptr--; + } + } else if (splitedExp [0] == "..") { //search starting at current node + int levelUp = splitedExp.Length - 1; + if (levelUp > ptr + 1) + throw new Exception ("Binding error: try to bind outside IML source"); + ptr -= levelUp; } - } else if (splitedExp [0] == "..") { //search starting at current node - int levelUp = splitedExp.Length - 1; - if (levelUp > ptr + 1) - throw new Exception ("Binding error: try to bind outside IML source"); - ptr -= levelUp; } expression = splitedExp [splitedExp.Length - 1]; //TODO:change Template special address identified with Nodecount = 0 to something not using array count to 0, diff --git a/src/Input/MouseEventArgs.cs b/src/Input/MouseEventArgs.cs index e1f7ae2a..cf883f13 100644 --- a/src/Input/MouseEventArgs.cs +++ b/src/Input/MouseEventArgs.cs @@ -257,6 +257,12 @@ namespace Crow this.IsPressed = pressed; } + public MouseButtonEventArgs(MouseButton button) + : base() + { + this.button = button; + } + /// <summary> /// Constructs a new <see cref="MouseButtonEventArgs"/> instance. /// </summary> diff --git a/src/Interface.cs b/src/Interface.cs index 03ea9308..0393fbc8 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -75,6 +75,15 @@ namespace Crow if (!Directory.Exists (CrowConfigRoot)) Directory.CreateDirectory (CrowConfigRoot); + //ensure all assemblies are loaded, because IML could contains classes not instanciated in source +// foreach (string af in Directory.GetFiles (AppDomain.CurrentDomain.BaseDirectory, "*.dll")){ +// try { +// Assembly.LoadFrom (af); +// } catch (Exception ex) { +// Console.WriteLine ("{0} not loaded as assembly.", af); +// } +// } + loadCursors (); findAvailableTemplates (); @@ -89,6 +98,7 @@ namespace Crow CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture; loadStyling (); initTooltip (); + initContextMenus (); } #endregion @@ -676,6 +686,12 @@ namespace Crow /// <summary>Set visible state of widget to false and remove if from the graphic tree</summary> public void RemoveWidget(GraphicObject g) { + if (g.Contains(HoverWidget)) { + while (HoverWidget != g.LogicalParent) { + HoverWidget.onMouseLeave (HoverWidget, null); + HoverWidget = HoverWidget.LogicalParent as GraphicObject; + } + } lock (UpdateMutex) { RegisterClip (g.ScreenCoordinates (g.LastPaintedSlot)); GraphicTree.Remove (g); @@ -861,7 +877,7 @@ namespace Crow public bool ProcessMouseButtonUp(int button) { Mouse.DisableBit (button); - MouseButtonEventArgs e = new MouseButtonEventArgs () { Mouse = Mouse }; + MouseButtonEventArgs e = new MouseButtonEventArgs ((Crow.MouseButton)button) { Mouse = Mouse }; if (_activeWidget == null) return false; @@ -888,7 +904,7 @@ namespace Crow public bool ProcessMouseButtonDown(int button) { Mouse.EnableBit (button); - MouseButtonEventArgs e = new MouseButtonEventArgs () { Mouse = Mouse }; + MouseButtonEventArgs e = new MouseButtonEventArgs ((Crow.MouseButton)button) { Mouse = Mouse }; if (HoverWidget == null) return false; @@ -1016,6 +1032,31 @@ namespace Crow } #endregion + #region Contextual menu + MenuItem ctxMenuContainer; + void initContextMenus (){ + ctxMenuContainer = Load ("#Crow.ContextMenu.template") as MenuItem; + } + + public void ShowContextMenu (GraphicObject go) { + + if (ctxMenuContainer.Parent == null) + this.AddWidget (ctxMenuContainer); + else + ctxMenuContainer.IsOpened = true; + + ctxMenuContainer.LogicalParent = go; + ctxMenuContainer.DataSource = go; + + PutOnTop (ctxMenuContainer, true); + ctxMenuContainer.Left = Mouse.X - 5; + ctxMenuContainer.Top = Mouse.Y - 5; + + HoverWidget = ctxMenuContainer; + ctxMenuContainer.onMouseEnter (ctxMenuContainer, new MouseMoveEventArgs (Mouse.X, Mouse.Y, 0, 0)); + } + #endregion + #region Device Repeat Events volatile bool mouseRepeatOn, keyboardRepeatOn; volatile int mouseRepeatCount, keyboardRepeatCount; @@ -1044,6 +1085,10 @@ namespace Crow #endregion #region ILayoutable implementation + public virtual bool PointIsIn(ref Point m) + { + return true; + } public void RegisterClip(Rectangle r){ clipping.UnionRectangle (r); } |