<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType>
-- <DefineConstants>TRACE;DEBUG;DESIGN_MODE;_DEBUG_CLIP_RECTANGLE;NETFRAMEWORK;NET471</DefineConstants>
++ <DefineConstants>TRACE;DESIGN_MODE;_DEBUG_CLIP_RECTANGLE;_DEBUG_FOCUS;_DEBUG_DRAGNDROP;DEBUG;NETFRAMEWORK;NET471</DefineConstants>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
</PropertyGroup>
Width = "12";
Height = "12";
}
--
Wrapper {
Orientation = "Vertical";
}
Label {
Height = "Fit";
Width = "Fit";
-- Margin = "0";
++ Margin = "0";
++}
++TextBox {
++ Background = "White";
++ Foreground = "Black";
++ Selectable = "True";
++ Text = "TextBox";
++ Margin = "1";
++ MouseCursor = "IBeam";
}
Menu {
Margin = "1";
//MouseLeave = "{Foreground=LightGrey;Background=Jet;}";
AllowDrag = "true";
}
--TextBox {
-- Background = "White";
-- Foreground = "Black";
-- Selectable = "True";
-- Text = "TextBox";
-- Margin = "1";
--}
Window {
Caption = "Window";
Focusable = "true";
<?xml version="1.0"?>
-<HorizontalStack>
<Popper Font="{./Font}" Caption="{./Caption}" Background="{./Background}" PopDirection="{./PopDirection}"
- Foreground = "{./Foreground}" CanPop="{./HasChildren}" MouseClick="./onMI_Click"
+ Foreground = "{./Foreground}" CanPop="{./HasChildren}"
IsPopped="{²./IsOpened}" PopWidth="{./PopWidth}" PopHeight="{./PopHeight}">
<Template>
<CheckBox IsChecked="{²./IsPopped}" Caption="{./Caption}" Background="{./Background}" Foreground="{./Foreground}">
<?xml version="1.0"?>
<CheckBox Caption="{./Caption}" IsChecked="{²./IsPopped}" Foreground="{./Foreground}" Background="{./Background}">
<Template>
- <Border Style="ControlBorder" Foreground="{./Foreground}" Background="{./Background}">
- <Border Style="ControlBorder" Foreground="{./Foreground}" Background="{./Background}" ForwardMouseEvents="true">
++ <Border Style="ControlBorder" Foreground="{./Foreground}" Background="{./Background}" >
<HorizontalStack Spacing="1">
<Image Style="Icon" Margin="1" Width="9" Height="9"
MouseEnter="{Background=White}" MouseLeave="{Background=Transparent}"
}
}
-- public override void onMouseDown (object sender, MouseButtonEventArgs e)
++ public override void onMouseClick (object sender, MouseButtonEventArgs e)
{
IsChecked = !IsChecked;
-- base.onMouseDown (sender, e);
++ base.onMouseClick (sender, e);
}
}
}
}
public override void onMouseDown (object sender, MouseButtonEventArgs e)
{
++ e.Handled = true;
base.onMouseDown (sender, e);
if (this.HasFocus && IsDocked && e.Button == MouseButton.Left)
public bool CheckUndock (Point mousePos) {
//if (DockingPosition == Alignment.Center)
// return false;
++ Console.WriteLine ($"{mousePos.X},{mousePos.Y}");
if (Math.Abs (mousePos.X - undockingMousePosOrig.X) < undockThreshold ||
Math.Abs (mousePos.X - undockingMousePosOrig.X) < undockThreshold)
return false;
try {
for (int i = 0; i < lines.Count; i++) {
-- string l = lines[i].Replace ("\t", new String (' ', Interface.TabSize));
++ string l = lines[i].Replace ("\t", new String (' ', Interface.TAB_SIZE));
TextExtents tmp = gr.TextExtents (l);
//*******************
for (int i = 0; i < lines.Count; i++) {
-- string l = lines [i].Replace ("\t", new String (' ', Interface.TabSize));
++ string l = lines [i].Replace ("\t", new String (' ', Interface.TAB_SIZE));
int lineLength = (int)gr.TextExtents (l).XAdvance;
Rectangle lineRect = new Rectangle (
rText.X,
if (mouseLocalPos.Y < 0)
mouseLocalPos.Y = 0;
}
-- public override void onMouseEnter (object sender, MouseMoveEventArgs e)
-- {
-- base.onMouseEnter (sender, e);
-- if (Selectable)
- IFace.MouseCursor = MouseCursor.IBeam;
- IFace.MouseCursor = XCursor.Text;
-- }
-- public override void onMouseLeave (object sender, MouseMoveEventArgs e)
-- {
-- base.onMouseLeave (sender, e);
- IFace.MouseCursor = MouseCursor.Arrow;
- IFace.MouseCursor = XCursor.Default;
-- }
protected override void onFocused (object sender, EventArgs e)
{
base.onFocused (sender, e);
{
string c = lines [CurrentLine].Substring (i, 1);
if (c == "\t")
-- c = new string (' ', Interface.TabSize);
++ c = new string (' ', Interface.TAB_SIZE);
te = gr.TextExtents(c);
{
try {
string l = lines [pos.Y].Substring (0, pos.X).
-- Replace ("\t", new String (' ', Interface.TabSize));
++ Replace ("\t", new String (' ', Interface.TAB_SIZE));
return gr.TextExtents (l).XAdvance;
} catch{
return -1;
IsOpened = false;
base.onMouseLeave (this, e);
}
+ public override void onMouseClick (object sender, MouseButtonEventArgs e)
+ {
++#if DEBUG_FOCUS
++ System.Diagnostics.Debug.WriteLine ("MENU CLICK => " + this.ToString ());
++#endif
+ if (command != null) {
+ command.Execute ();
+ closeMenu ();
+ }
+ if (hasClick)
+ base.onMouseClick (sender, e);
+ if (!IsOpened)
+ (LogicalParent as Menu).AutomaticOpening = false;
+ }
void closeMenu () {
MenuItem tmp = LogicalParent as MenuItem;
while (tmp != null) {
set {
if (_content != null) {
_content.LogicalParent = null;
-- _content.isPopup = false;
++ //_content.isPopup = false;
_content.LayoutChanged -= _content_LayoutChanged;
}
return;
_content.LogicalParent = this;
-- _content.isPopup = true;
++ //_content.isPopup = true;
_content.HorizontalAlignment = HorizontalAlignment.Left;
_content.VerticalAlignment = VerticalAlignment.Top;
_content.LayoutChanged += _content_LayoutChanged;
Content.Visible = true;
if (Content.Parent == null)
IFace.AddWidget (Content);
-- if (Content.LogicalParent != this)
-- Content.LogicalParent = this;
++ //if (Content.LogicalParent != this)
++ Content.LogicalParent = this;
IFace.PutOnTop (Content, true);
_content_LayoutChanged (this, new LayoutingEventArgs (LayoutingType.Sizing));
}
/// <summary> Process scrolling vertically, or if shift is down, vertically </summary>
public override void onMouseWheel (object sender, MouseWheelEventArgs e)
{
-- base.onMouseWheel (sender, e);
if (IFace.IsKeyDown (Key.Shift_L))
ScrollX += e.Delta * ScrollSpeed;
else
ScrollY -= e.Delta * ScrollSpeed;
++ e.Handled = true;
++ base.onMouseWheel (sender, e);
}
/// <summary> Process scrolling with arrow keys, home and end keys. </summary>
public override void onKeyDown (object sender, KeyEventArgs e)
{
base.onMouseEnter (sender, e);
if ((Parent as GenericStack).Orientation == Orientation.Horizontal)
- IFace.MouseCursor = XCursor.H;
+ IFace.MouseCursor = MouseCursor.H;
else
- IFace.MouseCursor = XCursor.V;
- }
- public override void onMouseLeave (object sender, MouseMoveEventArgs e)
- {
- base.onMouseLeave (sender, e);
- IFace.MouseCursor = XCursor.Default;
+ IFace.MouseCursor = MouseCursor.V;
}
- public override void onMouseLeave (object sender, MouseMoveEventArgs e)
- {
- base.onMouseLeave (sender, e);
- IFace.MouseCursor = MouseCursor.Arrow;
- }
public override void onMouseDown (object sender, MouseButtonEventArgs e)
{
base.onMouseDown (sender, e);
}
foreach (string s in lines) {
-- string l = s.Replace("\t", new String (' ', Interface.TabSize));
++ string l = s.Replace("\t", new String (' ', Interface.TAB_SIZE));
TextExtents tmp = gr.TextExtents (l);
if (tmp.XAdvance > te.XAdvance)
te = tmp;
int curLineCount = 0;
for (int i = 0; i < lines.Count; i++) {
-- string l = lines [i].Replace ("\t", new String (' ', Interface.TabSize));
++ string l = lines [i].Replace ("\t", new String (' ', Interface.TAB_SIZE));
List<string> wl = new List<string> ();
int lineLength = (int)gr.TextExtents (l).XAdvance;
internal static List<GraphicObject> GraphicObjects = new List<GraphicObject>();
#endif
-- internal bool isPopup = false;
-- public Widget focusParent {
-- get { return (isPopup ? LogicalParent : parent) as Widget; }
-- }
++ //internal bool isPopup = false;
++ //public Widget focusParent {
++ // get { return (isPopup ? LogicalParent : parent) as Widget; }
++ //}
/// <summary>
/// interface this widget is bound to, this should not be changed once the instance is created
Font font = "sans, 10";
protected Measure width, height;
int left, top;
- double cornerRadius = 0;
- int margin = 0;
- bool focusable = false;
- bool hasFocus = false;
- bool isActive = false;
- //bool isHover = false;
+ double cornerRadius;
+ int margin;
+ bool focusable ;
+ bool hasFocus;
+ bool isActive;
+ bool isHover;
bool mouseRepeat;
- bool forwardMouseEvents;
++ MouseCursor mouseCursor = MouseCursor.Arrow;
protected bool isVisible = true;
bool isEnabled = true;
VerticalAlignment verticalAlignment = VerticalAlignment.Center;
onParentChanged (this, e);
}
}
++ /// <summary>
++ /// Mouse routing need to go back to logical parent for popups
++ /// </summary>
++ public Widget FocusParent => (parent is Interface ? LogicalParent : parent) as Widget;
++
[XmlIgnore]public ILayoutable LogicalParent {
get { return logicalParent == null ? Parent : logicalParent; }
set {
if (logicalParent == value)
return;
-- if (logicalParent != null)
++ if (logicalParent is Widget)
(logicalParent as Widget).DataSourceChanged -= onLogicalParentDataSourceChanged;
DataSourceChangeEventArgs dsce = new DataSourceChangeEventArgs (LogicalParent, null);
logicalParent = value;
dsce.NewDataSource = LogicalParent;
-- if (logicalParent != null)
++ if (logicalParent is Widget)
(logicalParent as Widget).DataSourceChanged += onLogicalParentDataSourceChanged;
onLogicalParentChanged (this, dsce);
}
NotifyValueChanged ("MouseRepeat", mouseRepeat);
}
}
- /// forward mouse events even if an handle is bound
+ /// <summary>
- [DesignCategory ("Behaviour")][DefaultValue (false)]
- public bool ForwardMouseEvents {
- get { return forwardMouseEvents; }
++ /// Determine Cursor when mouse is Hover.
+ /// </summary>
- if (forwardMouseEvents == value)
++ [DesignCategory ("Behaviour")]
++ [DefaultValue (MouseCursor.Arrow)]
++ public virtual MouseCursor MouseCursor {
++ get { return mouseCursor; }
+ set {
- forwardMouseEvents = value;
- NotifyValueChanged ("ForwardMouseEvents", forwardMouseEvents);
++ if (mouseCursor == value)
+ return;
++ mouseCursor = value;
++ NotifyValueChanged ("MouseCursor", mouseCursor);
++ this.RegisterForRedraw ();
++
++ if (isHover)
++ IFace.MouseCursor = mouseCursor;
+ }
+ }
++
++ /// <summary>
++ /// forward mouse events even if an handle is bound
++ /// </summary>
++ //[DesignCategory ("Behaviour")][DefaultValue (false)]
++ //public bool ForwardMouseEvents {
++ // get { return forwardMouseEvents; }
++ // set {
++ // if (forwardMouseEvents == value)
++ // return;
++ // forwardMouseEvents = value;
++ // NotifyValueChanged ("ForwardMouseEvents", forwardMouseEvents);
++ // }
++ //}
bool clearBackground = false;
/// <summary>
/// background fill of the control, maybe solid color, gradient, image, or svg
#region Keyboard handling
public virtual void onKeyDown(object sender, KeyEventArgs e){
-- KeyDown.Raise (this, e);
++ if (KeyDown != null)
++ KeyDown.Invoke (this, e);
++ else if (!e.Handled)
++ FocusParent?.onKeyDown (sender, e);
}
public virtual void onKeyUp(object sender, KeyEventArgs e){
-- KeyUp.Raise (this, e);
++ if (KeyUp != null)
++ KeyUp.Invoke (this, e);
++ else if (!e.Handled)
++ FocusParent?.onKeyUp (sender, e);
}
public virtual void onKeyPress(object sender, KeyPressEventArgs e){
-- KeyPress.Raise (this, e);
++ if (KeyPress != null)
++ KeyPress.Invoke (this, e);
++ else if (!e.Handled)
++ FocusParent?.onKeyPress (sender, e);
}
#endregion
//this.onMouseMove (this, e);//without this, window border doesn't work, should be removed
}
-- public virtual void onMouseMove(object sender, MouseMoveEventArgs e)
++ public virtual void onMouseMove (object sender, MouseMoveEventArgs e)
{
if (allowDrag & hasFocus & e.Mouse.LeftButton == ButtonState.Pressed) {
if (IFace.DragAndDropOperation == null) {
//to let other control behind have mouse entering
if (isDragged)
return;
-
- //bubble event to the top
- Widget p = focusParent;
- if (p != null)
- p.onMouseMove(sender,e);
- MouseMove.Raise (this, e);
- if (MouseMove == null)
- focusParent?.onMouseMove (sender, e);
- else
- MouseMove.Invoke (this, e);
++ if (MouseMove != null)
++ MouseMove.Invoke (this, e);
++ else if (!e.Handled)
++ FocusParent?.onMouseMove (sender, e);
++
+
}
public virtual void onMouseDown(object sender, MouseButtonEventArgs e){
- #if DEBUG_FOCUS
+ #if DEBUG_FOCUS
Debug.WriteLine("MOUSE DOWN => " + this.ToString());
- #endif
+ #endif
- if (focusable && !Interface.FocusOnHover) {
- /*if (focusable && !Interface.FocusOnHover) {
-- BubblingMouseButtonEventArg be = e as BubblingMouseButtonEventArg;
-- if (be.Focused == null) {
-- be.Focused = this;
-- IFace.FocusedWidget = this;
-- if (e.Button == MouseButton.Right && contextCommands != null)
-- IFace.ShowContextMenu (this);
-- }
- }*/
++ if (e.Button == MouseButton.Right && contextCommands != null) {
++ IFace.ShowContextMenu (this);
++ e.Handled = true;
+ }
- //bubble event to the top
- Widget p = focusParent;
- if (p != null)
- p.onMouseDown(sender,e);
+
- MouseDown.Raise (this, e);
+ if (MouseDown != null)
- MouseDown.Invoke (this, e);
- if (MouseDown == null || forwardMouseEvents)
- focusParent?.onMouseDown (sender, e);
++ MouseDown?.Invoke (this, e);
++ else if (!e.Handled)
++ FocusParent?.onMouseDown (sender, e);
}
public virtual void onMouseUp(object sender, MouseButtonEventArgs e){
- #if DEBUG_FOCUS
+ #if DEBUG_FOCUS
Debug.WriteLine("MOUSE UP => " + this.ToString());
- #endif
+ #endif
- /*if (IFace.DragAndDropOperation != null){
+ if (IFace.DragAndDropOperation != null){
if (IFace.DragAndDropOperation.DragSource == this) {
if (IFace.DragAndDropOperation.DropTarget != null)
onDrop (this, IFace.DragAndDropOperation);
onEndDrag (this, IFace.DragAndDropOperation);
IFace.DragAndDropOperation = null;
}
- }*/
-
+ }
-
- //bubble event to the top
- Widget p = focusParent;
- if (p != null)
- p.onMouseUp(sender,e);
-
- MouseUp.Raise (this, e);
+ if (MouseUp != null)
+ MouseUp.Invoke (this, e);
- if (MouseUp == null || forwardMouseEvents)
- focusParent?.onMouseUp (sender, e);
-
++ else if (!e.Handled)
++ FocusParent?.onMouseUp (sender, e);
}
public virtual void onMouseClick(object sender, MouseButtonEventArgs e){
#if DEBUG_FOCUS
Debug.WriteLine("CLICK => " + this.ToString());
#endif
- if (MouseClick != null)
- {
- MouseClick.Raise(this, e);
- return;
- }
- Widget p = focusParent;
- if (p != null)
- p.onMouseClick(sender,e);
+ if (MouseClick != null)
+ MouseClick.Invoke (this, e);
- if (MouseClick == null || forwardMouseEvents)
- focusParent?.onMouseClick (sender, e);
++ else if (!e.Handled)
++ FocusParent?.onMouseClick (sender, e);
}
public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){
#if DEBUG_FOCUS
Debug.WriteLine("DOUBLE CLICK => " + this.ToString());
#endif
- if (MouseDoubleClick != null)
- {
- MouseDoubleClick.Raise(this, e);
- return;
- }
- Widget p = focusParent;
- if (p != null)
- p.onMouseDoubleClick(sender,e);
- if (MouseDoubleClick != null)
++ if (MouseDoubleClick != null)
+ MouseDoubleClick.Invoke (this, e);
- if (MouseDoubleClick == null || forwardMouseEvents)
- focusParent?.onMouseDoubleClick (sender, e);
++ else if (!e.Handled)
++ FocusParent?.onMouseDoubleClick (sender, e);
}
public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){
- if (MouseWheelChanged != null)
- {
- MouseWheelChanged.Raise(this, e);
- return;
- }
- Widget p = focusParent;
- if (p != null)
- p.onMouseWheel(sender,e);
+ if (MouseWheelChanged != null)
+ MouseWheelChanged.Invoke (this, e);
- if (MouseWheelChanged == null || forwardMouseEvents)
- focusParent?.onMouseWheel (sender, e);
-
++ else if (!e.Handled)
++ FocusParent?.onMouseWheel (sender, e);
}
public virtual void onMouseEnter(object sender, MouseMoveEventArgs e)
{
#if DEBUG_FOCUS
Debug.WriteLine("MouseEnter => " + this.ToString());
-- #endif
++#endif
++
++ IFace.MouseCursor = mouseCursor;
if (IFace.DragAndDropOperation != null) {
Widget g = this;
}
break;
}
-- g = g.focusParent;
++ g = g.FocusParent;
}
}
Interface otkgw = IFace;
-- if (!hoverBorder) {
++ /*if (!hoverBorder) {
currentDirection = Direction.None;
- IFace.MouseCursor = XCursor.Default;
+ IFace.MouseCursor = MouseCursor.Arrow;
return;
-- }
++ }*/
if (this.HasFocus && movable) {
if (e.Mouse.IsButtonDown (MouseButton.Left)) {
namespace Crow
{
-- public class KeyEventArgs : EventArgs
++ public class KeyEventArgs : CrowEventArgs
{
int keyCode;
Key key;
/// Defines the event arguments for KeyPress events. Instances of this class are cached:
/// KeyPressEventArgs should only be used inside the relevant event, unless manually cloned.
/// </summary>
-- public class KeyPressEventArgs : EventArgs
++ public class KeyPressEventArgs : CrowEventArgs
{
char key_char;
namespace Crow
{
-- /// <summary>
-- /// Defines the event data for <see cref="MouseDevice"/> events.
-- /// </summary>
-- /// <remarks>
-- /// <para>
-- /// Do not cache instances of this type outside their event handler.
-- /// If necessary, you can clone an instance using the
-- /// <see cref="MouseEventArgs(MouseEventArgs)"/> constructor.
-- /// </para>
-- /// </remarks>
-- public class MouseEventArgs : EventArgs
++ public class CrowEventArgs : EventArgs
++ {
++ public bool Handled;
++ }
++ public class MouseEventArgs : CrowEventArgs
{
#region Fields
throw new Exception (@"C.R.O.W. run only on Mono, download latest version at: http://www.mono-project.com/download/stable/");
}*/
-- CrowConfigRoot =
++ CROW_CONFIG_ROOT =
System.IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".config");
-- CrowConfigRoot = System.IO.Path.Combine (CrowConfigRoot, "crow");
-- if (!Directory.Exists (CrowConfigRoot))
-- Directory.CreateDirectory (CrowConfigRoot);
++ CROW_CONFIG_ROOT = System.IO.Path.Combine (CROW_CONFIG_ROOT, "crow");
++ if (!Directory.Exists (CROW_CONFIG_ROOT))
++ Directory.CreateDirectory (CROW_CONFIG_ROOT);
//ensure all assemblies are loaded, because IML could contains classes not instanciated in source
foreach (string af in Directory.GetFiles (AppDomain.CurrentDomain.BaseDirectory, "*.dll")){
t.Start ();
}
public void Run () {
- //load default main.crow if present
- try {
- Load ("#main.crow").DataSource = this;
- } catch { }
-
++ Startup ();
while (running) {
ProcessEvents ();
Thread.Sleep(1);
}
}
++ protected virtual void Startup ()
++ {
++ //load default main.crow if present
++ try {
++ Load ("#main.crow").DataSource = this;
++ } catch { }
++ }
public void ProcessKeyPress (char c)
{
-- if (_focusedWidget != null)
-- _focusedWidget.onKeyPress (this, new KeyPressEventArgs(c));
++ _focusedWidget?.onKeyPress (_focusedWidget, new KeyPressEventArgs(c));
}
public void ProcessKeyUp (Key key)
{
-- if (_focusedWidget != null)
-- _focusedWidget.onKeyUp (this, new KeyEventArgs(key, false));
++ _focusedWidget?.onKeyUp (_focusedWidget, new KeyEventArgs(key, false));
// if (keyboardRepeatThread != null) {
// keyboardRepeatOn = false;
// keyboardRepeatThread.Abort();
//Keyboard.SetKeyState((Crow.Key)Key,true);
lastKeyDownEvt = new KeyEventArgs (key, true);
-- if (_focusedWidget != null)
-- _focusedWidget.onKeyDown (this, new KeyEventArgs (key, false));
++ _focusedWidget?.onKeyDown (_focusedWidget, new KeyEventArgs (key, false));
// keyboardRepeatThread = new Thread (keyboardRepeatThreadFunc);
// keyboardRepeatThread.IsBackground = true;
}
#endregion
- public void ProcessEvents() {
+ public void ProcessEvents ()
+ {
+
- if (armedClick != null) {
- if (lastClickTime.ElapsedMilliseconds > DoubleClick) {
- //cancel double click and
- armedClick.onMouseClick (armedClick, armedClickEventArgs);
- armedClick = null;
- }
- }
++ //if (armedClick != null) {
++ // if (lastClickTime.ElapsedMilliseconds > DOUBLECLICK_TRESHOLD) {
++ // //cancel double click and
++ // armedClick.onMouseClick (armedClick, armedClickEventArgs);
++ // armedClick = null;
++ // }
++ //}
+
+ Widget w = _hoverWidget; //previous hover widget
+
backend.ProcessEvents ();
- if (!FocusOnHover || (w == _hoverWidget))
+
- FocusedWidget = _hoverWidget;
++ if (DragAndDropOperation != null)
++ return;
++
++ if (!FOCUS_ON_HOVER || (w == _hoverWidget))
+ return;
+
+ w = _hoverWidget;
+ while (w != null) {
+ if (w.Focusable) {
- w = w.focusParent;
++ FocusedWidget = w;
+ break;
+ }
++ w = w.LogicalParent as Widget;
+ }
+
}
public void Init () {
CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
/// <summary>
/// Crow configuration root path
/// </summary>
-- public static string CrowConfigRoot;
++ public static string CROW_CONFIG_ROOT;
/// <summary>If true, mouse focus is given when mouse is over control</summary>
- public static bool FocusOnHover = false;
- public static bool FocusOnHover = true;
++ public static bool FOCUS_ON_HOVER = true;
/// <summary> Threshold to catch borders for sizing </summary>
public static int BorderThreshold = 5;
/// <summary> delay before tooltip appear </summary>
-- public static int ToolTipDelay = 500;
++ public static int TOOLTIP_DELAY = 500;
/// <summary>Double click threshold in milisecond</summary>
- public static int DoubleClick = 250;//max duration between two mouse_down evt for a dbl clk in milisec.
- public static int DoubleClick = 240;//max duration between two mouse_down evt for a dbl clk in milisec.
++ public static int DOUBLECLICK_TRESHOLD = 240;//max duration between two mouse_down evt for a dbl clk in milisec.
/// <summary> Time to wait in millisecond before starting repeat loop</summary>
-- public static int DeviceRepeatDelay = 700;
++ public static int DEVICE_REPEAT_DELAY = 700;
/// <summary> Time interval in millisecond between device event repeat</summary>
-- public static int DeviceRepeatInterval = 40;
++ public static int DEVICE_REPEAT_INTERVAL = 40;
public static float WheelIncrement = 1;
/// <summary>Tabulation size in Text controls</summary>
-- public static int TabSize = 4;
++ public static int TAB_SIZE = 4;
public static string LineBreak = "\n";
/// <summary> Allow rendering of interface in development environment </summary>
public static bool DesignerMode = false;
/// the ref of this one will be stored in GraphicObject.currentInterface
/// </summary>
protected static Interface CurrentInterface;
- internal Stopwatch clickTimer = new Stopwatch();
- Widget armedClickSender = null;
- MouseButtonEventArgs armedClickEvtArgs = null;
- // internal GraphicObject EligibleForDoubleClick {
- // get { return eligibleForDoubleClick; }
- // set {
- // eligibleForDoubleClick = value;
- // clickTimer.Restart ();
- // }
- // }
- internal void armeClick (Widget sender, MouseButtonEventArgs e){
- armedClickSender = sender;
- armedClickEvtArgs = e;
- clickTimer.Restart ();
- }
-
- Stopwatch lastClickTime = new Stopwatch ();
- Widget armedClick;//store widget with double click on first click
- MouseButtonEventArgs armedClickEventArgs;
#endregion
#region Events
#if DEBUG_FOCUS
NotifyValueChanged("HoverWidget", _hoverWidget);
#endif
-- /*
++
if (_hoverWidget != null)
{
_hoverWidget.IsHover = true;
-- #if DEBUG_FOCUS
++#if DEBUG_FOCUS
Debug.WriteLine("Hover => " + _hoverWidget.ToString());
-- }else
++ }else
Debug.WriteLine("Hover => null");
-- #else
++#else
}
-- #endif
-- */
++#endif
}
}
/// <summary>Widget has the keyboard or mouse focus</summary>
for (int i = 0; i < tmpThreads.Length; i++)
tmpThreads [i].CheckState ();
- if (mouseRepeatTimer.ElapsedMilliseconds > 0) {
- if (_hoverWidget != null && _hoverWidget.MouseRepeat) {
- int repeatCount = (int)mouseRepeatTimer.ElapsedMilliseconds / DeviceRepeatInterval - mouseRepeatCount;
- for (int i = 0; i < repeatCount; i++)
- _hoverWidget.onMouseDown (_hoverWidget, lastMouseDownEvent);
- mouseRepeatCount += repeatCount;
- }
- } else if (lastMouseDown.ElapsedMilliseconds > DeviceRepeatDelay)
- mouseRepeatTimer.Start ();
++ //if (mouseRepeatTimer.ElapsedMilliseconds > 0) {
++ // if ((bool)_hoverWidget?.MouseRepeat) {
++ // int repeatCount = (int)mouseRepeatTimer.ElapsedMilliseconds / DEVICE_REPEAT_INTERVAL - mouseRepeatCount;
++ // for (int i = 0; i < repeatCount; i++)
++ // _hoverWidget.onMouseDown (_hoverWidget, lastMouseDownEvent);
++ // mouseRepeatCount += repeatCount;
++ // }
++ //} else if (lastMouseDown.ElapsedMilliseconds > DEVICE_REPEAT_DELAY)
++ //mouseRepeatTimer.Start ();
+
if (!Monitor.TryEnter (UpdateMutex))
return;
}
#region Mouse and Keyboard Handling
- XCursor cursor = XCursor.Default;
+ MouseCursor cursor = MouseCursor.Arrow;
public MouseState Mouse;
+ Stopwatch lastMouseDown = new Stopwatch (), mouseRepeatTimer = new Stopwatch ();
++ bool doubleClickTriggered; //next mouse up will trigger a double click
+ int mouseRepeatCount;
+ MouseButtonEventArgs lastMouseDownEvent;
- public XCursor MouseCursor {
+ public MouseCursor MouseCursor {
set {
+
if (value == cursor)
return;
cursor = value;
Widget topc = null;
while (tmp is Widget) {
topc = tmp;
-- tmp = tmp.focusParent;
++ tmp = tmp.LogicalParent as Widget;
}
int idxhw = GraphicTree.IndexOf (topc);
if (idxhw != 0) {
int i = 0;
while (i < idxhw) {
-- if (!GraphicTree [i].isPopup) {
++ //if logical parent of top container is a widget, that's a popup
++ if (GraphicTree [i].LogicalParent is Interface) {
if (GraphicTree [i].MouseIsIn (e.Position)) {
while (_hoverWidget != null) {
_hoverWidget.onMouseLeave (_hoverWidget, e);
-- HoverWidget = _hoverWidget.focusParent;
++ HoverWidget = _hoverWidget.FocusParent;
}
GraphicTree [i].checkHoverWidget (e);
}
_hoverWidget.onMouseLeave (_hoverWidget, e);
//seek upward from last focused graph obj's
-- while (_hoverWidget.focusParent != null) {
-- HoverWidget = _hoverWidget.focusParent;
++ tmp = _hoverWidget.FocusParent;
++ while (tmp != null) {
++ HoverWidget = tmp;
if (_hoverWidget.MouseIsIn (e.Position)) {
_hoverWidget.checkHoverWidget (e);
- _hoverWidget.onMouseMove (this, e);
+ _hoverWidget.onMouseMove (_hoverWidget, e);
return true;
}
_hoverWidget.onMouseLeave (_hoverWidget, e);
- }
++ tmp = _hoverWidget.FocusParent;
+ }
}
//top level graphic obj's parsing
return false;
}
/// <summary>
-- /// Forward the mouse up event from the host to the crow interface
++ /// Forward the mouse down event from the host to the hover widget in the crow interface
/// </summary>
/// <returns>return true, if interface handled the event, false otherwise.</returns>
/// <param name="button">Button index</param>
-- public bool ProcessMouseButtonUp(Crow.MouseButton button)
++ public bool ProcessMouseButtonDown (MouseButton button)
{
-- Mouse.DisableBit ((int)button);
- MouseButtonEventArgs e = new MouseButtonEventArgs (button) { Mouse = Mouse };
- if (_activeWidget == null)
-
- lastMouseDown.Reset ();
- mouseRepeatTimer.Reset ();
++ Mouse.EnableBit ((int)button);
+
- MouseButtonEventArgs e = new MouseButtonEventArgs (button) { Mouse = Mouse };
- if (_activeWidget == null)
- return false;
++ doubleClickTriggered = (lastMouseDown.ElapsedMilliseconds < DOUBLECLICK_TRESHOLD);
++ lastMouseDown.Restart ();
++ mouseRepeatCount = -1;//stays negative until repeat delay is hit
+
- _activeWidget.onMouseUp (_activeWidget, e);
++ lastMouseDownEvent = new MouseButtonEventArgs (button) { Mouse = Mouse };
+
- if (armedClick != null) {
- if (lastClickTime.ElapsedMilliseconds <= DoubleClick) {
- armedClick.onMouseDoubleClick (armedClick, armedClickEventArgs);
- ActiveWidget = null;
- } else
- armedClick.onMouseClick (armedClick, armedClickEventArgs);
- armedClick = null;
- }
++ if (_hoverWidget == null)
+ return false;
- if (mouseRepeatThread != null) {
- mouseRepeatOn = false;
- mouseRepeatThread.Cancel();
- }
- if (!mouseRepeatTriggeredAtLeastOnce) {
- if (_activeWidget.MouseIsIn (e.Position))
- armeClick (_activeWidget, e);
- Widget target = _activeWidget;
- while (target != null) {
- if (target.hasDoubleClick) {
- armedClick = _activeWidget;
- armedClickEventArgs = e;
- lastClickTime.Restart ();
- break;
- }
- if (target.hasClick) {
- _activeWidget.onMouseClick (_activeWidget, e);
- break;
- }
- target = target.focusParent;
-- }
- mouseRepeatTriggeredAtLeastOnce = false;
- _activeWidget.onMouseUp (_activeWidget, e);
++ _hoverWidget.onMouseDown (_hoverWidget, lastMouseDownEvent);
- // GraphicObject lastActive = _activeWidget;
- // GraphicObject lastActive = _activeWidget;
-- ActiveWidget = null;
- // if (!lastActive.MouseIsIn (Mouse.Position)) {
- // ProcessMouseMove (Mouse.X, Mouse.Y);
- // }
- // if (!lastActive.MouseIsIn (Mouse.Position)) {
- // ProcessMouseMove (Mouse.X, Mouse.Y);
- // }
++ ActiveWidget = _hoverWidget;
return true;
}
/// <summary>
-- /// Forward the mouse down event from the host to the crow interface
++ /// Forward the mouse up event from the host to the crow interface
/// </summary>
/// <returns>return true, if interface handled the event, false otherwise.</returns>
/// <param name="button">Button index</param>
-- public bool ProcessMouseButtonDown(Crow.MouseButton button)
++ public bool ProcessMouseButtonUp(MouseButton button)
{
-- Mouse.EnableBit ((int)button);
- MouseButtonEventArgs e = new MouseButtonEventArgs (button) { Mouse = Mouse };
-
- if (_hoverWidget == null)
- return false;
- lastMouseDown.Start ();
- mouseRepeatCount = 0;
++ Mouse.DisableBit ((int)button);
- Widget hoverFocused = _hoverWidget;
- while (!hoverFocused.Focusable) {
- hoverFocused = hoverFocused.focusParent;
- if (hoverFocused == null) {
- hoverFocused = _hoverWidget;
- break;
- }
- }
- if (hoverFocused == armedClickSender) {
- if (clickTimer.ElapsedMilliseconds < Interface.DoubleClick) {
- armedClickSender.onMouseDoubleClick (armedClickSender, e);
- armedClickSender = null;
- return true;
- }
-
- }
- if (armedClickSender!=null)
- armedClickSender.onMouseClick (armedClickSender, armedClickEvtArgs);
- armedClickSender = null;
- lastMouseDownEvent = new MouseButtonEventArgs (button) { Mouse = Mouse };
++ mouseRepeatTimer.Reset ();
- _hoverWidget.onMouseDown(_hoverWidget,new BubblingMouseButtonEventArg(e));
- if (HoverWidget == null)
++ MouseButtonEventArgs e = new MouseButtonEventArgs (button) { Mouse = Mouse };
++ if (_activeWidget == null)
+ return false;
- if (_focusedWidget == null)
- return true;
- Widget hoverFocused = HoverWidget;
- while (!hoverFocused.Focusable) {
- hoverFocused = hoverFocused.focusParent;
- if (hoverFocused == null) {
- hoverFocused = HoverWidget;
- break;
- }
- }
-
- _hoverWidget.onMouseDown (_hoverWidget, lastMouseDownEvent);
++ _activeWidget.onMouseUp (_activeWidget, e);
- ActiveWidget = FocusedWidget;
- /*if (_focusedWidget == null)
- return true;*/
++ if (doubleClickTriggered)
++ _activeWidget.onMouseDoubleClick (_activeWidget, e);
++ else
++ _activeWidget.onMouseClick (_activeWidget, e);
- if (!FocusedWidget.MouseRepeat)
- return true;
- mouseRepeatThread = new CrowThread (FocusedWidget, mouseRepeatThreadFunc);
- mouseRepeatThread.Start ();
- ActiveWidget = _hoverWidget;
++ ActiveWidget = null;
++// if (!lastActive.MouseIsIn (Mouse.Position)) {
++// ProcessMouseMove (Mouse.X, Mouse.Y);
++// }
return true;
}
/// <summary>
/// Forward the mouse wheel event from the host to the crow interface
/// </summary>
/// <returns>return true, if interface handled the event, false otherwise.</returns>
-- /// <param name="button">Button index</param>
++ /// <param name="delta">wheel delta</param>
public bool ProcessMouseWheelChanged(float delta)
{
Mouse.SetScrollRelative (0, delta);
MouseWheelEventArgs e = new MouseWheelEventArgs () { Mouse = Mouse, DeltaPrecise = delta };
- if (HoverWidget == null)
+ if (_hoverWidget == null)
return false;
- _hoverWidget.onMouseWheel (this, e);
- HoverWidget.onMouseWheel (this, e);
++ _hoverWidget.onMouseWheel (_hoverWidget, e);
return true;
}
void toolTipThreadFunc ()
{
while(true) {
-- if (tooltipTimer.ElapsedMilliseconds > ToolTipDelay) {
++ if (tooltipTimer.ElapsedMilliseconds > TOOLTIP_DELAY) {
if (!tooltipVisible) {
Widget g = _hoverWidget;
while (g != null) {
else
ctxMenuContainer.IsOpened = true;
-- ctxMenuContainer.isPopup = true;
++ //ctxMenuContainer.isPopup = true;
ctxMenuContainer.LogicalParent = go;
ctxMenuContainer.DataSource = go;
void keyboardRepeatThreadFunc()
{
keyboardRepeatOn = true;
-- Thread.Sleep (Interface.DeviceRepeatDelay);
++ Thread.Sleep (Interface.DEVICE_REPEAT_DELAY);
while (keyboardRepeatOn) {
keyboardRepeatCount++;
-- Thread.Sleep (Interface.DeviceRepeatInterval);
++ Thread.Sleep (Interface.DEVICE_REPEAT_INTERVAL);
}
keyboardRepeatCount = 0;
}
<ReleaseVersion>0.8.0</ReleaseVersion>
</PropertyGroup>
++ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
++ <DefineConstants>TRACE;DEBUG;NETFRAMEWORK;NET471</DefineConstants>
++ </PropertyGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('net4'))">
<Reference Include="System" />
</ItemGroup>