File: cursor.h

package info (click to toggle)
freespace2 24.2.0%2Brepack-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 43,716 kB
  • sloc: cpp: 595,001; ansic: 21,741; python: 1,174; sh: 457; makefile: 248; xml: 181
file content (198 lines) | stat: -rw-r--r-- 4,782 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198

#ifndef CURSOR_H
#define CURSOR_H
#pragma once

#include <SDL_mouse.h>

#include "globalincs/pstypes.h"
#include "cmdline/cmdline.h"
#include "io/timer.h"

#include <memory>

namespace io
{
	namespace mouse
	{
		/**
		 * @brief A mouse cursor
		 *
		 * This class holds the SDL_Cursor objects which represent the individual animation frames
		 */
		class Cursor
		{
		private:
			SCP_vector<SDL_Cursor*> mAnimationFrames; //!< The individual frames

			int mBitmapHandle; //!< The bitmap of this cursor

			UI_TIMESTAMP mBeginTimeStamp; //!< The UI timestamp when the animation was started, unused when not animated
			size_t mLastFrame; //!< The last frame which was set
			
			Cursor(const Cursor&); // Not implemented
			Cursor& operator=(const Cursor&); // Not implemented
		public:
			/**
			 * @brief Default constructor
			 * @param bitmap The bitmap handle of the cursor. The cursor takes ownership over this handle
			 */
			explicit Cursor(int bitmap) : mBitmapHandle(bitmap), mLastFrame(static_cast<size_t>(-1)) {}

			/**
			 * @brief Move constructor
			 *
			 * Transfers SDL resources to this newly constructed object
			 */
			Cursor(Cursor&& other) noexcept;
			
			/**
			 * @brief Move operator
			 *
			 * Transfers SDL resources to this object
			 */
			Cursor& operator=(Cursor&& other) noexcept;

			/**
			 * @brief Cursor destructor
			 *
			 * Frees the allocated SDL cursors
			 */
			~Cursor();
			
			/**
			 * @brief Adds an animation frame
			 *
			 * @param frame The cursor frame to add
			 */
			void addFrame(SDL_Cursor* frame);

			/**
			 * @brief Called to enable the cursor
			 * Either this function sets the cursor directly, or initializes values to #setCurrentFrame() works correctly
			 */
			void enable();

			/**
			 * @brief Called to set the correct frame
			 */
			void setCurrentFrame();

			/**
			 * @brief Query the cursors bitmap handle for bmpman
			 */
			int getBitmapHandle();
		};

		/**
		 * @brief Manages the cursor state of the game
		 */
		class CursorManager
		{
		private:
			static CursorManager* mSingleton; //!< The singleton manager

			SCP_vector<std::unique_ptr<Cursor>> mLoadedCursors; //!< A list of loaded cursors

			Cursor* mCurrentCursor; //!< The current cursor

			SCP_vector<std::pair<bool, bool>> mStatusStack; //!< Contains the stack of saved mouse statuses

			/**
			 * @brief Default constructor
			 *
			 * @note This class should not be instantiated outside from this module
			 */
			CursorManager();
		public:
			/**
			 * @brief Releases the cursor resources
			 */
			~CursorManager();

			/**
			 * @brief Loads a cursor
			 *
			 * Loads the specified file name as a cursor, by default this will try to load an animated cursor
			 *
			 * @param fileName The file name
			 * @param animated @c true to also load animated images
			 * @return The cursor or @c NULL if the process failed
			 */
			Cursor* loadCursor(const char* fileName, bool animated = true);

			/**
			 * @brief Loads a cursor from a bitmap handle
			 * The returned cursor takes ownership over the passed handle.
			 *
			 * @param bitmapHandle The bitmap handle, must be a valid handle
			 * @return The new cursor
			 */
			Cursor* loadFromBitmap(int bitmapHandle);

			/**
			 * @brief Sets the current cursor
			 * @param cursor The cursor instance to be set, may not be @c NULL
			 */
			void setCurrentCursor(Cursor* cursor);

			/**
			 * @brief Show or hide the cursor.
			 *
			 * Optionally @c grab may be specified to grab or not grab the mouse when the cursor is hidden
			 *
			 * @param show @c true to show @c false to hide
			 * @param grab @c true to grab the mouse @c false to disable grabbing
			 */
			void showCursor(bool show, bool grab = false);

			/**
			 * @brief Specifies if the cursor is shown
			 * @return @c true if shown ,@c false otherwise
			 */
			bool isCursorShown() { return mStatusStack.back().first; }

			/**
			 * @brief Gets the current cursor
			 * @return The current cursor instance
			 */
			Cursor* getCurrentCursor() { return mCurrentCursor; }
			
			/**
			 * @brief Pushes the current status onto the stack as a new entry
			 */
			void pushStatus();
			
			/**
			 * @brief Removes the top status from the stack and restores the previous
			 * @returns The removed state
			 */
			std::pair<bool, bool> popStatus();

		public:
			/**
			 * @brief Gets the global CursorManager
			 * @return The CursorManager
			 */
			static CursorManager* get() { return mSingleton; }

			/**
			 * @brief Initializes the Cursor system
			 */
			static void init();

			/**
			 * @brief Do a cursor frame
			 * This is needed for animated cursors
			 */
			static void doFrame();

			/**
			 * @brief Releases cursor resources
			 */
			static void shutdown();
		};
	}
}

#endif