diff options
| author | j-p <jp.bruyere@live.be> | 2016-08-15 20:55:55 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-08-15 20:55:55 +0200 |
| commit | ea5ba40d536aa80b56db118c3e8e077790c24359 (patch) | |
| tree | 194329bce587f3f7035f9d4d6258728ac45f3d2b /src/GraphicObjects | |
| parent | ed815a31113235890cf6c902c754fb3dc7536708 (diff) | |
| parent | 6c5120d8108af9ed53e7205d221cf96a281a28a4 (diff) | |
Merge pull request #19 from jpbruyere/TemplatesPathes
Default Templates searched among resources finishing with .template
Textbox and label debug
Keyboard repeat
Double click
Wrapper
Diffstat (limited to 'src/GraphicObjects')
31 files changed, 776 insertions, 399 deletions
diff --git a/src/GraphicObjects/AnalogMeter.cs b/src/GraphicObjects/AnalogMeter.cs index 80e0e850..1d60850c 100644 --- a/src/GraphicObjects/AnalogMeter.cs +++ b/src/GraphicObjects/AnalogMeter.cs @@ -5,7 +5,6 @@ using Cairo; namespace Crow { - [DefaultTemplate("#Crow.Templates.AnalogMeter0.goml")] public class AnalogMeter : NumericControl { #region CTOR diff --git a/src/GraphicObjects/Border.cs b/src/GraphicObjects/Border.cs index 6c1ed6a1..c91001b7 100644 --- a/src/GraphicObjects/Border.cs +++ b/src/GraphicObjects/Border.cs @@ -44,25 +44,25 @@ namespace Crow { Rectangle rBack = new Rectangle (Slot.Size); - rBack.Inflate (-Margin); - if (BorderWidth > 0) - rBack.Inflate (-BorderWidth / 2); + //rBack.Inflate (-Margin); +// if (BorderWidth > 0) +// rBack.Inflate (-BorderWidth / 2); Background.SetAsSource (gr, rBack); CairoHelpers.CairoRectangle(gr, rBack, CornerRadius); gr.Fill (); - if (BorderWidth > 0) { - gr.LineWidth = BorderWidth; + if (BorderWidth > 0) { Foreground.SetAsSource (gr, rBack); - CairoHelpers.CairoRectangle(gr, rBack, CornerRadius); - gr.Stroke (); + CairoHelpers.CairoRectangle(gr, rBack, CornerRadius, BorderWidth); } gr.Save (); - //clip to client zone - CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); - gr.Clip (); + if (ClipToClientRect) { + //clip to client zone + CairoHelpers.CairoRectangle (gr, ClientRectangle,Math.Max(0.0, CornerRadius-Margin)); + gr.Clip (); + } if (child != null) child.Paint (ref gr); diff --git a/src/GraphicObjects/Button.cs b/src/GraphicObjects/Button.cs index 92238e69..59762182 100644 --- a/src/GraphicObjects/Button.cs +++ b/src/GraphicObjects/Button.cs @@ -12,7 +12,6 @@ using System.ComponentModel; namespace Crow { - [DefaultTemplate("#Crow.Templates.Button.crow")] public class Button : TemplatedContainer { string caption; @@ -74,7 +73,7 @@ namespace Crow } #endregion - [XmlAttributeAttribute()][DefaultValue("Button")] + [XmlAttributeAttribute][DefaultValue("Button")] public string Caption { get { return caption; } set { @@ -84,7 +83,7 @@ namespace Crow NotifyValueChanged ("Caption", caption); } } - [XmlAttributeAttribute()][DefaultValue("#Crow.Images.button.svg")] + [XmlAttributeAttribute][DefaultValue("#Crow.Images.button.svg")] public string Image { get { return image; } set { @@ -94,7 +93,7 @@ namespace Crow NotifyValueChanged ("Image", image); } } - [XmlAttributeAttribute()][DefaultValue(false)] + [XmlAttributeAttribute][DefaultValue(false)] public bool IsPressed { get { return isPressed; } diff --git a/src/GraphicObjects/CheckBox.cs b/src/GraphicObjects/CheckBox.cs index 61b581ed..46d77e76 100644 --- a/src/GraphicObjects/CheckBox.cs +++ b/src/GraphicObjects/CheckBox.cs @@ -25,7 +25,6 @@ using System.Xml.Serialization; namespace Crow { - [DefaultTemplate("#Crow.Templates.CheckBox.goml")] public class CheckBox : TemplatedControl { string caption; diff --git a/src/GraphicObjects/ComboBox.cs b/src/GraphicObjects/ComboBox.cs index d2b0567e..becee3ce 100644 --- a/src/GraphicObjects/ComboBox.cs +++ b/src/GraphicObjects/ComboBox.cs @@ -24,7 +24,6 @@ using System.Xml.Serialization; namespace Crow { - [DefaultTemplate("#Crow.Templates.ComboBox.goml")] public class ComboBox : ListBox { #region CTOR diff --git a/src/GraphicObjects/DirectoryView.cs b/src/GraphicObjects/DirectoryView.cs index ac53ee8b..586b1b26 100644 --- a/src/GraphicObjects/DirectoryView.cs +++ b/src/GraphicObjects/DirectoryView.cs @@ -25,7 +25,6 @@ using System.IO; namespace Crow { - [DefaultTemplate("#Crow.Templates.DirectoryView.crow")] public class DirectoryView : TemplatedControl { #region CTOR diff --git a/src/GraphicObjects/DummyTemplate.cs b/src/GraphicObjects/DummyTemplate.cs index 68597d18..891499ff 100644 --- a/src/GraphicObjects/DummyTemplate.cs +++ b/src/GraphicObjects/DummyTemplate.cs @@ -22,7 +22,6 @@ using System; namespace Crow { - [DefaultTemplate("#Crow.Templates.Dummy.goml")] public class DummyTemplate : TemplatedControl { public DummyTemplate () : base() diff --git a/src/GraphicObjects/Expandable.cs b/src/GraphicObjects/Expandable.cs index 819987eb..059cab8b 100644 --- a/src/GraphicObjects/Expandable.cs +++ b/src/GraphicObjects/Expandable.cs @@ -25,7 +25,6 @@ using System.Xml.Serialization; namespace Crow { - [DefaultTemplate("#Crow.Templates.Expandable.goml")] public class Expandable : TemplatedContainer { #region CTOR diff --git a/src/GraphicObjects/FileDialog.cs b/src/GraphicObjects/FileDialog.cs index da85580a..16a60a4f 100644 --- a/src/GraphicObjects/FileDialog.cs +++ b/src/GraphicObjects/FileDialog.cs @@ -48,7 +48,7 @@ namespace Crow public FileDialog () { currentDir = new DirectoryInfo (Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)); - window = Interface.Load("#Crow.Templates.FileDialog.goml") as Window; + //window = Interface..Load("#Crow.Templates.FileDialog.goml") as Window; window.DataSource = this; } #endregion diff --git a/src/GraphicObjects/GenericStack.cs b/src/GraphicObjects/GenericStack.cs index fcc90e98..840e883f 100644 --- a/src/GraphicObjects/GenericStack.cs +++ b/src/GraphicObjects/GenericStack.cs @@ -100,7 +100,7 @@ namespace Crow //if no layouting remains in queue for item, registre for redraw if (RegisteredLayoutings == LayoutingType.None && bmp == null) - Interface.CurrentInterface.EnqueueForRepaint (this); + CurrentInterface.EnqueueForRepaint (this); return true; } diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index f8d307ea..bd96b76c 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -42,14 +42,14 @@ namespace Crow uid = currentUid; currentUid++; - if (Interface.CurrentInterface.XmlLoading) - return; - loadDefaultValues (); +// if (CurrentInterface.XmlLoading) +// return; +// loadDefaultValues (); } public GraphicObject (Rectangle _bounds) { - if (!Interface.CurrentInterface.XmlLoading) - loadDefaultValues (); +// if (!CurrentInterface.XmlLoading) +// loadDefaultValues (); Left = _bounds.Left; Top = _bounds.Top; @@ -61,25 +61,27 @@ namespace Crow #region private fields LayoutingType registeredLayoutings = LayoutingType.All; ILayoutable logicalParent; - ILayoutable _parent; - string _name = "unamed"; - Fill _background = Color.Transparent; - Fill _foreground = Color.White; - Font _font = "droid, 10"; - Measure _width, _height; - int _left, _top; - double _cornerRadius = 0; - int _margin = 0; - bool _focusable = false; - bool _hasFocus = false; - bool _isActive = false; - bool _mouseRepeat; - protected bool _isVisible = true; - VerticalAlignment _verticalAlignment = VerticalAlignment.Center; - HorizontalAlignment _horizontalAlignment = HorizontalAlignment.Center; - Size _maximumSize = "0,0"; - Size _minimumSize = "0,0"; + ILayoutable parent; + string name = "unamed"; + Fill background = Color.Transparent; + Fill foreground = Color.White; + Font font = "droid, 10"; + Measure width, height; + int left, top; + double cornerRadius = 0; + int margin = 0; + bool focusable = false; + bool hasFocus = false; + bool isActive = false; + bool mouseRepeat; + protected bool isVisible = true; + bool isEnabled = true; + VerticalAlignment verticalAlignment = VerticalAlignment.Center; + HorizontalAlignment horizontalAlignment = HorizontalAlignment.Center; + Size maximumSize = "0,0"; + Size minimumSize = "0,0"; bool cacheEnabled = false; + bool clipToClientRect = true; object dataSource; string style; #endregion @@ -124,8 +126,8 @@ namespace Crow /// Parent in the graphic tree, used for rendering and layouting /// </summary> [XmlIgnore]public virtual ILayoutable Parent { - get { return _parent; } - set { _parent = value; } + get { return parent; } + set { parent = value; } } [XmlIgnore]public ILayoutable LogicalParent { get { return logicalParent == null ? Parent : logicalParent; } @@ -158,6 +160,7 @@ namespace Crow public event EventHandler<MouseButtonEventArgs> MouseUp; public event EventHandler<MouseButtonEventArgs> MouseDown; public event EventHandler<MouseButtonEventArgs> MouseClick; + public event EventHandler<MouseButtonEventArgs> MouseDoubleClick; public event EventHandler<MouseMoveEventArgs> MouseMove; public event EventHandler<MouseMoveEventArgs> MouseEnter; public event EventHandler<MouseMoveEventArgs> MouseLeave; @@ -166,6 +169,8 @@ namespace Crow public event EventHandler<KeyPressEventArgs> KeyPress; public event EventHandler Focused; public event EventHandler Unfocused; + public event EventHandler Enabled; + public event EventHandler Disabled; public event EventHandler<LayoutingEventArgs> LayoutChanged; #endregion @@ -180,87 +185,111 @@ namespace Crow NotifyValueChanged ("CacheEnabled", cacheEnabled); } } + [XmlAttributeAttribute()][DefaultValue(true)] + public virtual bool ClipToClientRect { + get { return clipToClientRect; } + set { + if (clipToClientRect == value) + return; + clipToClientRect = value; + NotifyValueChanged ("ClipToClientRect", clipToClientRect); + this.RegisterForRedraw (); + } + } [XmlAttributeAttribute()][DefaultValue("unamed")] public virtual string Name { - get { return _name; } + get { return name; } set { - if (_name == value) + if (name == value) return; - _name = value; - NotifyValueChanged("Name", _verticalAlignment); + name = value; + NotifyValueChanged("Name", verticalAlignment); } } [XmlAttributeAttribute ()][DefaultValue(VerticalAlignment.Center)] public virtual VerticalAlignment VerticalAlignment { - get { return _verticalAlignment; } + get { return verticalAlignment; } set { - if (_verticalAlignment == value) + if (verticalAlignment == value) return; - _verticalAlignment = value; - NotifyValueChanged("VerticalAlignment", _verticalAlignment); + verticalAlignment = value; + NotifyValueChanged("VerticalAlignment", verticalAlignment); } } [XmlAttributeAttribute()][DefaultValue(HorizontalAlignment.Center)] public virtual HorizontalAlignment HorizontalAlignment { - get { return _horizontalAlignment; } + get { return horizontalAlignment; } set { - if (_horizontalAlignment == value) + if (horizontalAlignment == value) return; - _horizontalAlignment = value; - NotifyValueChanged("HorizontalAlignment", _horizontalAlignment); + horizontalAlignment = value; + NotifyValueChanged("HorizontalAlignment", horizontalAlignment); } } [XmlAttributeAttribute()][DefaultValue(0)] public virtual int Left { - get { return _left; } + get { return left; } set { - if (_left == value) + if (left == value) return; - _left = value; - NotifyValueChanged ("Left", _left); + left = value; + NotifyValueChanged ("Left", left); this.RegisterForLayouting (LayoutingType.X); } } [XmlAttributeAttribute()][DefaultValue(0)] public virtual int Top { - get { return _top; } + get { return top; } set { - if (_top == value) + if (top == value) return; - _top = value; - NotifyValueChanged ("Top", _top); + top = value; + NotifyValueChanged ("Top", top); this.RegisterForLayouting (LayoutingType.Y); } } + /// <summary> + /// When set to True, the <see cref="T:Crow.GraphicObject"/>'s width and height will be set to Fit. + /// </summary> + [XmlAttributeAttribute()][DefaultValue(false)] + public virtual bool Fit { + get { return Width == Measure.Fit && Height == Measure.Fit ? true : false; } + set { + if (value == Fit) + return; + + Width = Height = Measure.Fit; + } + } [XmlAttributeAttribute()][DefaultValue("Stretched")] public virtual Measure Width { - get { return _width; } + get { return width; } set { - if (_width == value) + if (width == value) return; if (value.IsFixed) { if (value < MinimumSize.Width || (value > MaximumSize.Width && MaximumSize.Width > 0)) return; } Measure lastWP = WidthPolicy; - _width = value; - NotifyValueChanged ("Width", _width); + width = value; + NotifyValueChanged ("Width", width); if (WidthPolicy != lastWP) { NotifyValueChanged ("WidthPolicy", WidthPolicy); //contentSize in Stacks are only update on childLayoutChange, and the single stretched //child of the stack is not counted in contentSize, so when changing size policy of a child //we should adapt contentSize //TODO:check case when child become stretched, and another stretched item already exists. - if (_parent is GenericStack) {//TODO:check if I should test Group instead - if ((_parent as GenericStack).Orientation == Orientation.Horizontal) { + if (parent is GenericStack) {//TODO:check if I should test Group instead + if ((parent as GenericStack).Orientation == Orientation.Horizontal) { if (lastWP == Measure.Fit) - (_parent as GenericStack).contentSize.Width -= this.LastSlots.Width; + (parent as GenericStack).contentSize.Width -= this.LastSlots.Width; else - (_parent as GenericStack).contentSize.Width += this.LastSlots.Width; + (parent as GenericStack).contentSize.Width += this.LastSlots.Width; } } } @@ -270,25 +299,25 @@ namespace Crow } [XmlAttributeAttribute()][DefaultValue("Stretched")] public virtual Measure Height { - get { return _height; } + get { return height; } set { - if (_height == value) + if (height == value) return; if (value.IsFixed) { if (value < MinimumSize.Height || (value > MaximumSize.Height && MaximumSize.Height > 0)) return; } Measure lastHP = HeightPolicy; - _height = value; - NotifyValueChanged ("Height", _height); + height = value; + NotifyValueChanged ("Height", height); if (HeightPolicy != lastHP) { NotifyValueChanged ("HeightPolicy", HeightPolicy); - if (_parent is GenericStack) { - if ((_parent as GenericStack).Orientation == Orientation.Vertical) { + if (parent is GenericStack) { + if ((parent as GenericStack).Orientation == Orientation.Vertical) { if (lastHP == Measure.Fit) - (_parent as GenericStack).contentSize.Height -= this.LastSlots.Height; + (parent as GenericStack).contentSize.Height -= this.LastSlots.Height; else - (_parent as GenericStack).contentSize.Height += this.LastSlots.Height; + (parent as GenericStack).contentSize.Height += this.LastSlots.Height; } } } @@ -310,165 +339,166 @@ namespace Crow [XmlIgnore]public virtual Measure HeightPolicy { get { return Height.Units == Unit.Percent || Height.IsFixed ? Measure.Stretched : Measure.Fit; } } - /// <summary> - /// When set to True, the <see cref="T:Crow.GraphicObject"/>'s width and height will be set to Fit. - /// </summary> - [XmlAttributeAttribute()][DefaultValue(false)] - public virtual bool Fit { - get { return Width == Measure.Fit && Height == Measure.Fit ? true : false; } - set { - if (value == Fit) - return; - - Width = Height = Measure.Fit; - } - } [XmlAttributeAttribute()][DefaultValue(false)] public virtual bool Focusable { - get { return _focusable; } + get { return focusable; } set { - if (_focusable == value) + if (focusable == value) return; - _focusable = value; - NotifyValueChanged ("Focusable", _focusable); + focusable = value; + NotifyValueChanged ("Focusable", focusable); } } [XmlIgnore]public virtual bool HasFocus { - get { return _hasFocus; } + get { return hasFocus; } set { - if (value == _hasFocus) + if (value == hasFocus) return; - _hasFocus = value; - NotifyValueChanged ("HasFocus", _hasFocus); + hasFocus = value; + NotifyValueChanged ("HasFocus", hasFocus); } } [XmlIgnore]public virtual bool IsActive { - get { return _isActive; } + get { return isActive; } set { - if (value == _isActive) + if (value == isActive) return; - _isActive = value; - NotifyValueChanged ("IsActive", _isActive); + isActive = value; + NotifyValueChanged ("IsActive", isActive); } } [XmlAttributeAttribute()][DefaultValue(false)] public virtual bool MouseRepeat { - get { return _mouseRepeat; } + get { return mouseRepeat; } set { - if (_mouseRepeat == value) + if (mouseRepeat == value) return; - _mouseRepeat = value; - NotifyValueChanged ("MouseRepeat", _mouseRepeat); + mouseRepeat = value; + NotifyValueChanged ("MouseRepeat", mouseRepeat); } } [XmlAttributeAttribute()][DefaultValue("Transparent")] public virtual Fill Background { - get { return _background; } + get { return background; } set { - if (_background == value) + if (background == value) return; - _background = value; - NotifyValueChanged ("Background", _background); + background = value; + NotifyValueChanged ("Background", background); RegisterForRedraw (); } } [XmlAttributeAttribute()][DefaultValue("White")] public virtual Fill Foreground { - get { return _foreground; } + get { return foreground; } set { - if (_foreground == value) + if (foreground == value) return; - _foreground = value; - NotifyValueChanged ("Foreground", _foreground); + foreground = value; + NotifyValueChanged ("Foreground", foreground); RegisterForRedraw (); } } [XmlAttributeAttribute()][DefaultValue("sans,10")] public virtual Font Font { - get { return _font; } + get { return font; } set { - if (value == _font) + if (value == font) return; - _font = value; - NotifyValueChanged ("Font", _font); + font = value; + NotifyValueChanged ("Font", font); RegisterForGraphicUpdate (); } } [XmlAttributeAttribute()][DefaultValue(0.0)] public virtual double CornerRadius { - get { return _cornerRadius; } + get { return cornerRadius; } set { - if (value == _cornerRadius) + if (value == cornerRadius) return; - _cornerRadius = value; - NotifyValueChanged ("CornerRadius", _cornerRadius); + cornerRadius = value; + NotifyValueChanged ("CornerRadius", cornerRadius); RegisterForRedraw (); } } [XmlAttributeAttribute()][DefaultValue(0)] public virtual int Margin { - get { return _margin; } + get { return margin; } set { - if (value == _margin) + if (value == margin) return; - _margin = value; - NotifyValueChanged ("Margin", _margin); + margin = value; + NotifyValueChanged ("Margin", margin); RegisterForGraphicUpdate (); } } - [XmlAttributeAttribute()][DefaultValue(true)] + [XmlAttributeAttribute][DefaultValue(true)] public virtual bool Visible { - get { return _isVisible; } + get { return isVisible; } set { - if (value == _isVisible) + if (value == isVisible) return; - _isVisible = value; - - if (Interface.CurrentInterface == null) - return; + isVisible = value; //ensure main win doesn't keep hidden childrens ref - if (!_isVisible && this.Contains (Interface.CurrentInterface.HoverWidget)) - Interface.CurrentInterface.HoverWidget = null; + if (!isVisible && this.Contains (CurrentInterface.HoverWidget)) + CurrentInterface.HoverWidget = null; if (Parent is GraphicObject) (Parent as GraphicObject).RegisterForLayouting (LayoutingType.Sizing); if (Parent is GenericStack) (Parent as GraphicObject).RegisterForLayouting (LayoutingType.ArrangeChildren); - if (_isVisible) + if (isVisible) RegisterForLayouting (LayoutingType.Sizing); - Interface.CurrentInterface.EnqueueForRepaint (this); + CurrentInterface.EnqueueForRepaint (this); + + NotifyValueChanged ("Visible", isVisible); + } + } + [XmlAttributeAttribute][DefaultValue(true)] + public virtual bool IsEnabled { + get { return isEnabled; } + set { + if (value == isEnabled) + return; - NotifyValueChanged ("Visible", _isVisible); + isEnabled = value; + + if (isEnabled) + onEnable (this, null); + else + onDisable (this, null); + + NotifyValueChanged ("IsEnabled", isEnabled); } } [XmlAttributeAttribute()][DefaultValue("1,1")] public virtual Size MinimumSize { - get { return _minimumSize; } + get { return minimumSize; } set { - if (value == _minimumSize) + if (value == minimumSize) return; - _minimumSize = value; + minimumSize = value; - NotifyValueChanged ("MinimumSize", _minimumSize); + NotifyValueChanged ("MinimumSize", minimumSize); RegisterForLayouting (LayoutingType.Sizing); } } [XmlAttributeAttribute()][DefaultValue("0,0")] public virtual Size MaximumSize { - get { return _maximumSize; } + get { return maximumSize; } set { - if (value == _maximumSize) + if (value == maximumSize) return; - _maximumSize = value; + maximumSize = value; - NotifyValueChanged ("MaximumSize", _maximumSize); + NotifyValueChanged ("MaximumSize", maximumSize); RegisterForLayouting (LayoutingType.Sizing); } } @@ -668,11 +698,13 @@ namespace Crow #endregion public virtual GraphicObject FindByName(string nameToFind){ - return string.Equals(nameToFind, _name, StringComparison.Ordinal) ? this : null; + return string.Equals(nameToFind, name, StringComparison.Ordinal) ? this : null; } public virtual bool Contains(GraphicObject goToFind){ return false; } + + #region Queuing public virtual void RegisterClip(Rectangle clip){ if (CacheEnabled && bmp != null) Clipping.AddRectangle (clip + ClientRectangle.Position); @@ -687,7 +719,7 @@ namespace Crow if (Width == Measure.Fit || Height == Measure.Fit) RegisterForLayouting (LayoutingType.Sizing); else if (RegisteredLayoutings == LayoutingType.None) - Interface.CurrentInterface.EnqueueForRepaint (this); + CurrentInterface.EnqueueForRepaint (this); } /// <summary> query an update of the content, a redraw </summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -695,19 +727,10 @@ namespace Crow { bmp = null; if (RegisteredLayoutings == LayoutingType.None) - Interface.CurrentInterface.EnqueueForRepaint (this); + CurrentInterface.EnqueueForRepaint (this); } -// public Interface CurrentInterface { -// get { -// ILayoutable tmp = this.Parent; -// while (tmp != null) { -// if (tmp is Interface) -// return tmp as Interface; -// tmp = tmp.Parent; -// } -// return null; -// } -// } + internal Interface CurrentInterface = null; + #endregion #region Layouting @@ -727,7 +750,7 @@ namespace Crow public virtual void RegisterForLayouting(LayoutingType layoutType){ if (Parent == null) return; - lock (Interface.CurrentInterface.LayoutMutex) { + lock (CurrentInterface.LayoutMutex) { //dont set position for stretched item if (Width == Measure.Stretched) layoutType &= (~LayoutingType.X); @@ -749,15 +772,15 @@ namespace Crow //enqueue LQI LayoutingTypes separately if (layoutType.HasFlag (LayoutingType.Width)) - Interface.CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this)); + CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this)); if (layoutType.HasFlag (LayoutingType.Height)) - Interface.CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this)); + CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this)); if (layoutType.HasFlag (LayoutingType.X)) - Interface.CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this)); + CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this)); if (layoutType.HasFlag (LayoutingType.Y)) - Interface.CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this)); + CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this)); if (layoutType.HasFlag (LayoutingType.ArrangeChildren)) - Interface.CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this)); + CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this)); } } @@ -927,7 +950,7 @@ namespace Crow //if no layouting remains in queue for item, registre for redraw if (this.registeredLayoutings == LayoutingType.None && bmp == null) - Interface.CurrentInterface.EnqueueForRepaint (this); + CurrentInterface.EnqueueForRepaint (this); return true; } @@ -940,7 +963,7 @@ namespace Crow Rectangle rBack = new Rectangle (Slot.Size); Background.SetAsSource (gr, rBack); - CairoHelpers.CairoRectangle(gr,rBack,_cornerRadius); + CairoHelpers.CairoRectangle(gr,rBack,cornerRadius); gr.Fill (); } @@ -1054,8 +1077,8 @@ namespace Crow } public virtual void checkHoverWidget(MouseMoveEventArgs e) { - if (Interface.CurrentInterface.HoverWidget != this) { - Interface.CurrentInterface.HoverWidget = this; + if (CurrentInterface.HoverWidget != this) { + CurrentInterface.HoverWidget = this; onMouseEnter (this, e); } @@ -1071,13 +1094,13 @@ namespace Crow MouseMove.Raise (sender, e); } public virtual void onMouseDown(object sender, MouseButtonEventArgs e){ - if (Interface.CurrentInterface.activeWidget == null) - Interface.CurrentInterface.activeWidget = this; + if (CurrentInterface.activeWidget == null) + CurrentInterface.activeWidget = this; if (this.Focusable && !Interface.FocusOnHover) { BubblingMouseButtonEventArg be = e as BubblingMouseButtonEventArg; if (be.Focused == null) { be.Focused = this; - Interface.CurrentInterface.FocusedWidget = this; + CurrentInterface.FocusedWidget = this; } } //bubble event to the top @@ -1099,11 +1122,27 @@ namespace Crow onMouseClick (this, e); } public virtual void onMouseClick(object sender, MouseButtonEventArgs e){ + + if (Interface.clickTimer.ElapsedMilliseconds > 0 && + Interface.clickTimer.ElapsedMilliseconds < Interface.DoubleClick) { + Interface.clickTimer.Reset (); + Debug.WriteLine ("double click"); + onMouseDoubleClick (this, e); + return; + } else + Interface.clickTimer.Restart (); + GraphicObject p = Parent as GraphicObject; if (p != null) p.onMouseClick(sender,e); MouseClick.Raise (this, e); } + public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){ + GraphicObject p = Parent as GraphicObject; + if (p != null) + p.onMouseDoubleClick(sender,e); + MouseDoubleClick.Raise (this, e); + } public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){ GraphicObject p = Parent as GraphicObject; if (p != null) @@ -1111,6 +1150,22 @@ namespace Crow MouseWheelChanged.Raise (this, e); } + public virtual void onMouseEnter(object sender, MouseMoveEventArgs e) + { + #if DEBUG_FOCUS + Debug.WriteLine("MouseEnter => " + this.ToString()); + #endif + MouseEnter.Raise (this, e); + } + public virtual void onMouseLeave(object sender, MouseMoveEventArgs e) + { + #if DEBUG_FOCUS + Debug.WriteLine("MouseLeave => " + this.ToString()); + #endif + MouseLeave.Raise (this, e); + } + #endregion + public virtual void onFocused(object sender, EventArgs e){ #if DEBUG_FOCUS Debug.WriteLine("Focused => " + this.ToString()); @@ -1126,22 +1181,12 @@ namespace Crow Unfocused.Raise (this, e); this.HasFocus = false; } - public virtual void onMouseEnter(object sender, MouseMoveEventArgs e) - { - #if DEBUG_FOCUS - Debug.WriteLine("MouseEnter => " + this.ToString()); - #endif - MouseEnter.Raise (this, e); + public virtual void onEnable(object sender, EventArgs e){ + Enabled.Raise (this, e); } - public virtual void onMouseLeave(object sender, MouseMoveEventArgs e) - { - #if DEBUG_FOCUS - Debug.WriteLine("MouseLeave => " + this.ToString()); - #endif - MouseLeave.Raise (this, e); + public virtual void onDisable(object sender, EventArgs e){ + Disabled.Raise (this, e); } - #endregion - public override string ToString () { string tmp =""; @@ -1406,6 +1451,7 @@ namespace Crow { Type type = this.GetType (); GraphicObject result = (GraphicObject)Activator.CreateInstance (type); + result.CurrentInterface = CurrentInterface; foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { if (pi.GetSetMethod () == null) diff --git a/src/GraphicObjects/Grid.cs b/src/GraphicObjects/Grid.cs index ed0cd986..a0f0cb69 100644 --- a/src/GraphicObjects/Grid.cs +++ b/src/GraphicObjects/Grid.cs @@ -135,7 +135,7 @@ namespace Crow //if no layouting remains in queue for item, registre for redraw if (RegisteredLayoutings == LayoutingType.None && bmp == null) - Interface.CurrentInterface.EnqueueForRepaint (this); + CurrentInterface.EnqueueForRepaint (this); return true; } diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index e87ca41c..950992e2 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -164,6 +164,60 @@ namespace Crow break; } } + protected override void onDraw (Context gr) + { + base.onDraw (gr); + + gr.Save (); + + if (ClipToClientRect) { + //clip to client zone + CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); + gr.Clip (); + } + + lock (children) { + foreach (GraphicObject g in Children) { + g.Paint (ref gr); + } + } + gr.Restore (); + } + protected override void UpdateCache (Context ctx) + { + Rectangle rb = Slot + Parent.ClientRectangle.Position; + + using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) { + Context gr = new Context (cache); + + if (Clipping.count > 0) { + Clipping.clearAndClip (gr); + base.onDraw (gr); + + //clip to client zone + CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); + gr.Clip (); + + foreach (GraphicObject c in Children) { + if (!c.Visible) + continue; + if (Clipping.intersect(c.Slot + ClientRectangle.Position)) + c.Paint (ref gr); + } + + #if DEBUG_CLIP_RECTANGLE + Clipping.stroke (gr, Color.Amaranth.AdjustAlpha (0.8)); + #endif + } + gr.Dispose (); + + ctx.SetSourceSurface (cache, rb.X, rb.Y); + ctx.Paint (); + } + Clipping.Reset(); + } + #endregion + public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) { GraphicObject g = sender as GraphicObject; @@ -193,7 +247,6 @@ namespace Crow break; } } - //TODO: x,y position should be taken in account for computation of width and height void resetChildrenMaxSize(){ largestChild = null; @@ -235,62 +288,12 @@ namespace Crow } } - protected override void onDraw (Context gr) - { - base.onDraw (gr); - - gr.Save (); - //clip to client zone - CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); - gr.Clip (); - lock (children) { - foreach (GraphicObject g in Children) { - g.Paint (ref gr); - } - } - gr.Restore (); - } - protected override void UpdateCache (Context ctx) - { - Rectangle rb = Slot + Parent.ClientRectangle.Position; - - using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) { - Context gr = new Context (cache); - - if (Clipping.count > 0) { - Clipping.clearAndClip (gr); - base.onDraw (gr); - - //clip to client zone - CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); - gr.Clip (); - - foreach (GraphicObject c in Children) { - if (!c.Visible) - continue; - if (Clipping.intersect(c.Slot + ClientRectangle.Position)) - c.Paint (ref gr); - } - - #if DEBUG_CLIP_RECTANGLE - Clipping.stroke (gr, Color.Amaranth.AdjustAlpha (0.8)); - #endif - } - gr.Dispose (); - - ctx.SetSourceSurface (cache, rb.X, rb.Y); - ctx.Paint (); - } - Clipping.Reset(); - } - #endregion - #region Mouse handling public override void checkHoverWidget (MouseMoveEventArgs e) { - if (Interface.CurrentInterface.HoverWidget != this) { - Interface.CurrentInterface.HoverWidget = this; + if (CurrentInterface.HoverWidget != this) { + CurrentInterface.HoverWidget = this; onMouseEnter (this, e); } for (int i = Children.Count - 1; i >= 0; i--) { diff --git a/src/GraphicObjects/GroupBox.cs b/src/GraphicObjects/GroupBox.cs index 886e7964..db457282 100644 --- a/src/GraphicObjects/GroupBox.cs +++ b/src/GraphicObjects/GroupBox.cs @@ -25,7 +25,6 @@ using System.ComponentModel; namespace Crow { - [DefaultTemplate("#Crow.Templates.GroupBox.goml")] public class GroupBox : TemplatedContainer { string caption; diff --git a/src/GraphicObjects/Label.cs b/src/GraphicObjects/Label.cs index e9568c5d..666f00a2 100644 --- a/src/GraphicObjects/Label.cs +++ b/src/GraphicObjects/Label.cs @@ -200,8 +200,8 @@ namespace Crow set { if (value == _currentLine) return; - if (value > lines.Count) - _currentLine = lines.Count; + if (value >= lines.Count) + _currentLine = lines.Count-1; else if (value < 0) _currentLine = 0; else @@ -213,7 +213,13 @@ namespace Crow NotifyValueChanged ("CurrentLine", _currentLine); } } + [XmlIgnore]public Point CurrentPosition { + get { return new Point(_currentCol, CurrentLine); } + } //TODO:using HasFocus for drawing selection cause SelBegin and Release binding not to work + /// <summary> + /// Selection begin position in char units + /// </summary> [XmlAttributeAttribute][DefaultValue("-1")] public Point SelBegin { get { @@ -240,14 +246,19 @@ namespace Crow NotifyValueChanged ("SelectedText", SelectedText); } } - - [XmlIgnore]protected Char CurrentChar //ordered selection start and end positions + /// <summary> + /// return char at CurrentLine, CurrentColumn + /// </summary> + [XmlIgnore]protected Char CurrentChar { get { return lines [CurrentLine] [CurrentColumn]; } } - [XmlIgnore]protected Point selectionStart //ordered selection start and end positions + /// <summary> + /// ordered selection start and end positions in char units + /// </summary> + [XmlIgnore]protected Point selectionStart { get { return SelRelease < 0 || SelBegin.Y < SelRelease.Y ? SelBegin : @@ -287,11 +298,40 @@ namespace Crow List<string> getLines { get { return _multiline ? - Regex.Split (_text, "\r\n|\r|\n|" + @"\\n").ToList() : + Regex.Split (_text, "\r\n|\r|\n|\\\\n").ToList() : new List<string>(new string[] { _text }); } } - + /// <summary> + /// Moves cursor one char to the left. + /// </summary> + /// <returns><c>true</c> if move succeed</returns> + public bool MoveLeft(){ + int tmp = _currentCol - 1; + if (tmp < 0) { + if (_currentLine == 0) + return false; + CurrentLine--; + CurrentColumn = int.MaxValue; + } else + CurrentColumn = tmp; + return true; + } + /// <summary> + /// Moves cursor one char to the right. + /// </summary> + /// <returns><c>true</c> if move succeed</returns> + public bool MoveRight(){ + int tmp = _currentCol + 1; + if (tmp > lines [_currentLine].Length){ + if (CurrentLine == lines.Count - 1) + return false; + CurrentLine++; + CurrentColumn = 0; + } else + CurrentColumn = tmp; + return true; + } public void GotoWordStart(){ CurrentColumn--; //skip white spaces @@ -304,6 +344,8 @@ namespace Crow } public void GotoWordEnd(){ //skip white spaces + if (CurrentColumn >= lines [CurrentLine].Length - 1) + return; while (char.IsWhiteSpace (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1) CurrentColumn++; while (!char.IsWhiteSpace (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1) @@ -315,7 +357,7 @@ namespace Crow { if (selectionIsEmpty) { if (CurrentColumn == 0) { - if (CurrentLine == 0) + if (CurrentLine == 0 && lines.Count == 1) return; CurrentLine--; CurrentColumn = lines [CurrentLine].Length; @@ -327,7 +369,7 @@ namespace Crow CurrentColumn--; lines [CurrentLine] = lines [CurrentLine].Remove (CurrentColumn, 1); } else { - int linesToRemove = selectionEnd.Y - selectionStart.Y; + int linesToRemove = selectionEnd.Y - selectionStart.Y + 1; int l = selectionStart.Y; if (linesToRemove > 0) { @@ -336,8 +378,8 @@ namespace Crow l++; for (int c = 0; c < linesToRemove-1; c++) lines.RemoveAt (l); - CurrentColumn = selectionStart.X; CurrentLine = selectionStart.Y; + CurrentColumn = selectionStart.X; } else lines [l] = lines [l].Remove (selectionStart.X, selectionEnd.X - selectionStart.X); CurrentColumn = selectionStart.X; @@ -352,8 +394,21 @@ namespace Crow /// <param name="str">String.</param> protected void Insert(string str) { - lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, str); - CurrentColumn += str.Length; + if (!selectionIsEmpty) + this.DeleteChar (); + if (_multiline) { + string[] strLines = Regex.Split (str, "\r\n|\r|\n|" + @"\\n").ToArray(); + lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[0]); + CurrentColumn += strLines[0].Length; + for (int i = 1; i < strLines.Length; i++) { + InsertLineBreak (); + lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[i]); + CurrentColumn += strLines[i].Length; + } + } else { + lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, str); + CurrentColumn += str.Length; + } NotifyValueChanged ("Text", Text); } /// <summary> @@ -513,9 +568,9 @@ namespace Crow computeTextCursorPosition(gr); Foreground.SetAsSource (gr); - gr.LineWidth = 1.5; - gr.MoveTo(new PointD(textCursorPos + rText.X, rText.Y + CurrentLine * fe.Height)); - gr.LineTo(new PointD(textCursorPos + rText.X, rText.Y + (CurrentLine + 1) * fe.Height)); + gr.LineWidth = 1.0; + gr.MoveTo (0.5 + textCursorPos + rText.X, rText.Y + CurrentLine * fe.Height); + gr.LineTo (0.5 + textCursorPos + rText.X, rText.Y + (CurrentLine + 1) * fe.Height); gr.Stroke(); } #endregion @@ -548,9 +603,9 @@ namespace Crow int lineLength = (int)gr.TextExtents (l).XAdvance; Rectangle lineRect = new Rectangle ( rText.X, - rText.Y + (int)(i * fe.Height), - lineLength, - (int)fe.Height); + rText.Y + (int)Math.Ceiling(i * fe.Height), + lineLength, + (int)Math.Ceiling(fe.Height)); // if (TextAlignment == Alignment.Center || // TextAlignment == Alignment.Top || @@ -604,6 +659,17 @@ namespace Crow if (mouseLocalPos.Y < 0) mouseLocalPos.Y = 0; } + public override void onMouseEnter (object sender, MouseMoveEventArgs e) + { + base.onMouseEnter (sender, e); + if (Selectable) + CurrentInterface.MouseCursor = XCursor.Text; + } + public override void onMouseLeave (object sender, MouseMoveEventArgs e) + { + base.onMouseLeave (sender, e); + CurrentInterface.MouseCursor = XCursor.Default; + } public override void onFocused (object sender, EventArgs e) { base.onFocused (sender, e); @@ -657,6 +723,17 @@ namespace Crow SelectionInProgress = false; RegisterForRedraw (); } + public override void onMouseDoubleClick (object sender, MouseButtonEventArgs e) + { + base.onMouseDoubleClick (sender, e); + + GotoWordStart (); + SelBegin = CurrentPosition; + GotoWordEnd (); + SelRelease = CurrentPosition; + SelectionInProgress = false; + RegisterForRedraw (); + } #endregion /// <summary> diff --git a/src/GraphicObjects/ListBox.cs b/src/GraphicObjects/ListBox.cs index ab349ed4..ffbaf3e8 100644 --- a/src/GraphicObjects/ListBox.cs +++ b/src/GraphicObjects/ListBox.cs @@ -30,7 +30,6 @@ using System.Threading; namespace Crow { - [DefaultTemplate("#Crow.Templates.ListBox.goml")] public class ListBox : TemplatedControl { #region CTOR @@ -63,7 +62,7 @@ namespace Crow NotifyValueChanged ("Data", data); - lock (Interface.CurrentInterface.UpdateMutex) + lock (CurrentInterface.UpdateMutex) _list.ClearChildren (); if (_gsList.Orientation == Orientation.Horizontal) _gsList.Width = -1; @@ -163,40 +162,12 @@ namespace Crow if (cancelLoading) return; - GraphicObject g = null; - ItemTemplate iTemp = null; - Type dataType = data [i].GetType (); + loadItem (i, page); - if (ItemTemplates.ContainsKey (dataType.FullName)) - iTemp = ItemTemplates [dataType.FullName]; - else - iTemp = ItemTemplates ["default"]; - - lock (Interface.CurrentInterface.LayoutMutex) { - g = iTemp.CreateInstance(); - page.AddChild (g); - g.DataSource = data [i]; - } - if (this is TreeView) { - TreeView tv = this as TreeView; - while (!tv.IsRoot) { - ILayoutable tmp = tv.Parent; - while (!(tmp is TreeView)) { - tmp = tmp.Parent; - } - tv = tmp as TreeView; - } - g.MouseClick += tv.itemClick; - }else - g.MouseClick += itemClick; - - if (iTemp.Expand != null && g is Expandable) { - (g as Expandable).Expand += iTemp.Expand; - } //g.LogicalParent = this; } - lock (Interface.CurrentInterface.LayoutMutex) + lock (CurrentInterface.LayoutMutex) _list.AddChild (page); #if DEBUG_LOAD @@ -206,6 +177,31 @@ namespace Crow loadingTime.ElapsedMilliseconds, this.ToString()); #endif } + protected void loadItem(int i, Group page){ + GraphicObject g = null; + ItemTemplate iTemp = null; + Type dataType = data [i].GetType (); + + if (ItemTemplates.ContainsKey (dataType.FullName)) + iTemp = ItemTemplates [dataType.FullName]; + else + iTemp = ItemTemplates ["default"]; + + lock (CurrentInterface.LayoutMutex) { + g = iTemp.CreateInstance(CurrentInterface); + page.AddChild (g); + g.DataSource = data [i]; + } + + registerItemClick (g); + + if (iTemp.Expand != null && g is Expandable) { + (g as Expandable).Expand += iTemp.Expand; + } + } + protected virtual void registerItemClick(GraphicObject g){ + g.MouseClick += itemClick; + } protected void _list_LayoutChanged (object sender, LayoutingEventArgs e) { #if DEBUG_LAYOUTING diff --git a/src/GraphicObjects/MessageBox.cs b/src/GraphicObjects/MessageBox.cs index 550f5b72..dbca769d 100644 --- a/src/GraphicObjects/MessageBox.cs +++ b/src/GraphicObjects/MessageBox.cs @@ -23,7 +23,6 @@ using System.ComponentModel; namespace Crow { - [DefaultTemplate("#Crow.Templates.MessageBox.goml")] public class MessageBox : Window { public MessageBox ():base(){} diff --git a/src/GraphicObjects/Popper.cs b/src/GraphicObjects/Popper.cs index ea11435a..8d62f002 100644 --- a/src/GraphicObjects/Popper.cs +++ b/src/GraphicObjects/Popper.cs @@ -26,7 +26,6 @@ using OpenTK.Input; namespace Crow { - [DefaultTemplate("#Crow.Templates.Popper.goml")] public class Popper : TemplatedContainer { #region CTOR @@ -170,7 +169,7 @@ namespace Crow //ensure popped window is cleared if (Content != null) { if (Content.Parent != null) - Interface.CurrentInterface.DeleteWidget (Content); + CurrentInterface.DeleteWidget (Content); } base.ClearBinding (); } @@ -195,21 +194,17 @@ namespace Crow public virtual void onPop(object sender, EventArgs e) { - if (Interface.CurrentInterface == null) - return; if (Content != null) { Content.Visible = true; if (Content.Parent == null) - Interface.CurrentInterface.AddWidget (Content); - Interface.CurrentInterface.PutOnTop (Content); + CurrentInterface.AddWidget (Content); + CurrentInterface.PutOnTop (Content); _content_LayoutChanged (this, new LayoutingEventArgs (LayoutingType.Sizing)); } Pop.Raise (this, e); } public virtual void onUnpop(object sender, EventArgs e) { - if (Interface.CurrentInterface == null) - return; if (Content != null) Content.Visible = false; Unpop.Raise (this, e); diff --git a/src/GraphicObjects/PrivateContainer.cs b/src/GraphicObjects/PrivateContainer.cs index a6f52f29..5f70dd17 100644 --- a/src/GraphicObjects/PrivateContainer.cs +++ b/src/GraphicObjects/PrivateContainer.cs @@ -158,9 +158,12 @@ namespace Crow base.onDraw (gr); gr.Save (); - //clip to client zone - CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); - gr.Clip (); + + if (ClipToClientRect) { + //clip to client zone + CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); + gr.Clip (); + } if (child != null) child.Paint (ref gr); diff --git a/src/GraphicObjects/RadioButton.cs b/src/GraphicObjects/RadioButton.cs index 35c96c30..ede16475 100644 --- a/src/GraphicObjects/RadioButton.cs +++ b/src/GraphicObjects/RadioButton.cs @@ -25,7 +25,6 @@ using System.Xml.Serialization; namespace Crow { - [DefaultTemplate("#Crow.Templates.RadioButton.goml")] public class RadioButton : TemplatedControl { string caption; diff --git a/src/GraphicObjects/ScrollBar.cs b/src/GraphicObjects/ScrollBar.cs index 017b50ac..5660c00b 100644 --- a/src/GraphicObjects/ScrollBar.cs +++ b/src/GraphicObjects/ScrollBar.cs @@ -5,7 +5,6 @@ using OpenTK.Input; namespace Crow { - [DefaultTemplate("#Crow.Templates.ScrollBar.goml")] public class ScrollBar : NumericControl { Orientation _orientation; diff --git a/src/GraphicObjects/Scroller.cs b/src/GraphicObjects/Scroller.cs index c248595d..4b83b0cb 100644 --- a/src/GraphicObjects/Scroller.cs +++ b/src/GraphicObjects/Scroller.cs @@ -215,9 +215,11 @@ namespace Crow gr.Fill (); gr.Save (); - //clip to scrolled client zone - CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); - gr.Clip (); + if (ClipToClientRect) { + //clip to scrolled client zone + CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); + gr.Clip (); + } gr.Translate (-ScrollX, -ScrollY); if (child != null) diff --git a/src/GraphicObjects/Spinner.cs b/src/GraphicObjects/Spinner.cs index 0806d4d3..7fc34ae8 100644 --- a/src/GraphicObjects/Spinner.cs +++ b/src/GraphicObjects/Spinner.cs @@ -22,7 +22,6 @@ using System; namespace Crow { - [DefaultTemplate("#Crow.Templates.Spinner.goml")] public class Spinner : NumericControl { #region CTOR diff --git a/src/GraphicObjects/Splitter.cs b/src/GraphicObjects/Splitter.cs index 1a1558af..43c1ab08 100644 --- a/src/GraphicObjects/Splitter.cs +++ b/src/GraphicObjects/Splitter.cs @@ -61,14 +61,14 @@ namespace Crow { base.onMouseEnter (sender, e); if ((Parent as GenericStack).Orientation == Orientation.Horizontal) - Interface.CurrentInterface.MouseCursor = XCursor.H; + CurrentInterface.MouseCursor = XCursor.H; else - Interface.CurrentInterface.MouseCursor = XCursor.V; + CurrentInterface.MouseCursor = XCursor.V; } public override void onMouseLeave (object sender, MouseMoveEventArgs e) { base.onMouseLeave (sender, e); - Interface.CurrentInterface.MouseCursor = XCursor.Default; + CurrentInterface.MouseCursor = XCursor.Default; } public override void onMouseMove (object sender, MouseMoveEventArgs e) { diff --git a/src/GraphicObjects/TabItem.cs b/src/GraphicObjects/TabItem.cs index 2d2ba453..e14a7815 100644 --- a/src/GraphicObjects/TabItem.cs +++ b/src/GraphicObjects/TabItem.cs @@ -25,7 +25,6 @@ using System.Diagnostics; namespace Crow { - [DefaultTemplate("#Crow.Templates.TabItem.crow")] public class TabItem : TemplatedContainer { #region Private fields @@ -103,18 +102,19 @@ namespace Crow protected override void onDraw (Cairo.Context gr) { int spacing = (Parent as TabView).Spacing; - gr.MoveTo (0, TabTitle.Slot.Bottom); - gr.LineTo (TabTitle.Slot.Left - spacing, TabTitle.Slot.Bottom); + + gr.MoveTo (0, TabTitle.Slot.Bottom-0.5); + gr.LineTo (TabTitle.Slot.Left - spacing, TabTitle.Slot.Bottom-0.5); gr.CurveTo ( - TabTitle.Slot.Left - spacing / 2, TabTitle.Slot.Bottom, - TabTitle.Slot.Left - spacing / 2, 1, - TabTitle.Slot.Left, 1); - gr.LineTo (TabTitle.Slot.Right, 1); + TabTitle.Slot.Left - spacing / 2, TabTitle.Slot.Bottom-0.5, + TabTitle.Slot.Left - spacing / 2, 0.5, + TabTitle.Slot.Left, 0.5); + gr.LineTo (TabTitle.Slot.Right, 0.5); gr.CurveTo ( - TabTitle.Slot.Right + spacing / 2, 1, - TabTitle.Slot.Right + spacing / 2, TabTitle.Slot.Bottom, - TabTitle.Slot.Right + spacing, TabTitle.Slot.Bottom); - gr.LineTo (Slot.Width, TabTitle.Slot.Bottom); + TabTitle.Slot.Right + spacing / 2, 0.5, + TabTitle.Slot.Right + spacing / 2, TabTitle.Slot.Bottom-0.5, + TabTitle.Slot.Right + spacing, TabTitle.Slot.Bottom-0.5); + gr.LineTo (Slot.Width, TabTitle.Slot.Bottom-0.5); gr.LineWidth = 1; Foreground.SetAsSource (gr); diff --git a/src/GraphicObjects/TabView.cs b/src/GraphicObjects/TabView.cs index e140191b..a1d1a093 100644 --- a/src/GraphicObjects/TabView.cs +++ b/src/GraphicObjects/TabView.cs @@ -82,7 +82,7 @@ namespace Crow RegisterForRedraw (); } } - [XmlAttributeAttribute()][DefaultValue("15")] + [XmlAttributeAttribute()][DefaultValue("18")] public virtual Measure TabThickness { get { return tabThickness; } set { @@ -143,7 +143,7 @@ namespace Crow //if no layouting remains in queue for item, registre for redraw if (RegisteredLayoutings == LayoutingType.None && bmp == null) - Interface.CurrentInterface.EnqueueForRepaint (this); + CurrentInterface.EnqueueForRepaint (this); return true; } @@ -159,9 +159,12 @@ namespace Crow gr.Fill (); gr.Save (); - //clip to client zone - CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); - gr.Clip (); + + if (ClipToClientRect) { + //clip to client zone + CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); + gr.Clip (); + } for (int i = 0; i < Children.Count; i++) { if (i == SelectedTab) @@ -178,8 +181,8 @@ namespace Crow #region Mouse handling public override void checkHoverWidget (MouseMoveEventArgs e) { - if (Interface.CurrentInterface.HoverWidget != this) { - Interface.CurrentInterface.HoverWidget = this; + if (CurrentInterface.HoverWidget != this) { + CurrentInterface.HoverWidget = this; onMouseEnter (this, e); } diff --git a/src/GraphicObjects/TemplatedControl.cs b/src/GraphicObjects/TemplatedControl.cs index 422a45ec..b77c89e3 100644 --- a/src/GraphicObjects/TemplatedControl.cs +++ b/src/GraphicObjects/TemplatedControl.cs @@ -31,35 +31,14 @@ using System.Reflection; namespace Crow { - [AttributeUsage(AttributeTargets.Class)] - public class TemplateAttribute : Attribute - { - public string Path = ""; - public TemplateAttribute(string path) - { - Path = path; - } - } - - [AttributeUsage(AttributeTargets.Class)] - public class DefaultTemplate : TemplateAttribute - { - public DefaultTemplate(string path) : base(path){} - } - [AttributeUsage(AttributeTargets.Class)] - public class DefaultItemTemplate : TemplateAttribute - { - public DefaultItemTemplate(string path) : base(path){} - } - public abstract class TemplatedControl : PrivateContainer, IXmlSerializable { #region CTOR public TemplatedControl () : base() { - if (Interface.CurrentInterface.XmlLoading) - return; - loadTemplate (); +// if (CurrentInterface.XmlLoading) +// return; + //loadTemplate (); } #endregion @@ -78,7 +57,7 @@ namespace Crow if (string.IsNullOrEmpty(_template)) loadTemplate (); else - loadTemplate (Interface.Load (_template)); + loadTemplate (CurrentInterface.Load (_template)); } } [XmlAttributeAttribute][DefaultValue("#Crow.Templates.ItemTemplate.goml")] @@ -103,9 +82,12 @@ namespace Crow protected override void onDraw (Cairo.Context gr) { gr.Save (); - //clip to client zone - CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); - gr.Clip (); + + if (ClipToClientRect) { + //clip to client zone + CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); + gr.Clip (); + } if (child != null) child.Paint (ref gr); @@ -116,8 +98,9 @@ namespace Crow protected virtual void loadTemplate(GraphicObject template = null) { if (template == null) { - DefaultTemplate dt = (DefaultTemplate)this.GetType ().GetCustomAttributes (typeof(DefaultTemplate), true).FirstOrDefault(); - this.SetChild (Interface.Load (dt.Path)); + if (!Interface.DefaultTemplates.ContainsKey (this.GetType ().FullName)) + throw new Exception (string.Format ("No default template found for '{0}'", this.GetType ().FullName)); + this.SetChild (CurrentInterface.Load (Interface.DefaultTemplates[this.GetType ().FullName])); }else this.SetChild (template); @@ -195,7 +178,7 @@ namespace Crow } } } else - loadTemplate (Interface.Load (template)); + loadTemplate (CurrentInterface.Load (template)); //if no template found, load default one if (this.child == null) diff --git a/src/GraphicObjects/TextBox.cs b/src/GraphicObjects/TextBox.cs index 81fce3e2..44690342 100644 --- a/src/GraphicObjects/TextBox.cs +++ b/src/GraphicObjects/TextBox.cs @@ -76,15 +76,18 @@ namespace Crow switch (key) { case Key.Back: + if (CurrentPosition == 0) + return; this.DeleteChar(); break; case Key.Clear: break; case Key.Delete: - if (selectionIsEmpty) - CurrentColumn++; - else if (e.Shift) - Interface.CurrentInterface.Clipboard = this.SelectedText; + if (selectionIsEmpty) { + if (!MoveRight ()) + return; + }else if (e.Shift) + CurrentInterface.Clipboard = this.SelectedText; this.DeleteChar (); break; case Key.Enter: @@ -119,11 +122,11 @@ namespace Crow case Key.End: if (e.Shift) { if (selectionIsEmpty) - SelBegin = new Point (CurrentColumn, CurrentLine); + SelBegin = CurrentPosition; if (e.Control) CurrentLine = int.MaxValue; CurrentColumn = int.MaxValue; - SelRelease = new Point (CurrentColumn, CurrentLine); + SelRelease = CurrentPosition; break; } SelRelease = -1; @@ -133,9 +136,9 @@ namespace Crow break; case Key.Insert: if (e.Shift) - this.Insert (Interface.CurrentInterface.Clipboard); - else if (e.Control) - Interface.CurrentInterface.Clipboard = this.SelectedText; + this.Insert (CurrentInterface.Clipboard); + else if (e.Control && !selectionIsEmpty) + CurrentInterface.Clipboard = this.SelectedText; break; case Key.Left: if (e.Shift) { @@ -143,40 +146,40 @@ namespace Crow SelBegin = new Point(CurrentColumn, CurrentLine); if (e.Control) GotoWordStart (); - else - CurrentColumn--; - SelRelease = new Point(CurrentColumn, CurrentLine); + else if (!MoveLeft ()) + return; + SelRelease = CurrentPosition; break; } SelRelease = -1; if (e.Control) GotoWordStart (); else - CurrentColumn--; + MoveLeft(); break; case Key.Right: if (e.Shift) { if (selectionIsEmpty) - SelBegin = new Point(CurrentColumn, CurrentLine); + SelBegin = CurrentPosition; if (e.Control) GotoWordEnd (); - else - CurrentColumn++; - SelRelease = new Point(CurrentColumn, CurrentLine); + else if (!MoveRight ()) + return; + SelRelease = CurrentPosition; break; } SelRelease = -1; if (e.Control) GotoWordEnd (); else - CurrentColumn++; + MoveRight (); break; case Key.Up: if (e.Shift) { if (selectionIsEmpty) - SelBegin = new Point(CurrentColumn, CurrentLine); + SelBegin = CurrentPosition; CurrentLine--; - SelRelease = new Point(CurrentColumn, CurrentLine); + SelRelease = CurrentPosition; break; } SelRelease = -1; @@ -185,9 +188,9 @@ namespace Crow case Key.Down: if (e.Shift) { if (selectionIsEmpty) - SelBegin = new Point(CurrentColumn, CurrentLine); + SelBegin = CurrentPosition; CurrentLine++; - SelRelease = new Point(CurrentColumn, CurrentLine); + SelRelease = CurrentPosition; break; } SelRelease = -1; diff --git a/src/GraphicObjects/TreeView.cs b/src/GraphicObjects/TreeView.cs index 51080281..ef228260 100644 --- a/src/GraphicObjects/TreeView.cs +++ b/src/GraphicObjects/TreeView.cs @@ -27,7 +27,6 @@ namespace Crow { //treeview expect expandable child (or not) //if their are expandable, some functions and events are added - [DefaultTemplate("#Crow.Templates.TreeView.crow")] public class TreeView : ListBox { GraphicObject selectedItemContainer = null; @@ -79,6 +78,20 @@ namespace Crow "" : selectedItemContainer.DataSource; } } + + protected override void registerItemClick (GraphicObject g) + { + //register ItemClick on the Root node + TreeView tv = this as TreeView; + while (!tv.IsRoot) { + ILayoutable tmp = tv.Parent; + while (!(tmp is TreeView)) { + tmp = tmp.Parent; + } + tv = tmp as TreeView; + } + g.MouseClick += tv.itemClick; + } internal override void itemClick (object sender, MouseButtonEventArgs e) { GraphicObject tmp = sender as GraphicObject; diff --git a/src/GraphicObjects/Window.cs b/src/GraphicObjects/Window.cs index be482e43..9ef9e642 100644 --- a/src/GraphicObjects/Window.cs +++ b/src/GraphicObjects/Window.cs @@ -26,7 +26,6 @@ using System.Diagnostics; namespace Crow { - [DefaultTemplate("#Crow.Templates.Window.goml")] public class Window : TemplatedContainer { enum Direction @@ -47,11 +46,15 @@ namespace Crow bool _resizable; bool _movable; bool hoverBorder = false; + bool isMaximized = false; + Measure savedH, savedW; Container _contentContainer; Direction currentDirection = Direction.None; public event EventHandler Closing; + public event EventHandler Maximized; + public event EventHandler Unmaximized; #region CTOR public Window () : base() { @@ -75,6 +78,7 @@ namespace Crow } #endregion + #region public properties [XmlAttributeAttribute()][DefaultValue("Window")] public string Title { get { return _title; } @@ -111,6 +115,24 @@ namespace Crow NotifyValueChanged ("Movable", _movable); } } + [XmlAttributeAttribute()][DefaultValue(false)] + public bool IsMaximized { + get { return isMaximized; } + set{ + if (value == isMaximized) + return; + isMaximized = value; + + if (isMaximized) + onMaximized (this, null); + else + onUnmaximized (this, null); + + NotifyValueChanged ("IsMaximized", isMaximized); + } + } + #endregion + #region GraphicObject Overrides public override void ResolveBindings () { @@ -122,11 +144,11 @@ namespace Crow { base.onMouseMove (sender, e); - Interface otkgw = Interface.CurrentInterface; + Interface otkgw = CurrentInterface; if (!hoverBorder) { currentDirection = Direction.None; - Interface.CurrentInterface.MouseCursor = XCursor.Default; + CurrentInterface.MouseCursor = XCursor.Default; return; } @@ -273,28 +295,45 @@ namespace Crow base.onMouseDown (sender, e); } #endregion + protected void onMaximized (object sender, EventArgs e){ + savedW = this.Width; + savedH = this.Height; + this.Width = Measure.Stretched; + this.Height = Measure.Stretched; + + Maximized.Raise (sender, e); + } + protected void onUnmaximized (object sender, EventArgs e){ + this.Width = savedW; + this.Height = savedH; - public void onBorderMouseLeave (object sender, MouseMoveEventArgs e) + Unmaximized.Raise (sender, e); + } + + protected void onBorderMouseLeave (object sender, MouseMoveEventArgs e) { hoverBorder = false; currentDirection = Direction.None; - Interface.CurrentInterface.MouseCursor = XCursor.Default; + CurrentInterface.MouseCursor = XCursor.Default; } - public void onBorderMouseEnter (object sender, MouseMoveEventArgs e) + protected void onBorderMouseEnter (object sender, MouseMoveEventArgs e) { hoverBorder = true; } + protected void butMaximizePress (object sender, MouseButtonEventArgs e){ + IsMaximized = !IsMaximized; + } protected void butQuitPress (object sender, MouseButtonEventArgs e) { - Interface.CurrentInterface.MouseCursor = XCursor.Default; + CurrentInterface.MouseCursor = XCursor.Default; close (); } void close(){ Closing.Raise (this, null); - Interface.CurrentInterface.DeleteWidget (this); + CurrentInterface.DeleteWidget (this); } } } diff --git a/src/GraphicObjects/Wrapper.cs b/src/GraphicObjects/Wrapper.cs new file mode 100644 index 00000000..03251af9 --- /dev/null +++ b/src/GraphicObjects/Wrapper.cs @@ -0,0 +1,226 @@ +// +// Wrapper.cs +// +// Author: +// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> +// +// Copyright (c) 2016 jp +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +using System; + +namespace Crow +{ + public class Wrapper : GenericStack + { + public Wrapper () : base() + {} + + #region Group Overrides + public override void ChildrenLayoutingConstraints (ref LayoutingType layoutType) + { + layoutType &= (~LayoutingType.Positioning); + } + public override void ComputeChildrenPositions() + { + int dx = 0; + int dy = 0; + + if (Orientation == Orientation.Vertical) { + int tallestChild = 0; + foreach (GraphicObject c in Children) { + if (!c.Visible) + continue; + if (dx + c.Slot.Width > ClientRectangle.Width) { + dx = 0; + dy += tallestChild + Spacing; + c.Slot.X = dx; + c.Slot.Y = dy; + tallestChild = c.Slot.Height; + } else { + if (tallestChild < c.Slot.Height) + tallestChild = c.Slot.Height; + c.Slot.X = dx; + c.Slot.Y = dy; + } + dx += c.Slot.Width + Spacing; + } + } else { + int largestChild = 0; + foreach (GraphicObject c in Children) { + if (!c.Visible) + continue; + if (dy + c.Slot.Height > ClientRectangle.Height) { + dy = 0; + dx += largestChild + Spacing; + c.Slot.X = dx; + c.Slot.Y = dy; + largestChild = c.Slot.Width; + } else { + if (largestChild < c.Slot.Width) + largestChild = c.Slot.Width; + c.Slot.X = dx; + c.Slot.Y = dy; + } + dy += c.Slot.Height + Spacing; + } + } + bmp = null; + } + public override void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) + { + //children can't stretch in a wrapper + GraphicObject go = sender as GraphicObject; + //Debug.WriteLine ("child layout change: " + go.LastSlots.ToString() + " => " + go.Slot.ToString()); + switch (arg.LayoutType) { + case LayoutingType.Width: + if (Orientation == Orientation.Horizontal && go.Width.Units == Unit.Percent) { + go.Width = Measure.Fit; + return; + } + break; + case LayoutingType.Height: + if (Orientation == Orientation.Vertical && go.Height.Units == Unit.Percent) { + go.Height = Measure.Fit; + return; + } + break; + default: + return; + } + this.RegisterForLayouting (LayoutingType.ArrangeChildren); + } + #endregion + + #region GraphicObject Overrides + protected override int measureRawSize (LayoutingType lt) + { + int tmp = 0; + //Wrapper can't fit in the direction of the wrapper + if (lt == LayoutingType.Width) { + if (Orientation == Orientation.Vertical) { + Width = Measure.Stretched; + return -1; + } else if (RegisteredLayoutings.HasFlag (LayoutingType.Height)) + return -1; + else { + int dy = 0; + int largestChild = 0; + lock (Children) { + foreach (GraphicObject c in Children) { + if (!c.Visible) + continue; + if (c.Height.Units == Unit.Percent && + c.RegisteredLayoutings.HasFlag (LayoutingType.Height)) + return -1; + if (dy + c.Slot.Height > ClientRectangle.Height) { + dy = 0; + tmp += largestChild + Spacing; + largestChild = c.Slot.Width; + } else if (largestChild < c.Slot.Width) + largestChild = c.Slot.Width; + + dy += c.Slot.Height + Spacing; + } + if (dy == 0) + tmp -= Spacing; + return tmp + largestChild + 2 * Margin; + } + } + } else if (Orientation == Orientation.Horizontal) { + Height = Measure.Stretched; + return -1; + } else if (RegisteredLayoutings.HasFlag (LayoutingType.Width)) + return -1; + else { + int dx = 0; + int tallestChild = 0; + lock (Children) { + foreach (GraphicObject c in Children) { + if (!c.Visible) + continue; + if (c.Width.Units == Unit.Percent && + c.RegisteredLayoutings.HasFlag (LayoutingType.Width)) + return -1; + if (dx + c.Slot.Width > ClientRectangle.Width) { + dx = 0; + tmp += tallestChild + Spacing; + tallestChild = c.Slot.Height; + } else if (tallestChild < c.Slot.Height) + tallestChild = c.Slot.Height; + + dx += c.Slot.Width + Spacing; + } + if (dx == 0) + tmp -= Spacing; + return tmp + tallestChild + 2 * Margin; + } + } + } + + public override bool UpdateLayout (LayoutingType layoutType) + { + RegisteredLayoutings &= (~layoutType); + + if (layoutType == LayoutingType.ArrangeChildren) { + if ((RegisteredLayoutings & LayoutingType.Sizing) != 0) + return false; + + ComputeChildrenPositions (); + + //if no layouting remains in queue for item, registre for redraw + if (RegisteredLayoutings == LayoutingType.None && bmp == null) + CurrentInterface.EnqueueForRepaint (this); + + return true; + } + + return base.UpdateLayout(layoutType); + } + public override void OnLayoutChanges (LayoutingType layoutType) + { + #if DEBUG_LAYOUTING + LayoutingQueueItem.currentLQI.Slot = LastSlots; + LayoutingQueueItem.currentLQI.Slot = Slot; + #endif + + switch (layoutType) { + case LayoutingType.Width: + foreach (GraphicObject c in Children) { + if (c.Width.Units == Unit.Percent) + c.RegisterForLayouting (LayoutingType.Width); + } + if (Height == Measure.Fit) + RegisterForLayouting (LayoutingType.Height); + RegisterForLayouting (LayoutingType.X); + break; + case LayoutingType.Height: + foreach (GraphicObject c in Children) { + if (c.Height.Units == Unit.Percent) + c.RegisterForLayouting (LayoutingType.Height); + } + if (Width == Measure.Fit) + RegisterForLayouting (LayoutingType.Width); + RegisterForLayouting (LayoutingType.Y); + break; + default: + return; + } + RegisterForLayouting (LayoutingType.ArrangeChildren); + //LayoutChanged.Raise (this, new LayoutingEventArgs (layoutType)); + } + #endregion + } +} + |