Page 1 of 1

Custom cursors

Posted: 17 Dec 2013, 22:34
by Maddy123
Is there any way to incorporate custom cursors in Noesis? Thanks.

Re: Custom cursors

Posted: 18 Dec 2013, 20:38
by sfernandez
Hi,

Current version of NoesisGUI does not implement the FrameworkElement.Cursor property.
If you are very interested on this feature, please report it in our bugtracker (bugs.noesisengine.com).

But if you are working on Unity, you can set application Default Cursor in the PlayerSettings (under Edit > Project Settings > Player menu).

Re: Custom cursors

Posted: 25 Feb 2015, 17:23
by noesis_user
Does latest noesis version has cursors ?

Re: Custom cursors

Posted: 26 Feb 2015, 11:47
by sfernandez
Operating System cursors are not supported. If you need your own cursor icon I suggest to hide OS cursor and define a UI element placed on top of the main view that you can make follow mouse position:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid.Resources>
        <ImageBrush x:Key="arrowCursor" ImageSource="icons/arrow.png"/>
        <!-- ... -->
    </Grid.Resources>

    <Grid x:Name="LayoutRoot">
        <!-- ... -->
    </Grid>

    <Canvas>
        <Rectangle x:Name="cursor" Fill="{StaticResource arrowCursor}" IsHitTestVisible="False"
            Canvas.Left="0" Canvas.Top="0" Width="32" Height="32"/>
    </Canvas>
</Grid>

Re: Custom cursors

Posted: 26 Feb 2015, 17:50
by jsantos
The problem with that approach is that the cursor will refresh at the frame rate of the application. Operating System pointers normally refresh at a faster rate. Right now the best option is using native OS functions for changing the cursor.

Re: Custom cursors

Posted: 28 Feb 2015, 08:36
by noesis_user
So there is no update on cursor in 1.2 ?

Re: Custom cursors

Posted: 28 Feb 2015, 20:09
by Scherub
According to this changelog there aren't any changes related to the cursor. But you can easily change the cursor in Unity. Well, only if you use Unity of course. :)

Re: Custom cursors

Posted: 03 Mar 2015, 21:48
by noesis_user
Is there any way to know that Mouse hover/ mouse move is being caught by Noesis ?? like mousedown event.

Re: Custom cursors

Posted: 04 Mar 2015, 10:19
by sfernandez
When mouse is captured by any UIElement, all mouse events are received by that element.
You can know if an element has captured the mouse as follows:
UIElement* element; // an element of the UI tree
//...
UIElement* captured = element->GetMouse()->GetCaptured();
if (captured != 0)
{
  // mouse is captured by 'captured' element
}
else
{
  // mouse is not captured
}
Is this what you want to know?

Re: Custom cursors

Posted: 04 Mar 2015, 11:41
by ai_enabled
That's how we done automatic cursor switching in our game: (implementation utilizes attached properties, Unity3D)
	// list of cursor types
	public enum UiCursor : int
	{
		None = 0,
		Pointer = 1,
		Attack = 2,
		Speak = 3
                // you can add other types of cursors
	}

	public class CursorService : DependencyObject
	{
		#region Static Fields

		public static DependencyProperty CursorProperty = DependencyProperty.RegisterAttached(
			"Cursor",
			typeof(UiCursor),
			typeof(CursorService),
			new FrameworkPropertyMetadata(UiCursor.None, CursorAttachedHandler));

		#endregion

		#region Public Methods and Operators

		public static UiCursor GetCursor(FrameworkElement element)
		{
			return (UiCursor)element.GetValue(CursorProperty);
		}

		public static void RegisterCursor(FrameworkElement frameworkElement)
		{
			frameworkElement.MouseEnter += FrameworkElementMouseEnterHandler;
		}

		public static void SetCursor(FrameworkElement element, UiCursor value)
		{
			element.SetValue(CursorProperty, value);
		}

		#endregion

		#region Methods

		private static void CursorAttachedHandler(DependencyObject obj, DependencyPropertyChangedEventArgs e)
		{
			RegisterCursor((FrameworkElement)obj);
		}

		private static void FrameworkElementMouseEnterHandler(object sender, MouseEventArgs e)
		{
			FrameworkElement frameworkElement = (FrameworkElement)sender;
			UiCursor cursor = (UiCursor)frameworkElement.GetValue(CursorProperty);

			frameworkElement.MouseLeave += FrameworkElementMouseLeaveHandler;
			frameworkElement.Unloaded += FrameworkElementMouseUnloadedHandler;

			CursorServiceEvents.OnCursorEnter(frameworkElement, cursor);
		}

		private static void FrameworkElementMouseLeaveHandler(object sender, MouseEventArgs e)
		{
			FrameworkElement frameworkElement = (FrameworkElement)sender;
			ResetCursor(frameworkElement);
		}

		private static void FrameworkElementMouseUnloadedHandler(object sender, RoutedEventArgs arg1)
		{
			FrameworkElement frameworkElement = (FrameworkElement)sender;
			ResetCursor(frameworkElement);
		}

		private static void ResetCursor(FrameworkElement frameworkElement)
		{
			frameworkElement.MouseLeave -= FrameworkElementMouseLeaveHandler;
			frameworkElement.Unloaded -= FrameworkElementMouseUnloadedHandler;

			CursorServiceEvents.OnCursorLeave(frameworkElement);
		}

		#endregion
	}

	public static class CursorServiceEvents
	{
		#region Public Events

		public static event Action<FrameworkElement, UiCursor> CursorEnter;

		public static event Action<FrameworkElement> CursorLeave;

		#endregion

		#region Public Methods and Operators

		public static void OnCursorEnter(FrameworkElement arg1, UiCursor arg2)
		{
			Action<FrameworkElement, UiCursor> handler = CursorEnter;
			if (handler != null)
			{
				handler(arg1, arg2);
			}
		}

		public static void OnCursorLeave(FrameworkElement obj)
		{
			Action<FrameworkElement> handler = CursorLeave;
			if (handler != null)
			{
				handler(obj);
			}
		}

		#endregion
	}
So then you can subscribe on events and switch cursor when events fired: (example Cursor Manager class)
	public static class CursorManager
	{
		static CursorManager()
		{
			CursorServiceEvents.CursorEnter += this.CursorEnterHandler;
			CursorServiceEvents.CursorLeave += this.CursorLeaveHandler;
		}

		private void CursorEnterHandler(FrameworkElement frameworkElement, UiCursor cursor)
		{
			switch (cursor)
			{
				// set cursor depending on cursor type
			}
		}

		private void CursorLeaveHandler(FrameworkElement frameworkElement)
		{
 			// reset cursor to previous
		}
	}
How to use it in XAML: (pretty easy!)
<Button Content="Attack me" services:CursorService.Cursor="Attack" />
You can even define it in Style definition
<Style x:Key="ButtonAttackStyle" TargetType="{x:Type Button}">
        <Setter Property="services:CursorService.Cursor" Value="Attack" />
</Style>
So you can easily assign different cursors on your UI elements (including panels, buttons, checkboxes, everything!). You can assign specific cursor for all buttons (just set it in style).

We also implemented similar service for UI sounds, so we assign specific sounds for different controls types (buttons, tabs, sliders, checkboxes) for events like mouse enter/leave/click. We also used it for special tooltips and even for localization. Attached properties is amazing feature! Kudos to NoesisGUI team for implementing it!