arrow-left

All pages
gitbookPowered by GitBook
1 of 40

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

TransformationMatrix

hashtag
Introduction

The Cursor's TransformationMatrix value provides additional control for transforming the screen's coordinates as reported by the mouse to screen and world coordinates used by the game. This property defaults to the identity matrix and is typically used if your game renders to a RenderTarget which is being scaled up, such as for pixel perfect 2D games.

hashtag
Code Example - Setting the Transformation Matrix

Typically the TransformationMatrix is only set if you need to scale or offset your cursor for games which use render targets. For example, if a game is rendering to a render target with resolution of 480x360, but is being rendered at 300% zoom with render targets, then the following code would be used to scale down the larger resolution to the 480x360 resolution:

This code is not necessary if you are performing zoom through the FlatRedBall editor, since that automatically handles Cursor position scaling and offset - it is only necessary if you intend to perform additional screen scaling and offsets outside of the built-in code generation.

Cursor.Main.TransformationMatrix = Matrix.CreateScale(1 / 3f, 1 / 3f, 1);

IsOn

hashtag
Introduction

IsOn returns whether the calling Cursor is over a given object. This function will not behave properly if the Camera is not viewing down the Z axis (default). If you have a rotated Camera, then you should use IsOn3D. This function does a position check - it does not consider if anything is covering the argument, or if the Cursor is over any other UI component. For more information on checking of the Cursor is over UI (as a test before performing IsOn checks), see the WindowOverarrow-up-right page.

hashtag
IsOn(Layer)

The IsOn overload which takes a Layer will check if the Cursor is over the argument Layer in screen coordinates. In other words, this function will behave properly even if the Camera is rotated. This function will simply do a check of the Cursor's screen position against the bounds of the Layer. If a Layer occupies the full screen, then this function will return true.

ClickNoSlideThreshold

The ClickNoSlideThreshold value is measured in pixels which determines if a releasing the mouse or touch screen should be treated as a ClickNoSlide. If the distance moved since the last push is less than ClickNoSlideThreshold, then the PrimaryClickNoSlide property is true for that frame. Otherwise, only the Click property is true.

If this value is increased, then the Cursor reports clicks even if the user has moved the cursor slightly since pushing the cursor (or touching the screen). If this value is reduced, then clicks will not register as often if the cursor has moved slightly since touch. This value primarily exists to help distinguish between actual push/release vs. push+slide. Since this value is in pixels it may need to be increased for high-resolution touch screens.

Gui

ReceiveInput

The ReceiveInput function is called every frame by the FlatRedBall Engine on the current IInputReceiverarrow-up-right. This function can be used by objects implementing the IIputReceiver interface to handle input and to clear it after processing it.

ReceiveInput is ultimately called when the Keyboard's state is updated inside the FlatRedBall Engine. This means that this method is called *before* any Screen or Entity activity if using Glue. If not using Glue, and if all of your custom code is written *after* FlatRedBallServices.Update (which is called in your Game class) then the ReceiveInput will also be called before any of your custom code. This is useful because it allows the current IInputReceiverarrow-up-right to receive and clear input before any other custom game logic is performed. In other words, no game code will need to be modified to prevent double-input from happening if the IInputReceiver calls the Keyboard's Clear functionarrow-up-right after processing input.

IngnoreInputThisFrame

The IgnoreInputThisFrame will result in input values being ignored for the remainder of this frame. This can be used if two independent systems rely on cursor input (such as a click) and clicks (or other input) should be ignored for all objects if one responds to it.

SortZAndLayerBased

hashtag
Introduction

The SortZAndLayerBased function is a function which can be called to sort the GuiManager's Windowsarrow-up-right by their Z value and Layer membership. Layers take first priority, then IWindows which are on the same Layer will be sorted by their Z. The higher the Z value of an IWindow, or the further in-front a Layer is, the later in the list the IWindow will appear.

hashtag
Code Example

The following can be called to update the order:

IsInWindow

hashtag
Introduction

The IsInWindow method can be used to tell if the Cursor is actually inside the game window. Using this can prevent clicks from being registered when the cursor is outside of the window.

hashtag
Code Example

The following example shows how to detect clicks that fall only inside of the game window:

RemoveWindow

hashtag
Introduction

The RemoveWindow method can be used to remove a Window from the GuiManager. The pattern for addition and removal for the GuiManager matches the other managers. In other words, you call AddWindow to add a Window to the GuiManager, and RemoveWindow to remove it.

hashtag
Code Example

Windows are added to the GuiManager through the AddWindow method:

Windows can be removed from the GuiManager through the RemoveWindow method:

WorldPosition

hashtag
Introduction

WorldPosition returns a Vector2 of the cursor's world position (as opposed to screen position). WorldPosition can be used to place objects or perform manual detection of whether the cursor is over an object.

hashtag
Code Example - Moving an Object to the Cursor WorldPosition

The following code moves an object according to the cursor's position. Note that the ToVector3 extension method is used to convert a Vector2 to a Vector3

CallClick

hashtag
Introduction

The CallClick method forces the implementing IWindow to raise its Click event. This can be used to test clicking events or to allow other input or logic to simulate a button click.

hashtag
Code Example

The following calls click when the space bar is pressed.

GetRay

hashtag
Introduction

The GetRay method can be used to get a Ray representing objects which the Cursor is over. This Ray can be used for complex object picking, and will work even when the Camera is rotated, unlike the and methods.

hashtag

CustomUpdate

hashtag
Introduction

The CustomUpdate delegate allows for customizing the Cursor's behavior. Specifically this allows setting the Cursor's position and primary/secondary/middle values.

hashtag

WorldX

hashtag
Introduction

The WorldX property returns the X coordinate of the cursor in world units (impacted by zooming and camera position). WorldX is typically used on 2D games, or 3D games where the Z=0 plane contains the entities. For 3D games, see the .

