Torque3D/Engine/source/windowManager/platformWindow.h
2015-01-25 13:42:32 +01:00

513 lines
16 KiB
C++

//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _WINDOWMANAGER_PLATFORMWINDOW_H_
#define _WINDOWMANAGER_PLATFORMWINDOW_H_
#include "math/mRect.h"
#include "core/util/journal/journaledSignal.h"
#include "core/util/safeDelete.h"
#include "windowManager/platformCursorController.h"
#include "windowManager/windowInputGenerator.h"
//forward decl's
class PlatformWindowManager;
class GFXDevice;
struct GFXVideoMode;
class GFXWindowTarget;
class IProcessInput;
/// Abstract representation of a native OS window.
///
/// Every windowing system has its own representations and conventions as
/// regards the windows on-screen. In order to provide Torque with means for
/// interfacing with multiple windows, tracking their state, etc. we provide
/// this interface.
///
/// This interface also allows the app to access the render target for the
/// window it represents, as well as control mode switches, get mode info,
/// and so on.
///
/// @see PlatformWindowManager
class PlatformWindow
{
friend class PlatformWindowManager;
protected:
/// Are we enabling IME or other keyboard input translation services,
/// or concerned about raw input?
bool mEnableKeyboardTranslation;
/// When Torque GuiText input controls have focus they need to
/// disable native OS keyboard accelerator translation.
bool mEnableAccelerators;
/// Minimum allowed size for this window. When possible, we will communicate
/// this to the OS.
Point2I mMinimumSize;
/// When the resize is locked, this will be used as both minimum and maximum window size
Point2I mLockedSize;
/// When this is true, resizing is locked
bool mResizeLocked;
/// Is Idle?
bool mIsBackground;
/// Cursor Controller for this Window
PlatformCursorController *mCursorController;
/// An opaque ID used to resolve references to this Window
WindowId mWindowId;
/// Window Mouse/Key input Controller for this Window
WindowInputGenerator *mWindowInputGenerator;
/// Suppress device resets
bool mSuppressReset;
/// Offscreen Render
bool mOffscreenRender;
/// This is set as part of the canvas being shown, and flags that the windows should render as normal from now on.
// Basically a flag that lets the window manager know that we've handled the splash screen, and to operate as normal.
bool mDisplayWindow;
/// Protected constructor so that the win
PlatformWindow()
{
mIsBackground = false; // This could be toggled to true to prefer performance.
mMinimumSize.set(0,0);
mLockedSize.set(0,0);
mResizeLocked = false;
mEnableKeyboardTranslation = false;
mEnableAccelerators = true;
mCursorController = NULL;
mSuppressReset = false;
mOffscreenRender = false;
mDisplayWindow = false;
// This controller maps window input (Mouse/Keyboard) to a generic input consumer
mWindowInputGenerator = new WindowInputGenerator( this );
}
public:
/// To get rid of a window, just delete it. Make sure the GFXDevice is
/// done with it first!
virtual ~PlatformWindow()
{
SAFE_DELETE( mCursorController );
SAFE_DELETE( mWindowInputGenerator );
}
/// Get the WindowController associated with this window
virtual void setInputController( IProcessInput *controller ) { if( mWindowInputGenerator ) mWindowInputGenerator->setInputController( controller ); };
WindowInputGenerator* getInputGenerator() const { return mWindowInputGenerator; }
/// Get the ID that uniquely identifies this window in the context of its
/// window manager.
virtual WindowId getWindowId() { return 0; };
enum WindowSystem
{
WindowSystem_Unknown = 0,
WindowSystem_Windows,
WindowSystem_X11,
};
virtual void* getSystemWindow(const WindowSystem system) { return NULL; }
/// Set the flag that determines whether to suppress a GFXDevice reset
inline void setSuppressReset(bool suppress) { mSuppressReset = suppress; };
/// @name GFX State Management
///
/// @{
/// Return a pointer to the GFX device this window is bound to. A GFX
/// device may use many windows, but a window can only be used by a
/// single GFX device.
virtual GFXDevice *getGFXDevice()=0;
/// Return a pointer to this window's render target.
///
/// By setting window targets from different windows, we can effect
/// rendering to multiple windows from a single device.
virtual GFXWindowTarget *getGFXTarget()=0;
/// Set the video mode for this window.
virtual void setVideoMode(const GFXVideoMode &mode)=0;
/// Get our current video mode - if the window has been resized, it will
/// reflect this.
virtual const GFXVideoMode &getVideoMode()=0;
/// If we're fullscreen, this function returns us to desktop mode.
///
/// This will be either the last mode that we had that was not
/// fullscreen, or the equivalent mode, windowed.
virtual bool clearFullscreen()=0;
/// @return true if this window is fullscreen, false otherwise.
virtual bool isFullscreen()=0;
/// Acquire the entire screen
void setFullscreen(const bool fullscreen);
/// Set Idle State (Background)
///
/// This is called to put a window into idle state, which causes it's
/// rendering priority to be toned down to prefer performance
virtual void setBackground( bool val ) { mIsBackground = val; };
/// Get Idle State (Background)
///
/// This is called to poll the window as to it's idle state.
virtual bool getBackground() { return mIsBackground; };
/// Set whether this window is intended for offscreen rendering
/// An offscreen window will never be shown or lose focus
virtual void setOffscreenRender(bool val ) { mOffscreenRender = val; };
/// Set whether this window is intended for offscreen rendering
///
/// This is called to poll the window as to it's idle state.
virtual bool getOffscreenRender() { return mOffscreenRender; };
/// Set whether this window is should display as normal
virtual void setDisplayWindow(bool val ) { mDisplayWindow = val; };
/// Set Focused State (Foreground)
///
/// Claim OS input focus for this window
virtual void setFocus() { }
/// @}
/// @name Caption
///
/// @{
/// Set the window's caption.
virtual bool setCaption(const char *cap)=0;
/// Get the window's caption.
virtual const char *getCaption()=0;
/// @}
/// @name Visibility
///
/// Control how the window is displayed
/// @{
/// Minimize the window on screen
virtual void minimize()=0;
/// Maximize the window on screen
virtual void maximize()=0;
/// Hide the window on screen
virtual void hide()=0;
/// Show the window on screen
virtual void show()=0;
/// Destroy the window on screen
virtual void close()=0;
/// Restore the window from a Maximized or Minimized state
virtual void restore()=0;
/// @}
/// @name Window Bounds
///
/// @{
/// The Client Rectangle or "Render Area" of a window is the area that
/// is occupied by a given client that is rendering to that window.
/// This does not include the area occupied by a title-bar, menu,
/// borders or other non-client elements.
/// @{
/// Set the Client Area Extent (Resolution) of this window
virtual void setClientExtent( const Point2I newExtent ) = 0;
/// Get the Client Area Extent (Resolution) of this window
virtual const Point2I getClientExtent() = 0;
/// @}
/// The bounds of a Window are defined as the entire area occupied by
/// that Window. This includes the area needed for a title-bar, menu,
/// borders, and other non-client elements.
///
/// @{
/// Resize the window to have some new bounds.
virtual void setBounds( const RectI &newBounds ) = 0;
/// Get the position and size (fullscreen windows are always at (0,0)).
virtual const RectI getBounds() const = 0;
/// @}
/// The Position of a window is always in relation to the very upper left
/// of the window. This means that saying setPosition at 0,0 will put the
/// position of the window title-bar (if one exists) at 0,0 and the Client
/// area will be offset from that point by the space needed for the Non-Client
/// area.
/// @{
/// Set the position of this window
virtual void setPosition( const Point2I newPosition ) = 0;
/// Get the position of this window
virtual const Point2I getPosition() = 0;
virtual void centerWindow() {};
/// Resize the window to have a new size (but be in the same position).
virtual bool setSize(const Point2I &newSize)=0;
/// @}
/// @name Coordinate Space Conversion
/// @{
/// Convert the coordinate given in this window space to screen coordinates.
virtual Point2I clientToScreen( const Point2I& point ) = 0;
/// Convert the given screen coordinates to coordinates in this window space.
virtual Point2I screenToClient( const Point2I& point ) = 0;
/// @}
/// @name Windowed state
///
/// This is only really meaningful if the window is not fullscreen.
///
/// @{
/// Returns true if the window is instantiated in the OS.
virtual bool isOpen() = 0;
/// Returns true if the window is visible.
virtual bool isVisible() = 0;
/// Returns true if the window has input focus
virtual bool isFocused() = 0;
/// Returns true if the window is minimized
virtual bool isMinimized() = 0;
/// Returns true if the window is maximized
virtual bool isMaximized() = 0;
/// @name Keyboard Translation
///
/// When keyboard translation is on, keypress events that correspond to character input
/// should be send as character input events rather than as raw key events *except* if
/// shouldNotTranslate() returns true for a specific keypress event. This enables the
/// platform layer to perform platform-specific character input mapping.
///
/// @{
/// Set if relevant keypress events should be translated into character input events.
virtual void setKeyboardTranslation(const bool enabled)
{
mEnableKeyboardTranslation = enabled;
}
/// Returns true if keyboard translation is enabled.
virtual bool getKeyboardTranslation() const
{
return mEnableKeyboardTranslation;
}
/// Returns true if the given keypress event should not be translated.
virtual bool shouldNotTranslate( U32 modifiers, U32 keyCode ) const;
/// @}
/// Used to disable native OS keyboard accelerators.
virtual void setAcceleratorsEnabled(const bool enabled)
{
mEnableAccelerators = enabled;
}
/// Returns true if native OS keyboard accelerators are enabled.
virtual bool getAcceleratorsEnabled() const
{
return mEnableAccelerators;
}
/// Sets a minimum window size. We'll work with the OS to prevent user
/// from sizing the window to less than this. Setting to (0,0) means
/// user has complete freedom of resize.
virtual void setMinimumWindowSize(Point2I minSize)
{
mMinimumSize = minSize;
}
/// Returns the current minimum window size for this window.
virtual Point2I getMinimumWindowSize()
{
return mMinimumSize;
}
/// Locks/unlocks window resizing
virtual void lockSize(bool locked)
{
mResizeLocked = locked;
if (mResizeLocked)
mLockedSize = getBounds().extent;
}
/// Returns true if the window size is locked
virtual bool isSizeLocked()
{
return mResizeLocked;
}
/// Returns the locked window size
virtual Point2I getLockedSize()
{
return mLockedSize;
}
/// @}
/// @name Window Cursor
///
/// Accessors to control a windows cursor shape and visibility
///
/// @{
/// Get the CursorController that this window owns.
virtual PlatformCursorController *getCursorController() { return mCursorController; };
/// Set the cursor position based on logical coordinates from the upper-right corner
///
/// @param x The X position of the cursor
/// @param y The Y position of the cursor
virtual void setCursorPosition(S32 x, S32 y)
{
if( mCursorController != NULL )
mCursorController->setCursorPosition(x,y);
}
/// Get the cursor position based on logical coordinates from the upper-right corner
///
/// @param point A reference to a Point2I to store the coordinates
virtual void getCursorPosition( Point2I &point )
{
if( mCursorController != NULL )
mCursorController->getCursorPosition(point);
}
/// Set the cursor visibility on this window
///
/// @param visible Whether the cursor should be visible or not
virtual void setCursorVisible(bool visible)
{
if( mCursorController != NULL )
mCursorController->setCursorVisible(visible);
}
/// Get the cursor visibility on this window
///
/// @return true if the cursor is visible or false if it's hidden
virtual bool isCursorVisible()
{
if( mCursorController != NULL )
return mCursorController->isCursorVisible();
return false;
}
/// Lock the mouse to this window.
///
/// When this is set, the mouse will always be returned to the center
/// of the client area after every mouse event. The mouse will also be
/// hidden while it is locked.
///
/// The mouse cannot be moved out of the bounds of the window, but the
/// window may lose focus (for instance by an alt-tab or other event).
/// While the window lacks focus, no mouse events will be reported.
virtual void setMouseLocked( bool enable )=0;
/// Is the mouse locked ?
virtual bool isMouseLocked() const = 0;
/// Should the mouse be locked at the next opportunity ?
///
/// This flag is set to the current state of the mouse lock
/// on a window, to specify the preferred lock status of the
/// mouse in a platform window.
///
/// This is important for situations where a call is made
/// to setMouseLocked, and the window is not in a state that
/// it can be cleanly locked. Take for example if it was called
/// while the window is in the background, then it is not appropriate
/// to lock the window, but rather the window should query this
/// state at it's next opportunity and lock the mouse if requested.
virtual bool shouldLockMouse() const = 0;
/// @}
virtual PlatformWindow * getNextWindow() const = 0;
/// @name Event Handlers
///
/// Various events that this window receives. These are all subclasses of
/// JournaledSignal, so you can subscribe to them and receive notifications
/// per the documentation for that class.
///
/// @{
///
AppEvent appEvent;
MouseEvent mouseEvent;
MouseWheelEvent wheelEvent;
ButtonEvent buttonEvent;
LinearEvent linearEvent;
KeyEvent keyEvent;
CharEvent charEvent;
DisplayEvent displayEvent;
ResizeEvent resizeEvent;
IdleEvent idleEvent;
/// @}
/// Get the platform specific object needed to create or attach an accelerated
/// graohics drawing context on or to the window
/// Win32 D3D and OpenGL typically needs an HWND
/// Mac Cocoa OpenGL typically needs an NSOpenGLView
/// Mac Carbon OpenGL typically needs a WindowRef
///
virtual void* getPlatformDrawable() const = 0;
protected:
virtual void _setFullscreen(const bool fullScreen) {};
};
#endif