mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00

Throwing error on member references with ".." cascade token outside invocations (ie: "ts..mA = 123") Fixed 'Thread.ModuleTLSIndex' error - which caused us TLS lookup failures in Beef DLLs Fixed some hotswap errors Made BeefPerf shut down properly Fixed an 'int literal' FixIntUnknown issue where rhs was System.Object which caused an illegal boxing Fixed COFF::LocateSymbol issues with Win32 and also with linking to static libraries - showed up with hot-linking in fmod when hot-adding a floating point mod Fixed a couple memory leaks Fixed alignment issue in COFF::ParseCompileUnit
772 lines
23 KiB
Beef
772 lines
23 KiB
Beef
using System;
|
||
using System.Collections.Generic;
|
||
using System.Diagnostics;
|
||
using System.Text;
|
||
using Beefy.gfx;
|
||
using Beefy.events;
|
||
using Beefy.sys;
|
||
using Beefy.geom;
|
||
|
||
namespace Beefy.widgets
|
||
{
|
||
public delegate void MouseLeftWindowHandler(BFWindow window);
|
||
public delegate void WindowLostFocusHandler(BFWindow window, BFWindow newFocus);
|
||
public delegate bool WindowCloseQueryHandler(BFWindow window);
|
||
public delegate void WindowClosedHandler(BFWindow window);
|
||
public delegate void WindowMovedHandler(BFWindow window);
|
||
public delegate void MouseWheelHandler(MouseEvent mouseEvent);
|
||
public delegate void KeyDownHandler(KeyDownEvent keyboardEvent);
|
||
//public delegate void CloseTemporaryHandler(WidgetWindow window);
|
||
|
||
public class WidgetWindow : BFWindow
|
||
{
|
||
public Event<MouseLeftWindowHandler> mOnMouseLeftWindow ~ _.Dispose();
|
||
public Event<WindowLostFocusHandler> mOnWindowLostFocus ~ _.Dispose();
|
||
public Event<MouseEventHandler> mOnMouseDown ~ _.Dispose();
|
||
public Event<WindowCloseQueryHandler> mOnWindowCloseQuery ~ _.Dispose();
|
||
public Event<WindowClosedHandler> mOnWindowClosed ~ _.Dispose();
|
||
public Event<WindowMovedHandler> mOnWindowMoved ~ _.Dispose();
|
||
public Event<MouseWheelHandler> mOnMouseWheel ~ _.Dispose();
|
||
public Event<MenuItemSelectedHandler> mOnMenuItemSelected ~ _.Dispose();
|
||
public Event<KeyDownHandler> mOnWindowKeyDown ~ _.Dispose();
|
||
public Event<Func<int32, int32, HitTestResult>> mOnHitTest ~ _.Dispose();
|
||
|
||
public static Event<MouseLeftWindowHandler> sOnMouseLeftWindow ~ _.Dispose();
|
||
public static Event<WindowLostFocusHandler> sOnWindowLostFocus ~ _.Dispose();
|
||
public static Event<MouseEventHandler> sOnMouseDown ~ _.Dispose();
|
||
public static Event<WindowClosedHandler> sOnWindowClosed ~ _.Dispose();
|
||
public static Event<WindowMovedHandler> sOnWindowMoved ~ _.Dispose();
|
||
public static Event<MouseWheelHandler> sOnMouseWheel ~ _.Dispose();
|
||
public static Event<MenuItemSelectedHandler> sOnMenuItemSelected ~ _.Dispose();
|
||
public static Event<KeyDownHandler> sOnKeyDown ~ _.Dispose();
|
||
//public Event<CloseTemporaryHandler> sOnCloseTemporaries ~ _.Dispose();
|
||
|
||
public bool mIsMainWindow;
|
||
|
||
public MouseFlag mMouseFlags;
|
||
public Widget mRootWidget;
|
||
public Widget mCaptureWidget;
|
||
public Widget mOverWidget;
|
||
public Widget mFocusWidget;
|
||
public int32 mClientMouseX;
|
||
public int32 mClientMouseY;
|
||
public float mMouseX;
|
||
public float mMouseY;
|
||
public bool mIsMouseMoving;
|
||
public bool mHasMouseInside;
|
||
public bool mHasProxyMouseInside;
|
||
public bool mIsKeyDownHandled;
|
||
|
||
public int32 mContentClientWidth;
|
||
public int32 mContentClientHeight;
|
||
|
||
public static WidgetWindow sMouseInsideWindow;
|
||
public static int32 sLastClosedTick = -1;
|
||
|
||
public Matrix mScaleMatrix = Matrix.IdentityMatrix;
|
||
public Matrix mInvScaleMatrix = Matrix.IdentityMatrix;
|
||
|
||
public bool[] mIsKeyDown = new bool[(int32)KeyCode.COUNT] ~ delete _;
|
||
|
||
public this(BFWindow parent, String title, int x, int y, int width, int height, BFWindow.Flags windowFlags, Widget rootWidget) :
|
||
//TODO: Do BFWindow init outside constructor.. see where it be hanging
|
||
base(parent, title, x, y, width, height, windowFlags)
|
||
{
|
||
if (mWindowFlags.HasFlag(Flags.ClientSized))
|
||
{
|
||
mContentClientWidth = (int32)width;
|
||
mContentClientHeight = (int32)height;
|
||
}
|
||
|
||
if (!mWindowFlags.HasFlag(BFWindowBase.Flags.NoActivate))
|
||
GotFocus();
|
||
|
||
SetRootWidget(rootWidget);
|
||
|
||
//Debug.WriteLine("WidgetWindow.this {0} {1} {2}", this, mTitle, mRootWidget);
|
||
|
||
//Debug.WriteLine("WidgetWindow this");
|
||
}
|
||
|
||
public ~this()
|
||
{
|
||
if (sMouseInsideWindow == this)
|
||
sMouseInsideWindow = null;
|
||
delete mRootWidget;
|
||
|
||
//Debug.WriteLine("WidgetWindow ~this");
|
||
}
|
||
|
||
public void SetRootWidget(Widget rootWidget)
|
||
{
|
||
if (mRootWidget != null)
|
||
mRootWidget.[Friend]RemovedFromWindow();
|
||
|
||
mRootWidget = rootWidget;
|
||
if (mRootWidget != null)
|
||
{
|
||
mRootWidget.mWidgetWindow = this;
|
||
mRootWidget.InitChildren();
|
||
mRootWidget.AddedToParent();
|
||
Moved(); // Rehup size
|
||
}
|
||
}
|
||
|
||
public KeyFlags GetKeyFlags()
|
||
{
|
||
KeyFlags keyFlags = default;
|
||
if (IsKeyDown(KeyCode.Shift))
|
||
keyFlags |= KeyFlags.Shift;
|
||
if (IsKeyDown(KeyCode.Control))
|
||
keyFlags |= KeyFlags.Ctrl;
|
||
if (IsKeyDown(KeyCode.Menu))
|
||
keyFlags |= KeyFlags.Alt;
|
||
return keyFlags;
|
||
}
|
||
|
||
public bool IsKeyDown(KeyCode keyCode)
|
||
{
|
||
return mIsKeyDown[(int32)keyCode];
|
||
}
|
||
|
||
public override void Draw(Graphics g)
|
||
{
|
||
if (mRootWidget == null)
|
||
return;
|
||
|
||
base.Draw(g);
|
||
mRootWidget.DrawAll(g);
|
||
}
|
||
|
||
public override void Update()
|
||
{
|
||
if (mOverWidget != null)
|
||
Debug.Assert(mHasMouseInside);
|
||
|
||
if (mRootWidget == null)
|
||
return;
|
||
base.Update();
|
||
RehupMouse(false);
|
||
mRootWidget.UpdateAll();
|
||
}
|
||
|
||
public override int32 CloseQuery()
|
||
{
|
||
bool hadFalse = false;
|
||
for (var handler in mOnWindowCloseQuery)
|
||
{
|
||
if (!handler(this))
|
||
{
|
||
hadFalse = true;
|
||
break;
|
||
}
|
||
}
|
||
if (hadFalse)
|
||
return 0;
|
||
|
||
return base.CloseQuery();
|
||
}
|
||
|
||
public override void Closed()
|
||
{
|
||
sLastClosedTick = BFApp.sApp.mUpdateCnt;
|
||
|
||
if (!mHasClosed)
|
||
{
|
||
//Debug.WriteLine("WidgetWindow.Closed {0} {1} {2}", this, mTitle, mRootWidget);
|
||
|
||
if (mRootWidget != null)
|
||
{
|
||
mRootWidget.[Friend]RemovedFromWindow();
|
||
mRootWidget.RemovedFromParent(null, this);
|
||
}
|
||
|
||
//Debug.WriteLine("Window closing: {0}", this);
|
||
mOnWindowClosed(this);
|
||
sOnWindowClosed(this);
|
||
base.Closed();
|
||
}
|
||
}
|
||
|
||
public override void PreDraw(Graphics g)
|
||
{
|
||
base.PreDraw(g);
|
||
|
||
g.mMatrix.Set(mScaleMatrix);
|
||
}
|
||
|
||
public override void Moved()
|
||
{
|
||
base.Moved();
|
||
|
||
if (mWindowFlags.HasFlag(Flags.ScaleContent))
|
||
{
|
||
float scaleX = mClientWidth / (float)mContentClientWidth;
|
||
float scaleY = mClientHeight / (float)mContentClientHeight;
|
||
|
||
if (scaleX > scaleY)
|
||
{
|
||
float scale = scaleY;
|
||
mScaleMatrix.a = scale;
|
||
mScaleMatrix.b = 0;
|
||
mScaleMatrix.c = 0;
|
||
mScaleMatrix.d = scale;
|
||
mScaleMatrix.tx = (int32)(mClientWidth - (scale * mContentClientWidth)) / 2;
|
||
mScaleMatrix.ty = 0;
|
||
}
|
||
else
|
||
{
|
||
float scale = scaleX;
|
||
mScaleMatrix.a = scale;
|
||
mScaleMatrix.b = 0;
|
||
mScaleMatrix.c = 0;
|
||
mScaleMatrix.d = scale;
|
||
mScaleMatrix.tx = 0;
|
||
mScaleMatrix.ty = (int32)(mClientHeight - (scale * mContentClientHeight)) / 2;
|
||
}
|
||
|
||
mInvScaleMatrix.Set(mScaleMatrix);
|
||
mInvScaleMatrix.Invert();
|
||
mRootWidget.Resize(0, 0, mContentClientWidth, mContentClientHeight);
|
||
}
|
||
else
|
||
{
|
||
mInvScaleMatrix = Matrix.IdentityMatrix;
|
||
mScaleMatrix = Matrix.IdentityMatrix;
|
||
mContentClientWidth = mClientWidth;
|
||
mContentClientHeight = mClientHeight;
|
||
mRootWidget.Resize(0, 0, mClientWidth, mClientHeight);
|
||
}
|
||
|
||
mOnWindowMoved(this);
|
||
sOnWindowMoved(this);
|
||
}
|
||
|
||
public void SetFocus(Widget widget)
|
||
{
|
||
/*if (widget != null)
|
||
Debug.WriteLine("SetFocus: {0} {1}", widget.GetType(), widget.mWidgetWindow.mTitle);*/
|
||
|
||
if (mFocusWidget == widget)
|
||
return;
|
||
|
||
Widget oldFocusWidget = mFocusWidget;
|
||
mFocusWidget = null;
|
||
if (oldFocusWidget != null)
|
||
{
|
||
Debug.Assert(oldFocusWidget.mWidgetWindow == this);
|
||
if (oldFocusWidget.mHasFocus)
|
||
oldFocusWidget.LostFocus();
|
||
else
|
||
Debug.Assert(!mHasFocus);
|
||
}
|
||
if (mFocusWidget != null)
|
||
return; // Already got a new focus after LostFocus callbacks
|
||
mFocusWidget = widget;
|
||
if ((mFocusWidget != null) && (mHasFocus))
|
||
mFocusWidget.GotFocus();
|
||
}
|
||
|
||
public override void GotFocus()
|
||
{
|
||
if (mHasFocus)
|
||
return;
|
||
mIsDirty = true;
|
||
|
||
//Debug.WriteLine("GotFocus {0}", mIsMainWindow);
|
||
|
||
for (var window in sWindowDictionary.Values)
|
||
{
|
||
// Don't let more than one window think it has the focus
|
||
var widgetWindow = window as WidgetWindow;
|
||
if ((widgetWindow != null) && (widgetWindow != this) && (widgetWindow.mHasFocus))
|
||
{
|
||
widgetWindow.LostFocus(this);
|
||
break;
|
||
}
|
||
}
|
||
|
||
//Debug.WriteLine("GotFocus {0} {1}", mTitle, mIsMainWindow);
|
||
base.GotFocus();
|
||
|
||
if (mFocusWidget != null)
|
||
{
|
||
//Debug.Assert(!mFocusWidget.mHasFocus);
|
||
if (!mFocusWidget.mHasFocus)
|
||
mFocusWidget.GotFocus();
|
||
}
|
||
}
|
||
|
||
public override void LostFocus(BFWindow newFocus)
|
||
{
|
||
//Debug.WriteLine("LostFocus {0}", mIsMainWindow);
|
||
|
||
if (!mHasFocus)
|
||
return;
|
||
|
||
|
||
mIsDirty = true;
|
||
for (int32 i = 0; i < (int32)mIsKeyDown.Count; i++)
|
||
if (mIsKeyDown[i])
|
||
KeyUp(i);
|
||
|
||
// We could have a mousedown in one window while another window has focus still<6C><6C><EFBFBD>
|
||
// So this check isn't valid.
|
||
/*for (int btnIdx = 0; btnIdx < 3; btnIdx++)
|
||
{
|
||
if (((int)mMouseFlags & (1 << btnIdx)) != 0)
|
||
{
|
||
MouseUp(mClientMouseX, mClientMouseY, btnIdx);
|
||
}
|
||
}*/
|
||
|
||
base.LostFocus(newFocus);
|
||
|
||
if (mCaptureWidget != null)
|
||
mCaptureWidget = null;
|
||
if (mFocusWidget != null)
|
||
{
|
||
Debug.Assert(mFocusWidget.mWidgetWindow == this);
|
||
var prevFocus = mFocusWidget;
|
||
prevFocus.LostFocus();
|
||
}
|
||
|
||
mOnWindowLostFocus(this, newFocus);
|
||
sOnWindowLostFocus(this, newFocus);
|
||
|
||
//Debug.Assert(!mHasFocus);
|
||
}
|
||
|
||
public override void KeyChar(char32 c)
|
||
{
|
||
var fakeFocusWindow = GetFakeFocusWindow();
|
||
if (fakeFocusWindow != null)
|
||
{
|
||
fakeFocusWindow.KeyChar(c);
|
||
return;
|
||
}
|
||
|
||
mIsDirty = true;
|
||
|
||
if ((mHasFocus) && (mFocusWidget != null) && (!mIsKeyDownHandled))
|
||
{
|
||
let keyEvent = scope KeyCharEvent();
|
||
keyEvent.mChar = c;
|
||
keyEvent.mSender = mFocusWidget;
|
||
mFocusWidget.KeyChar(keyEvent);
|
||
}
|
||
}
|
||
|
||
BFWindow GetFakeFocusWindow()
|
||
{
|
||
/*for (int windowIdx = BFApp.sApp.mWindows.Count - 1; windowIdx >= 0; windowIdx--)
|
||
{
|
||
var checkWindow = BFApp.sApp.mWindows[windowIdx];
|
||
if (checkWindow == this)
|
||
return null;
|
||
if ((checkWindow.mWindowFlags.HasFlag(.FakeFocus)) && (checkWindow.mHasFocus))
|
||
return checkWindow;
|
||
}*/
|
||
return null;
|
||
}
|
||
|
||
public override bool KeyDown(int32 keyCode, int32 isRepeat)
|
||
{
|
||
var fakeFocusWindow = GetFakeFocusWindow();
|
||
if (fakeFocusWindow != null)
|
||
return fakeFocusWindow.KeyDown(keyCode, isRepeat);
|
||
|
||
mIsDirty = true;
|
||
|
||
mIsKeyDownHandled = false;
|
||
if (keyCode < mIsKeyDown.Count)
|
||
mIsKeyDown[keyCode] = true;
|
||
|
||
KeyDownEvent e = scope KeyDownEvent();
|
||
e.mSender = this;
|
||
e.mKeyFlags = GetKeyFlags();
|
||
e.mKeyCode = (KeyCode)keyCode;
|
||
e.mIsRepeat = isRepeat != 0;
|
||
|
||
if ((sOnKeyDown.HasListeners) || (mOnWindowKeyDown.HasListeners))
|
||
{
|
||
if (sOnKeyDown.HasListeners)
|
||
sOnKeyDown(e);
|
||
if (mOnWindowKeyDown.HasListeners)
|
||
mOnWindowKeyDown(e);
|
||
}
|
||
|
||
if ((mFocusWidget != null) && (!e.mHandled))
|
||
{
|
||
e.mSender = mFocusWidget;
|
||
mFocusWidget.KeyDown(e);
|
||
}
|
||
if (e.mHandled)
|
||
mIsKeyDownHandled = true;
|
||
|
||
return e.mHandled;
|
||
}
|
||
|
||
public override void KeyUp(int32 keyCode)
|
||
{
|
||
mIsDirty = true;
|
||
|
||
if (keyCode < mIsKeyDown.Count)
|
||
mIsKeyDown[keyCode] = false;
|
||
|
||
if (mFocusWidget != null)
|
||
mFocusWidget.KeyUp((KeyCode)keyCode);
|
||
|
||
var fakeFocusWindow = GetFakeFocusWindow();
|
||
if (fakeFocusWindow != null)
|
||
fakeFocusWindow.KeyUp(keyCode);
|
||
}
|
||
|
||
public override HitTestResult HitTest(int32 x, int32 y)
|
||
{
|
||
if (mOnHitTest.HasListeners)
|
||
{
|
||
var result = mOnHitTest(x, y);
|
||
if (result != HitTestResult.NotHandled)
|
||
{
|
||
if (result != .Client)
|
||
{
|
||
if (mHasMouseInside)
|
||
MouseLeave();
|
||
}
|
||
|
||
return result;
|
||
}
|
||
}
|
||
|
||
if (mWindowFlags.HasFlag(Flags.Resizable))
|
||
{
|
||
if ((x - mX > mWindowWidth - 24) && (y - mY > mWindowHeight - 24))
|
||
return HitTestResult.BottomRight;
|
||
}
|
||
|
||
return HitTestResult.NotHandled;
|
||
}
|
||
|
||
public void RehupMouse(bool force)
|
||
{
|
||
if (!mHasMouseInside)
|
||
return;
|
||
|
||
Widget aWidget = mRootWidget.FindWidgetByCoords(mMouseX, mMouseY);
|
||
if (mCaptureWidget != null)
|
||
{
|
||
bool didSomething = false;
|
||
|
||
if (mCaptureWidget == aWidget)
|
||
{
|
||
if (!mCaptureWidget.mMouseOver)
|
||
{
|
||
mCaptureWidget.MouseEnter();
|
||
didSomething = true;
|
||
}
|
||
mOverWidget = aWidget;
|
||
}
|
||
else
|
||
{
|
||
if (mCaptureWidget.mMouseOver)
|
||
{
|
||
mCaptureWidget.MouseLeave();
|
||
didSomething = true;
|
||
}
|
||
mOverWidget = null;
|
||
}
|
||
|
||
if ((didSomething) || (force))
|
||
{
|
||
float childX;
|
||
float childY;
|
||
mCaptureWidget.RootToSelfTranslate(mMouseX, mMouseY, out childX, out childY);
|
||
mCaptureWidget.MouseMove(childX, childY);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (mOverWidget != aWidget)
|
||
{
|
||
if (mOverWidget != null)
|
||
{
|
||
mOverWidget.MouseLeave();
|
||
if (!IsMouseCaptured())
|
||
{
|
||
// Clear out mousedowns if we don't have capture anymore
|
||
for (int32 btn < 4)
|
||
{
|
||
let checkFlag = (MouseFlag)(1 << btn);
|
||
if (mMouseFlags.HasFlag(checkFlag))
|
||
{
|
||
mMouseFlags &= ~checkFlag;
|
||
float childX;
|
||
float childY;
|
||
mOverWidget.RootToSelfTranslate(mMouseX, mMouseY, out childX, out childY);
|
||
mOverWidget.MouseUp(childX, childY, btn);
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
mOverWidget = aWidget;
|
||
if (aWidget != null)
|
||
{
|
||
aWidget.MouseEnter();
|
||
}
|
||
|
||
//Debug.WriteLine("Set OverWidget {0} in {1}", mOverWidget, this);
|
||
}
|
||
else if (!force)
|
||
return;
|
||
|
||
if (aWidget != null)
|
||
{
|
||
float childX;
|
||
float childY;
|
||
aWidget.RootToSelfTranslate(mMouseX, mMouseY, out childX, out childY);
|
||
aWidget.MouseMove(childX, childY);
|
||
}
|
||
}
|
||
}
|
||
|
||
void CheckOtherMouseCaptures()
|
||
{
|
||
if (mCaptureWidget == null)
|
||
{
|
||
/*foreach (WidgetWindow window in sWindowDictionary.Values)
|
||
{
|
||
if (window.mCaptureWidget != null)
|
||
{
|
||
//int a = 0;
|
||
}
|
||
}*/
|
||
}
|
||
}
|
||
|
||
void SetMouseInside()
|
||
{
|
||
if (sMouseInsideWindow == this)
|
||
{
|
||
//Debug.WriteLine("Mouse already inside");
|
||
return;
|
||
}
|
||
|
||
//Debug.WriteLine("SetMouseInside 1 {0} prev={1}", this, sMouseInsideWindow);
|
||
var prevMouseInsideWindow = sMouseInsideWindow;
|
||
sMouseInsideWindow = null;
|
||
if (prevMouseInsideWindow != null)
|
||
prevMouseInsideWindow.MouseLeave();
|
||
if (sMouseInsideWindow != null)
|
||
{
|
||
//Debug.WriteLine("SetMouseInside {0} aborted", this);
|
||
return;
|
||
}
|
||
sMouseInsideWindow = this;
|
||
mHasMouseInside = true;
|
||
|
||
//Debug.WriteLine("SetMouseInside 2 {0}", this);
|
||
}
|
||
|
||
public override void MouseMove(int32 inX, int32 inY)
|
||
{
|
||
//Debug.WriteLine("MouseMove {0} {1},{2}", this, inX, inY);
|
||
|
||
mClientMouseX = inX;
|
||
mClientMouseY = inY;
|
||
|
||
float x;
|
||
float y;
|
||
TranslateMouseCoords(inX, inY, out x, out y);
|
||
|
||
SetMouseInside();
|
||
CheckOtherMouseCaptures();
|
||
|
||
if ((mMouseX == x) && (mMouseY == y))
|
||
{
|
||
RehupMouse(false);
|
||
return;
|
||
}
|
||
|
||
mIsMouseMoving = true;
|
||
mMouseX = x;
|
||
mMouseY = y;
|
||
RehupMouse(true);
|
||
mIsMouseMoving = false;
|
||
}
|
||
|
||
public override void MouseProxyMove(int32 x, int32 y)
|
||
{
|
||
// This is just from dragging from another so we don't acknowledge the moves directly
|
||
//SetMouseInside();
|
||
mHasProxyMouseInside = true;
|
||
mMouseX = x;
|
||
mMouseY = y;
|
||
|
||
CheckOtherMouseCaptures();
|
||
}
|
||
|
||
void TranslateMouseCoords(int32 x, int32 y, out float outX, out float outY)
|
||
{
|
||
var pt = mInvScaleMatrix.Multiply(Point(x, y));
|
||
outX = pt.x;
|
||
outY = pt.y;
|
||
}
|
||
|
||
public override void MouseDown(int32 inX, int32 inY, int32 btn, int32 btnCount)
|
||
{
|
||
mMouseFlags |= (MouseFlag)(1 << btn);
|
||
if ((!mHasFocus) && (mParent == null))
|
||
{
|
||
//INVESTIGATE: This shouldn't be required normally
|
||
// Fixes some focus issues while debugging?
|
||
GotFocus();
|
||
}
|
||
|
||
float x;
|
||
float y;
|
||
TranslateMouseCoords(inX, inY, out x, out y);
|
||
|
||
MouseMove(inX, inY);
|
||
|
||
if ((mOnMouseDown.HasListeners) || (sOnMouseDown.HasListeners))
|
||
{
|
||
MouseEvent anEvent = scope MouseEvent();
|
||
anEvent.mSender = this;
|
||
anEvent.mX = x;
|
||
anEvent.mY = y;
|
||
mOnMouseDown(anEvent);
|
||
sOnMouseDown(anEvent);
|
||
if (anEvent.mHandled)
|
||
return;
|
||
}
|
||
|
||
Widget aWidget = mCaptureWidget ?? mOverWidget;
|
||
if (aWidget != null)
|
||
{
|
||
Debug.Assert(aWidget.mWidgetWindow == this);
|
||
float childX;
|
||
float childY;
|
||
aWidget.RootToSelfTranslate(mMouseX, mMouseY, out childX, out childY);
|
||
aWidget.MouseDown(childX, childY, btn, btnCount);
|
||
}
|
||
}
|
||
|
||
public override void MouseUp(int32 inX, int32 inY, int32 btn)
|
||
{
|
||
//Debug.WriteLine("MouseUp {0} {1} {2}", mIsMainWindow, this, mMouseFlags);
|
||
|
||
if (((int32)mMouseFlags & (1 << btn)) == 0)
|
||
return;
|
||
|
||
MouseMove(inX, inY);
|
||
mMouseFlags &= (MouseFlag)(~(1 << btn));
|
||
Widget aWidget = mCaptureWidget ?? mOverWidget;
|
||
if (aWidget != null)
|
||
{
|
||
float childX;
|
||
float childY;
|
||
aWidget.RootToSelfTranslate(mMouseX, mMouseY, out childX, out childY);
|
||
aWidget.MouseUp(childX, childY, btn);
|
||
}
|
||
}
|
||
|
||
public override void MouseWheel(int32 inX, int32 inY, int32 delta)
|
||
{
|
||
float x;
|
||
float y;
|
||
TranslateMouseCoords(inX, inY, out x, out y);
|
||
|
||
MouseMove(inX, inY);
|
||
|
||
if (sOnMouseWheel.HasListeners)
|
||
{
|
||
MouseEvent anEvent = scope MouseEvent();
|
||
anEvent.mX = x;
|
||
anEvent.mY = y;
|
||
anEvent.mWheelDelta = delta;
|
||
anEvent.mSender = this;
|
||
sOnMouseWheel(anEvent);
|
||
|
||
if (anEvent.mHandled)
|
||
return;
|
||
}
|
||
|
||
if (mOnMouseWheel.HasListeners)
|
||
{
|
||
MouseEvent anEvent = scope MouseEvent();
|
||
anEvent.mX = x;
|
||
anEvent.mY = y;
|
||
anEvent.mWheelDelta = delta;
|
||
anEvent.mSender = this;
|
||
mOnMouseWheel(anEvent);
|
||
|
||
if (anEvent.mHandled)
|
||
return;
|
||
}
|
||
|
||
Widget aWidget = mOverWidget;
|
||
if (aWidget != null)
|
||
{
|
||
float childX;
|
||
float childY;
|
||
aWidget.RootToSelfTranslate(mMouseX, mMouseY, out childX, out childY);
|
||
aWidget.MouseWheel(childX, childY, delta);
|
||
}
|
||
}
|
||
|
||
public override void MouseLeave()
|
||
{
|
||
/*if (mTitle == "Tooltip")
|
||
{
|
||
NOP!();
|
||
}
|
||
|
||
Debug.WriteLine("MouseLeave {0}", this);*/
|
||
|
||
// This line breaks the ability to drag a tab outside the window. Why did we have it?
|
||
/*if (sMouseInsideWindow == this)
|
||
return;*/
|
||
|
||
//Debug.WriteLine("MouseLeave {0}", this);
|
||
|
||
if (sMouseInsideWindow == this)
|
||
{
|
||
sMouseInsideWindow = null;
|
||
}
|
||
|
||
mHasProxyMouseInside = false;
|
||
mHasMouseInside = false;
|
||
if (mOverWidget != null)
|
||
{
|
||
mOverWidget.MouseLeave();
|
||
mOverWidget = null;
|
||
}
|
||
|
||
mOnMouseLeftWindow(this);
|
||
sOnMouseLeftWindow(this);
|
||
}
|
||
|
||
public override void MenuItemSelected(SysMenu sysMenu)
|
||
{
|
||
mOnMenuItemSelected(sysMenu);
|
||
sOnMenuItemSelected(sysMenu);
|
||
base.MenuItemSelected(sysMenu);
|
||
}
|
||
|
||
public void TransferMouse(WidgetWindow newMouseWindow)
|
||
{
|
||
if (mWindowFlags.HasFlag(.FakeFocus))
|
||
return;
|
||
|
||
if (mMouseFlags == default)
|
||
return;
|
||
|
||
newMouseWindow.mMouseFlags = mMouseFlags;
|
||
newMouseWindow.CaptureMouse();
|
||
mMouseFlags = default;
|
||
}
|
||
}
|
||
}
|