hashtag

Camera

hashtag
Introduction

Every Cursor in FlatRedBall belongs to a specific . Since multiple Cameras can exist at a given time, Cursors must know which Camera to use to convert screen space to world space for collision against game objects including UI.

By default the Cursor which can be accessed through GuiManager.Cursor uses the default Camera which FlatRedBall creates for you (which can be accessed through SpriteManager.Camera).

PrimaryClick

hashtag
Introduction

The PrimaryClick property returns whether the Cursor has been clicked this frame. A click is defined as:

  • was true last frame and...

IWindow

hashtag
Introduction

The IWindow interface is an interface that enables objects to be added to the GuiManager. Once an object is added to the GuiManager it will automatically be tested for Cursor events. The IWindow interface can be used to simplify the implementation of buttons, check boxes, and any other types of UI elements which may need to interact with the cursor.

hashtag

BringsClickedWindowsToFront

hashtag
Introduction

The BringsClickedWindowsToFront property controls whether the GuiManager brings any clicked Window to the front of its internal list. The internal GuiManager list does not control rendering, just the order that clicks are tested. Windows at the front of the list are prioritized regarding Cursor input. This is desired behavior if the GuiManager controls the rendering order of these windows (as is the case with the default FRB GUI found in the FRB tools) but it is not desirable behavior if the GuiManager does not control the rendering order (as is the case for Entities implementing .

In summary:

XForUi

hashtag
Introduction

The XForUI and YForUI members provide a coordinate system that can be used to interact with the default FlatRedBall GUI. There are a few things to keep in mind with the UI:

  • The values reported by XForUI and YForUI are rarely needed. Most interaction with the default FRB UI can be done through events and properties.

SecondaryClick

hashtag
Introduction

SecondaryClick determines whether the secondary button (right mouse button on a mouse) was pushed last frame but released this frame.

hashtag

SetJoystickControl

hashtag

This is obsolete. See

PrimaryPushTime

hashtag
Introduction

The PrimaryPushTime property returns the amount of time since the Cursor's PrimaryPush was last set to true. This value will return 0 if the PrimaryPush was just set, or if the Cursor's PrimaryDown is false. Otherwise, this value will be greater than 0. This value can be used to detect how long the mouse button has been pressed or the touch screen touched.

IClickable

hashtag
Introduction

The IClickable interface requires implementation to specify a HasCursorOver method, which is typically used for clicking or grabbing an object. Since the IClickable interface works with the Cursor object, it can be used with a physical mouse, touch screen, or any other input device which maps to the Cursor object. Although GUI elements are the most common type of IClickables, other objects such as clickable elements can implement IClickable. Examples include board pieces in a match-three game or units in a real time strategy game. IClickable is a base interface for . IWindow extends IClickable by adding input-based events.

IWindow and Glue

Although IWindow can be implemented manually in code, the IWindow interface is most typically implemented by Glue in generated code. For more information on IWindow in Glue, see this pagearrow-up-right.

https://flatredball.com/documentation/api/flatredball/flatredball-gui/flatredball-gui-cursor/setcontrollinggamepad/
hashtag
IClickable Entities

Glue entities can be marked as IClickable, which results in Glue generating IClickable-implementing code. For more information, see the Entity IClickable page.

IWindowarrow-up-right

PrimaryClickNoSlide

The PrimaryClickNoSlide property returns whether the Cursor has clicked (the primary button was down last frame, not this frame) and if the cursor has not moved more than ClickNoSlideThresholdarrow-up-right during the time the button was down. This property is often used on touch screens so that the game can differentiate between when the user intended to touch and release a UI element versus when a slide-release was performed.

GamepadsForUiControl

The GamePadsForUiControl list specifies which game pads can be used to control FlatRedBall.Forms controls. By default this list is empty, but it can be populated with gamepads to enable navigation and selection of UI with the DPad, AnalogSticks, and Buttons. For more information see the Forms and Xbox360Gamepad page.

GuiManager.SortZAndLayerBased();
Cursor cursor = GuiManager.Cursor;
if(cursor.PrimaryClick && cursor.IsInGameWindow())
{
   // do something to respond to the click
}
Button button = new Button(GuiManager.Cursor);
GuiManager.AddWindow(button);
GuiManager.RemoveWindow(button);
circle.Position = GuiManager.Cursor.WorldPosition.ToVector3();
bool wasSpacePushed = InputManager.Keyboard.KeyPushed(Keys.Space);

if(wasKeyPushed)
{
   WindowInstance.CallClick();
}
When is CustomUpdate used?

CustomUpdate is used if you would like to use the FRB Cursor class, but would like to provide custom input logic. The most common scenario for this is when using input devices which are not natively supported by FRB. For example, the Cursor could be used with the Wii's Remote hardware (which can be paired with a computer through bluetooth).

hashtag
CustomUpdate replaces regular update logic

If a non-null CustomUpdate delegate is specified then the regular input logic for the Cursor no longer applies. In other words, the Cursor no longer responds to Mouse input if CustomUpdate is used.

hashtag
Code Example

The following code shows how to control the cursor with the keyboard.

hashtag
Changing Camera

The Cursor's Camera property can be changed. To do this simply set the Camera property to the desired Camera instance:

hashtag
Where is the Camera property used?

The Cursor uses the Camera property internally when performing checks. Methods which use the Camera include:

  • FlatRedBall.Gui.Cursor.GetRay

  • FlatRedBall.Gui.Cursor.IsOn3D

The Camera property can be changed at any point, and it can be changed multiple times per frame if the Cursor is going to be used to check for whether it is over objects on multiple Cameras.

Camera
myCursor.Camera = someCameraInstance;
  • If using default FlatRedBall Gui for a tool or debugging, leave BringsClickedWindowsToFront to its default BringsClickedWindowsToFront value.

  • If using Gluearrow-up-right IWindow Entities, you should set BringsClickedWindowsToFront to false and control ordering through the BringToFrontarrow-up-right method)

  • hashtag
    Usage

    Gluearrow-up-right
    IWindowarrow-up-right

    The default FlatRedBall UI is not intended to be used in final games. It is not cross-platform, not skinnable, and lacks flexibility in areas that a full game may need. Instead, we recommend using Gluearrow-up-right and creating a custom UI.

  • The FlatRedBall UI was written in the very early days of FlatRedBall; therefore, the interface is not as clear as we would like to see it. Due to its rare use in shipped games and the amount of legacy code in the FRBDK, the interface has gone mostly unchanged for a long time.

  • hashtag
    Usage example

    The following code shows how to create a Windowarrow-up-right and have it move with the Cursor: Add the following using statement:

    Add the following at class scope:

    Add the following in Initialize after initializing FlatRedBall:

    Add the following to Update:

    The XForUI and YForUI properties return a coordinate system which is centered at the center of the screen with positive Y pointing up. The GUI coordinate system is centered at the top left with positive Y pointing down. The modifications using GuiManager.XEdge and YEdge are necessary to convert the Cursor's GUI coordinates to the FRB Gui's coordinate system. This confusing requirement is a result of very old FlatRedBall code which cannot be changed for legacy reasons.

    Code Example - Detecting Click on a UI Element

    The SecondaryClick property can be used to detect whether a UI element, such as a Gum GraphicalUiElement, was clicked with the right mouse button.

    // This would be checked every frame, such as in a screen's CustomActivity
    var cursor = GuiManager.Cursor;
    if(cursor.SecondaryClick && cursor.WindowOver == GumScreen.SomeGumObject)
    {
        // The gum object was right-clicked, so perform some action
    }
    hashtag
    Code Example
    FlatRedBall.Gui.Cursorarrow-up-right
    if(Cursor.PrimaryPushTime > 1)
    {
      // The cursor's primary state has been on for longer than 1 second
    }
    // In CustomInitialize or your Game's Initialize:
    GuiManager.Cursor.CustomUpdate = HandleCursorUpdate;
    
    // Then define HandleCursorUpdate:
    void HandleCursorUpdate(Cursor cursor)
    {
        Keyboard keyboard = InputManager.Keyboard;
    
        if (keyboard.KeyDown(Keys.Up))
        {
            cursor.ScreenY--;
        }
        if (keyboard.KeyDown(Keys.Down))
        {
            cursor.ScreenY++;
        }
        if (keyboard.KeyDown(Keys.Right))
        {
            cursor.ScreenX++;
        }
        if (keyboard.KeyDown(Keys.Left))
        {
            cursor.ScreenX--;
        }
    
        if (keyboard.KeyDown(Keys.Space))
        {
            cursor.PrimaryDown = true;
        }
    }
    // If using Glue and IWindow:
    FlatRedBall.Gui.GuiManager.BringsClickedWindowsToFront = false;
    using FlatRedBall.Gui;
    Window window;
    window = GuiManager.AddWindow();
     Cursor cursor = GuiManager.Cursor;
     window.X = cursor.XForUI + GuiManager.XEdge;
     window.Y = GuiManager.YEdge - cursor.YForUI;
    Code Example

    The following code shows how the GetRay function can be used to get a Ray representing the Cursor's current position and direction of the camera. The following code is implemented in the CustomInitialize and CustomActivity of an otherwise empty screen.

    GetRay.png

    hashtag
    Community Code

    Mouse world coordinates for a rotated Camera by Scott Dancerarrow-up-right

    WorldXAtarrow-up-right
    WorldYAtarrow-up-right
    Code Example - Moving an Entity with the Cursor

    The following code shows how to move an entity instance with the cursor.

    hashtag
    Code Example - Moving an Entity towards the Cursor

    The following code shows how to move an entity instance towards the cursor.

    WorldXAt method
    // This example assumes a Screen which contains PlayerInstance
    void CustomActivity(bool firstTimeCalled)
    {
      var cursor = GuiManager.Cursor;
      PlayerInstance.X = cursor.WorldX;
      PlayerInstance.Y = cursor.WorldY;
    }

    PrimaryDown is false this frame

    This occurs if the user pushes and releases the left moue button or touches and lifts on the touch screen. If developing games which may use a touch screen, you should consider PrimaryClickNoSlidearrow-up-right to differentiate between when the user touches and releases in the same spot vs. when the user touches, slides, then releases.

    hashtag
    Example

    The cursor can be checked to see if a click occurred in any CustomActivity code. The following code creates a Circle wherever the user clicks:

    Creating circles by clicking the cursor primary button
    PrimaryDownarrow-up-right
    if(GuiManager.Cursor.PrimaryClick)
    {
        var circle = new Circle();
        circle.Visible = true;
        circle.X = GuiManager.Cursor.WorldXAt(0);
        circle.Y = GuiManager.Cursor.WorldYAt(0);
    }

    AddDominantWindow

    hashtag
    Introduction

    Dominant Windows are IWindows which have higher priority over regular IWindows. If the GuiManager contains any dominant IWindows then any non-dominant IWindows will not receive any input from the Cursor. Dominant IWindows are a good way to prevent the user from interacting with regular (non-dominant) IWindows when UI such as a pause screen or exit confirmation screen is visible. Multiple IWindows can be marked as dominant windows using AddDominantWindow. AddDominantWindow can be called on a regular IWindow to convert it to a dominant window. Dominant windows can be converted back to non-dominant windows using the MakeRegularWindow method.

    hashtag
    Example - AddDominantWindow, FlatRedBall Forms, and Gum

    This example shows how to use AddDominantWindow to change whether a popup is the dominant window in response to UI events. This example uses a Gum screen with two objects - UserControlInstance and PopupInstance as shown in the following treeview:

    Visually, the layout is shown in the following image:

    The hiding and showing of the popup is controlled as shown in the following code:

    SetControllingGamepad

    hashtag
    Introduction

    The FlatRedBall Cursor object uses mouse or touch screen input by default. This default behavior can be changed with the SetControllingGamepad method, which switches a Cursor to be used by an Xbox360GamePad instance. When using an Xbox360GamePad for cursor control, the following input is applied:

    • Cursor position is controlled by the left analog stick and d-pad. Position is kept inside of the screen automatically.

    • The primary action (usually left mouse button) is controlled by the A button

    • The secondary action (usually the right mouse button) is controlled by the X button

    • Scrolling is controlled by the right analog stick’s Y (vertical) position

    When using an Xbox360GamePad, the native (Windows) cursor will not move in response to gamepad controls, so a visual representation must be manually added.

    hashtag
    Code Example - Using an Xbox360GamePad to Control the Cursor

    The following code assumes a Circle has been added to the current Screen:

    Windows

    hashtag
    Introduction

    The Windows IEnumerable contains all regular (non-dominant) windows in the GuiManager. By default IWindow-implementing Entities created in Glue will add themselves to the GuiManager and appear in this list. The order of IWindows in this list determines the order in which the Cursor performs UI checks.

    hashtag
    FlatRedBall Forms

    By default, FlatRedBall.Forms objects created through Gum screens add themselves to the GuiManager and appear in this list. Note that the GuiManager does not hold a direct reference to the FlatRedBall.Forms objects, but rather the Visual for each of the forms. Furthermore, only the top-level objects are added to the GuiManager. Therefore, if a StackLayout instance contains multiple buttons, only the StackLayout's Visual will appear in the Window list. For example, the following image shows a Gum screen with four buttons. Since all of the buttons are not contained by any other Forms objects, all four will appear in the Windows list.

    WorldXAt

    hashtag
    Introduction

    The WorldXAt and WorldYAt methods are useful for finding the position of the Cursor at a given Z value. These methods should generally be used only when dealing with an unrotated . For more information on limitations see below. If you are dealing with a (the default) then you can use a Z value of 0 in the WorldXAt and WorldYAt functions.

    WidowPushed

    hashtag
    Introduction

    The WindowPushed property returns the IWindow that the Cursor was over when a push last occurred. This property will remain valid while the cursor is down, and will continue to remain valid the frame when the cursor is clicked (released). After the frame where a click has occurred, the property is returned to null until the next push. WindowPushed is often used to push+drag off of a UI element.

    WindowOver

    hashtag
    Introduction

    The WindowOver returns the Window (or any object inheriting from Window such as Button, TextBox, etc.) that the Cursor is currently over. This will return the top-most window, so if the Cursor is over a Button which is contained inside a Window, the WindowOver property will contain a reference to the Button.

    Speicifcally WindowOver considers:

    MakeRegularWindow

    The MakeRegularWindow function can be used to convert an IWindow which has been made a dominant window through no longer act dominant and make it instead a regular window.

    BringToFront

    hashtag
    Introduction

    The GuiManager keeps track of the order of IWindows that it is storing. For default-drawn Windows, this ordering is reflected in the draw order. However, for Entities, the ordering of the Entities in the GuiManager may not match the ordering that the Entities are drawn. The order of IWindow Entities only matters if Entities overlap. In this case, you will need to manually control the order of Entities by using BringToFront. The GuiManager will also automatically bring clicked windows to the front. This is desirable when using default-drawn Windows, but usually not desirable when working with Entities. Therefore, if you are using IWindow Entities in you will want to set the property to false in your game's initialization.

    Enabled

    The Enabled property determines whether a UI element will react to input events, such as being clicked. IWindow instances which have their Enabled value set to false will be skipped over by the Cursor when performing UI checks; these instances will never be assigned to the property.

    void CustomInitialize()
    {
        // Add a circle for reference:
        Circle circle = ShapeManager.AddCircle();
        circle.Radius = 64;
    
        // so we can see the cursor:
        FlatRedBallServices.Game.IsMouseVisible = true;
    }
    
    void CustomActivity(bool firstTimeCalled)
    {
        var ray = GuiManager.Cursor.GetRay();
    
        FlatRedBall.Debugging.Debugger.Write(
            "Ray Position: " + ray.Position + "\n" +
            "Ray Direction: " + ray.Direction);
    
        // let's move the camera around too to make sure this works:
        const float velocity = 50;
        InputManager.Keyboard.ControlPositionedObject(Camera.Main, velocity);
    
    }
    var cursor = FlatRedBall.Gui.GuiManager.Cursor;
    
    if(cursor.PrimaryDown)
    {
        var cursorPosition = new Vector3(cursor.WorldX, cursor.WorldY, 0);
        var directionToPlayer = cursorPosition - PlayerInstance.Position;
        var normalized = directionToPlayer.NormalizedOrZero();
        float movementVelocity = 60;
    
        PlayerInstance.Velocity = normalized * movementVelocity;
    }
    else
    {
        PlayerInstance.Velocity = Vector3.Zero;
    }
    AddDominantWindowarrow-up-right
    Cursor.WindowOverarrow-up-right
    Gum objects
  • FlatRedBall.Forms objects (since they use Gum as their visuals)

  • Any Entity or code-only object which inherits from IWindow and has been added to the GuiManager.

  • hashtag
    Code Example

    The following code performs "ClickLogic" when the user performs a primary click (left click on the mouse or a release on a touch screen) if the Cursor is not over any window. This is a common way to check if the cursor is over any UI.

    hashtag
    Using WindowOver to debug GUI problems

    One very common bug is related to having multiple IWindows overlapping. In this case events may not be raising even though it appears they should be graphically. You can use the Cursor's WindowOver property in combination with the FlatRedBall.Debugging.Debugger to help identify the problem:

    If the wrong window is being returned by WindowOver, you can diagnose/correct this by doing the following:

    1. Verify that the two IWindows have different Z values if they are on the same layer or verify that the desired IWindows are on separate Layers

    2. Call GuiManager.SortZAndLayerBased() to sort the IWindows in the GuiManager so that tests are performed in the right order.

    3. See if the Window you are expecting to be over has its Enabled property set to true.

    hashtag
    Gum and WindowOver

    All Gum objects implement the IWindow interface, so all are (at least by interface) eligible for Cursor interaction. However, not all Gum objects will interact with the cursor. For more information, see the Events on Gum Objects tutorial.

    hashtag
    Gluearrow-up-right Entity example

    If you have IWindow Entities which are overlapping, you will want to control the order of your Entities using the BringToFront method. For example, consider an Entity called ButtonFrame which contains three Buttons. To bring the three Buttons to the front so that they are clickable, you might want to add the following code:

    Gluearrow-up-right
    Gluearrow-up-right
    GuiManager's BringsClickedWindowsToFrontarrow-up-right
    private void CustomInitialize()
    {
       BringButtonsToFront();
    }
    private void BringButtonsToFront()
    {
       GuiManager.BringToFront(ButtonInstance1);
       GuiManager.BringToFront(ButtonInstance2);
       GuiManager.BringToFront(ButtonInstance3);
    }
    void CustomInitialize()
    {
        GumScreen.PopupInstance.Visible = false;
    
        Forms.ClosePopupButton.Click += (not, used) =>
        {
            GumScreen.PopupInstance.Visible = false;
            FlatRedBall.Gui.GuiManager.MakeRegularWindow(GumScreen.PopupInstance);
        };
    
        Forms.ShowPopupButton.Click += (not, used) =>
        {
            GumScreen.PopupInstance.Visible = true;
            FlatRedBall.Gui.GuiManager.AddDominantWindow(GumScreen.PopupInstance);
        };
        
    }
    void CustomInitialize()
    {
        var cursor = GuiManager.Cursor;
        cursor.SetControllingGamepad(InputManager.Xbox360GamePads.First(item => item.IsConnected));
    }
    
    void CustomActivity(bool firstTimeCalled)
    {
        var worldPosition = GuiManager.Cursor.WorldPosition.ToVector3();
        FlatRedBall.Debugging.Debugger.Write(worldPosition);
        CircleInstance.Position = worldPosition;
    }
    Cursor cursor = GuiManager.Cursor;
    if(cursor.PrimaryClick && cursor.WindowOver == null)
    {
        ClickLogic();
    }
     FlatRedBall.Debugging.Debugger.Write( GuiManager.Cursor.WindowOver );
    hashtag
    Code Example

    The following code creates a Circlearrow-up-right which moves with the Cursor.

    Add the following using statements:

    Add the following at class scope:

    Add the following to Initialize after initializing FlatRedBall:

    Add the following to Update:

    CursorWorldXAt.png

    hashtag
    Additional Arguments

    The WorldXAt and WorldYAt methods can also be passed Cameras and Layers if the default is not being used. Most commonly when working with HUD in Glue, you may add the HUD element to a 2D Layer, and this 2D Layer may have a settings that differ from your default Camera. In this case, you should use these available overrides. Specifically, if you are working in an Entity, you can use the following:

    hashtag
    Using custom Cursor graphics

    The WorldXAt and WorldYAt methods can be combined with Sprites and Layers to create a custom cursor. The following code shows how to create a custom cursor using the redball.bmp graphic. This code assumes a 2D coordinate system. You will need to adjust the Sprite size appropriately if using 3D coordinates instead:

    Add the following at class scope:

    Add the following to your game or Screen's Initialize/CustomInitialize:

    Add the following to your game or Screen's Update/CustomActivity:

    hashtag
    Method Limitations

    The WorldXAt and WorldYAt methods may giave unexpected results if the Camera is rotated. These methods should only be used when the Camera is facing down the Z axis (default orientation). For a rotated Cameraarrow-up-right, the Cursor's GetRayarrow-up-right method should be used. If interested in object picking, you can use the Cursor's IsOn3D methodarrow-up-right or the IClickablearrow-up-right or IWindowarrow-up-right interfaces for Entities in Glue.

    Cameraarrow-up-right
    2D Cameraarrow-up-right
    hashtag
    Code Example

    The following code example shows how to create Circle and AxisAlignedRectangle instances by push+dragging off of two IWindows. These can be Glue entities implementing IWindow, Gum components, or hand-written IWindow-implementing objects. The following code assumes that the screen contains two IWindow-implementing objects:

    1. RectangleButton

    2. CircleButton

    Note that this code creates circles and rectangles, but does not add them to any list. In a real game these shapes would need to be added to some list (probably a list created in Glue for the screen) so that they would get properly disposed when the screen is destroyed. This additional code has been omitted for this sample.

    Cursor

    hashtag
    Introduction

    The Cursor class represents the moving cursor (on desktop) or the touch screen (on touch screens). The Cursor class is similar to the Mouse class in its interface, but provides a few additional features:

    • The Cursor is a more abstract class supporting a variety of input sources such as Mouse, Xbox360Gamepad, and TouchScreen

    • The Cursor works very well with the Window class and IWindow interface. The cursor is automatically used with Gum and FlatRedBall.Forms objects

    We recommend using the Cursor class unless you specifically need to inspect the Mouse hardware.

    hashtag
    Cursor and touch screens

    The Cursor can handle both mouse and touch screen input. Many games can use the exact same Cursor class whether written for the mouse or touch screen. Games needing more control over touch screen input can use the class.

    hashtag
    Accessing the Cursor

    The Cursor class can be accessed through the Cursor property as follows:

    hashtag
    "Primary" properties

    The Cursor is a general-purpose class for handling cross-platform input. It can represent a mouse, touch screen, or visible cursor controlled by the Xbox 360 Gamepad.

    hashtag
    Cursor visibility

    By default the cursor is invisible when moving over a FlatRedBall game. The following code makes the cursor visible when over the game window:

    hashtag
    Code Example - Detecting PrimaryPush

    The following code creates a Circle wherever the Cursor is pushed:

    IInputReceiver

    hashtag
    Introduction

    The IInputReceiver interface provides methods and properties common to all UI elements which can receive input from devices such as the Keyboard or Xbox360GamePads. Any object which implements the IInputReceiver can be assigned to the InputManager's InputReceiver.

    Only one instance can be assigned as the InputManager.InputReceiver property. If assigned, this instance has a number of methods called upon being assigned as well as in response to input. Its OnFocusUpdate is also called every frame automatically.

    hashtag
    OnFocusUpdate and FlatRedBall.Forms

    FlatRedBall.Forms elements typically receive input in one of two ways:

    1. In response to Cursor clicks. These events are ultimately raised by the underlying Gum objects (GraphicalUiElement)

    2. In response to changes in a keyboard state or Xbox360GamePad which is polled every-frame.

    Forms elements which need to poll input every frame should do so by implementing IInputReceiver and checking input in the OnFocusUpdate.

    For example, the following code could be used to perform custom actions whenever the A button is pressed on a Forms control which implements IInputReceiver:

    For a full example of implementation, see the ListBox implementation:

    hashtag
    Preventing multiple objects from receiving input

    The IInputReceiver interface is designed to prevent multiple objects from receiving input. The most common way to do this is to have the IInputReceiver process input in its ReceiveInput method, then clear the input. For example, the following code can be used to move an object and clear the input.

    This method is especially effective because ReceiveInput is called prior to the game's activity. For more information, see .

    hashtag
    TakingInput

    IInputReceivers automatically receive input from the keyboard when they have focus. To prevent this from occurring the TakingInput property can be set to false:

    WorldYAt

    hashtag
    Introduction

    The WorldXAt and WorldYAt methods are useful for finding the absolute world position of the Cursor at a given Z value. These methods should generally be used only when dealing with an unrotated . For more information on limitations see below. If you are dealing with a (the default) then you can use a Z value of 0 in the WorldXAt and WorldYAt functions.

    IsOn3d

    hashtag
    Introduction

    The IsOn3D method is a very powerful method that can be used to test if the cursor is over an object. IsOn3D is used by generated code to test if the Cursor is over an Entity if the Entity implements IClickable or IWindow. The IsOn3D method is very powerful and flexible. It considers:

    using FlatRedBall.Gui;
    using FlatRedBall.Math.Geometry;
    Circle circle;
     FlatRedBallServices.Game.IsMouseVisible = true;
     circle = ShapeManager.AddCircle();
    circle.X = GuiManager.Cursor.WorldXAt(0);
    circle.Y = GuiManager.Cursor.WorldYAt(0);
    // This represents the Entity assuming this code is in the custom methods of an Entity
    float worldX = GuiManager.Cursor.WorldXAt(this.Z, this.LayerProvidedByContainer);
    float worldY = GuiManager.Cursor.WorldYAt(this.Z, this.LayerProvidedByContainer);
    Sprite mCursorSprite;
    // Hide the cursor so that only our Sprite is invisible:
    FlatRedBallServices.Game.IsMouseVisible = false;
    // Make the layer 2D
    SpriteManager.TopLayer.UsePixelCoordinates();
    // Create the Sprite that will be used for the cursor
    mCursorSprite = SpriteManager.AddSprite("redball.bmp");
    // Add it to the TopLayer so it's always drawn on top of everything else
    SpriteManager.AddToLayer(mCursorSprite, SpriteManager.TopLayer);
    // Scale it so it's 2D.  This will be different if using a 3D camera
    mCursorSprite.PixelSize = .5f;
    Cursor cursor = GuiManager.Cursor;
    // Make sure to use the TopLayer when calling GetWorldXAt and GetWorldYAt
    mCursorSprite.X = cursor.WorldXAt(0, SpriteManager.TopLayer);
    mCursorSprite.Y = cursor.WorldYAt(0, SpriteManager.TopLayer);
    void CustomInitialize()
    {
        FlatRedBallServices.Game.IsMouseVisible = true;
    }
    
    void CustomActivity(bool firstTimeCalled)
    {
        var cursor = GuiManager.Cursor;
        
        // This code is not necessary, but displays the WindowPushed in real time, which
        // can help with debugging.
        FlatRedBall.Debugging.Debugger.Write(cursor.WindowPushed);
    
        if(cursor.PrimaryClick)
        {
            float worldX = cursor.WorldXAt(0);
            float worldY = cursor.WorldYAt(0);
    
            if(cursor.WindowPushed == RectangleButton)
            {
                var rectangle = new AxisAlignedRectangle();
                rectangle.X = worldX;
                rectangle.Y = worldY;
                rectangle.Width = 32;
                rectangle.Height = 32;
                rectangle.Visible = true;
            }
            else if(cursor.WindowPushed == CircleButton)
            {
                var circle = new Circle();
                circle.X = worldX;
                circle.Y = worldY;
                circle.Radius = 16;
                circle.Visible = true;
            }
        }
    }

    Property

    Mouse

    Touch Screen

    PrimaryPush

    The user just pressed the left mouse button down (was not down last frame)

    The user just touched the touch screen (was not touched last frame)

    PrimaryDown

    The user has the left mouse button down

    The user is touching the touch screen

    PrimaryClick

    The user has just released the left mouse button (was down last frame, not down this frame)

    The user has just lifted off of the touch screen (was touched last frame, not this frame)

    TouchScreen
    GuiManager's
    https://github.com/vchelaru/FlatRedBall/blob/NetStandard/Engines/Forms/FlatRedBall.Forms/FlatRedBall.Forms.Shared/Controls/ListBox.csarrow-up-right
    the ReceiveInput pagearrow-up-right
    var cursor = GuiManager.Cursor;
    if(cursor.PrimaryClick)
    {
      // do something if it's clicked
    }
    FlatRedBallServices.Game.IsMouseVisible = true;
    void CustomActivity(bool firstTimeCalled)
    {
        var cursor = GuiManager.Cursor;
    
        if (cursor.PrimaryPush)
        {
            var circle = new Circle();
            circle.X = cursor.WorldX;
            circle.Y = cursor.WorldY;
            circle.Visible = true;
            circle.Radius = 8;
        }
    }
    public void OnFocusUpdate()
    {
        var gamepads = GuiManager.GamePadsForUiControl;
        
        for (int i = 0; i < xboxGamepads.Count; i++)
        {
            var gamepad = xboxGamepads[i];
            if(gamepad.ButtonPushed(Button.A))
            {
                // perform logic here
            }
        }
    }
    // This assumes that the code exists in an object (such as a FlatRedBall Entity)
    // which implements IInputReceiver
    public void ReceiveInput()
    {
       // First let's process the input:
       // This assumes that MovementSpeed is a valid variable - like a variable defined on an Entity in Glue
       Keyboard keyboard = InputManager.Keyboard;
       if(keyboard.KeyDown(Keys.Left))
       {
           this.XVelocity = -MovementSpeed;
       }
       else if(keyboard.KeyDown(Keys.Right))
       {
           this.XVelocity = MovementSpeed;
       }
       else
       {
           this.XVelocity = 0;
       }
       // Prevents anything else from getting keyboard input this frame
       keyboard.Clear();
    }
    // assuming the receiver is a valid receiver
    receiver.TakingInput = false; // Will not be able to take input from the keyboard
    hashtag
    Code Example

    The following code creates a Circlearrow-up-right which moves with the Cursor.

    Add the following using statements:

    Add the following at class scope:

    Add the following to Initialize after initializing FlatRedBall:

    Add the following to Update:

    CursorWorldXAt.png

    hashtag
    Additional Arguments

    The WorldXAt and WorldYAt methods can also be passed Cameras and Layers if the default is not being used. Most commonly when working with HUD in Glue, you may add the HUD element to a 2D Layer, and this 2D Layer may have a settings that differ from your default Camera. In this case, you should use these available overrides. Specifically, if you are working in an Entity, you can use the following:

    hashtag
    Using custom Cursor graphics

    The WorldXAt and WorldYAt methods can be combined with Sprites and Layers to create a custom cursor. The following code shows how to create a custom cursor using the redball.bmp graphic. This code assumes a 2D coordinate system. You will need to adjust the Sprite size appropriately if using 3D coordinates instead:

    Add the following at class scope:

    Add the following to your game or Screen's Initialize/CustomInitialize:

    Add the following to your game or Screen's Update/CustomActivity:

    hashtag
    Method Limitations

    The WorldXAt and WorldYAt methods may giave unexpected results if the Camera is rotated. These methods should only be used when the Camera is facing down the Z axis (default orientation). For a rotated Cameraarrow-up-right, the Cursor's GetRayarrow-up-right method should be used. If interested in object picking, you can use the Cursor's IsOn3D methodarrow-up-right or the IClickablearrow-up-right or IWindowarrow-up-right interfaces for Entities in Glue.

    Cameraarrow-up-right
    2D Cameraarrow-up-right
    Object position
  • Camera position

  • Object orientation

  • Camera orientation

  • Camera perspective settings

  • Layers

  • It can be used to check if the cursor is over any of the following objects:

    • Sprite

    • Text

    • AxisAlignedCube

    • Sphere

    • Any other object implementing IPositionable, IScalable, IRotatable

    hashtag
    Code Example

    The following code creates a group of Sprites which turn invisible when the cursor moves over them. Add the following at class scope:

    Add the following in Initialize after initializing FlatRedBall:

    Add the following to Update:

    CursorIsOn3D.png

    hashtag
    IsOn3D for clicking UI

    The IsOn3D method can be used to detect if the Cursor has clicked on an object. For example, the following code shows how to check if the user has clicked on a Sprite:

    For more information on PrimaryClick, see the PrimaryClick pagearrow-up-right.

    hashtag
    IsOn3D and Layers

    The IsOn3D method supports Layersarrow-up-right as well. For example, assuming mySprite is a valid Sprite and myLayer is valid Layer:

    Gluearrow-up-right

    GuiManager

    hashtag
    Introduction

    The GuiManager is a static object responsible for common UI element management as well as some UI creation. There are two categories of UI elements:

    1. Default FlatRedBall GUI objects which are usually used for debugging and tools (these are used in all FRB graphical tools like the SpriteEditor, PolygonEditor, etc)

    2. Entities inheriting from

    For a Default FlatRedBall UI element to be visible and functional it must either belong to the GuiManager or another UI element. Entities are drawn by the engine like normal Entities - the GuiManager simply handles the cursor-based activity (like clicks).

    hashtag
    Window Categories

    When a is created and added to the GuiManager, it can be added to one of three internal lists. These lists define the three categories. These categories are:

    • Regular

    • Dominant

    • Perishable

    The following sections define the characteristics of each category.

    hashtag
    Regular

    Adding a by calling its constructor then passing it to the GuiManager's AddWindow method will add the as a regular . Regular remain in memory until they are removed using the GuiManager's RemoveWindow method. Making a regular invisible will not remove it from the GuiManager.

    hashtag
    Dominant

    Dominant are which consume interaction while they are visible. In other words, if a dominant is present, no other will receive input. Any can be made dominant through the method. Dominant are often used when the users attention is required on a particular . Examples include a asking if the program should really exit after clicking the close button or a for selecting a file to load in an application. Dominant can be removed by either calling the GuiManager's RemoveWindow method or by setting the dominant Visible property to false. Setting the Visible property to false will result in the GuiManager automatically removing the if is set to true.

    hashtag
    Perishable

    Perishable are which will automatically be removed by the GuiManager when the user clicks and the Cursor is not over the perishable . Perishable Windows are most commonly used for Windows which have a short life span. Examples include the drop-down ListBoxes that appear when clicking the on or menus appearing when right-clicking on an object. If the user clicks on a perishable , the will not automatically remove itself. The removal is usually handled in one of the events in this case.

    hashtag
    GuiManager Members

    Did this article leave any questions unanswered? Post any question in our for a rapid response.

    using FlatRedBall.Gui;
    using FlatRedBall.Math.Geometry;
    Circle circle;
     FlatRedBallServices.Game.IsMouseVisible = true;
     circle = ShapeManager.AddCircle();
    circle.X = GuiManager.Cursor.WorldXAt(0);
    circle.Y = GuiManager.Cursor.WorldYAt(0);
    // This represents the Entity assuming this code is in the custom methods of an Entity
    float worldX = GuiManager.Cursor.WorldXAt(this.Z, this.LayerProvidedByContainer);
    float worldY = GuiManager.Cursor.WorldYAt(this.Z, this.LayerProvidedByContainer);
    Sprite mCursorSprite;
    // Hide the cursor so that only our Sprite is invisible:
    FlatRedBallServices.Game.IsMouseVisible = false;
    // Make the layer 2D
    SpriteManager.TopLayer.UsePixelCoordinates();
    // Create the Sprite that will be used for the cursor
    mCursorSprite = SpriteManager.AddSprite("redball.bmp");
    // Add it to the TopLayer so it's always drawn on top of everything else
    SpriteManager.AddToLayer(mCursorSprite, SpriteManager.TopLayer);
    // Scale it so it's 2D.  This will be different if using a 3D camera
    mCursorSprite.PixelSize = .5f;
    Cursor cursor = GuiManager.Cursor;
    // Make sure to use the TopLayer when calling GetWorldXAt and GetWorldYAt
    mCursorSprite.X = cursor.WorldXAt(0, SpriteManager.TopLayer);
    mCursorSprite.Y = cursor.WorldYAt(0, SpriteManager.TopLayer);
    PositionedObjectList<Sprite> mSprites = new PositionedObjectList<Sprite>();
    for (int i = 0; i < 40; i++)
    {
        Sprite sprite = SpriteManager.AddSprite("redball.bmp");
        SpriteManager.Camera.PositionRandomlyInView(sprite, 20, 60);
        mSprites.Add(sprite);
    }
    for (int i = 0; i < mSprites.Count; i++)
    {
        Sprite sprite = mSprites[i];
    
        if (sprite.Visible && GuiManager.Cursor.IsOn3D(sprite))
        {
            sprite.Visible = false;
        }
    }
    // Assuming spriteInstance is a valid Sprite:
    if(GuiManager.Cursor.PrimaryClick && GuiManager.Cursor.IsOn3D(spriteInstance))
    {
       // The user has clicked on the Sprite, do something
    }
    bool isCursorOn = GuiManager.Cursor.IsOn3D(mySprite, myLayer);
  • Gluearrow-up-right
    IWindowarrow-up-right
    Gluearrow-up-right
    Windowarrow-up-right
    Windowarrow-up-right
    Windowarrow-up-right
    Windowarrow-up-right
    Windowsarrow-up-right
    Windowarrow-up-right
    Windowsarrow-up-right
    Windowsarrow-up-right
    Cursorarrow-up-right
    Windowarrow-up-right
    Windowsarrow-up-right
    Windowarrow-up-right
    AddDominantWindowarrow-up-right
    Windowsarrow-up-right
    Windowarrow-up-right
    OkCancelWindowarrow-up-right
    FileWindowarrow-up-right
    Windowsarrow-up-right
    Window'sarrow-up-right
    Windowarrow-up-right
    RemoveInvisibleDominantWindowsarrow-up-right
    Windowsarrow-up-right
    Windowsarrow-up-right
    Windowarrow-up-right
    Buttonarrow-up-right
    ComboBoxesarrow-up-right
    Windowarrow-up-right
    Windowarrow-up-right
    Window'sarrow-up-right
    FlatRedBall.Gui.GuiManager.AddDominantWindowarrow-up-right
    FlatRedBall.Gui.GuiManager.BringsClickedWindowsToFrontarrow-up-right
    FlatRedBall.Gui.GuiManager.BringToFrontarrow-up-right
    forumsarrow-up-right
    FlatRedBall.Gui.GuiManager.MakeRegularWindowarrow-up-right
    FlatRedBall.Gui.GuiManager.RemoveWindowarrow-up-right
    FlatRedBall.Gui.GuiManager.ShowTextInputWindowarrow-up-right
    FlatRedBall.Gui.GuiManager.SortZAndLayerBasedarrow-up-right
    FlatRedBall.Gui.GuiManager.TextHeightarrow-up-right
    FlatRedBall.Gui.GuiManager.Windowsarrow-up-right

    ScreenX

    hashtag
    Introduction

    The ScreenX and ScreenY properties return the X and Y coordinates of the Cursor in pixel coordinates. These values represent the location of the cursor relative to the top-left of the game screen. These values will not be impacted by properties set on the Cameraarrow-up-right. These values can be used if you are manually handling gestures or if you are converting screen coordinates to world coordinates instead of using the FlatRedBall methods.

    hashtag
    Code Example

    The following code uses the Debugger class to display the Cursor's screen coordinates in real time:

    void CustomActivity(bool firstTimeCalled)
    {
        FlatRedBall.Gui.Cursor cursor = FlatRedBall.Gui.GuiManager.Cursor;
    
        FlatRedBall.Debugging.Debugger.Write($"{cursor.ScreenX}, {cursor.ScreenY}");
    }