1 /*****************************************************************************
2  * Copyright (c) 2014-2020 OpenRCT2 developers
3  *
4  * For a complete list of all authors, please refer to contributors.md
5  * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
6  *
7  * OpenRCT2 is licensed under the GNU General Public License version 3.
8  *****************************************************************************/
9 
10 #pragma once
11 
12 #include <SDL.h>
13 #include <functional>
14 #include <map>
15 #include <openrct2/interface/Cursors.h>
16 #include <openrct2/util/Util.h>
17 
18 struct SDL_Cursor;
19 
20 namespace OpenRCT2::Ui
21 {
22     class CursorRepository
23     {
24     private:
25         class CursorSetHolder
26         {
27         private:
28             SDL_Cursor* _cursors[EnumValue(CursorID::Count)] = { nullptr };
29 
30         public:
CursorSetHolder(const std::function<SDL_Cursor * (CursorID)> & getCursor)31             CursorSetHolder(const std::function<SDL_Cursor*(CursorID)>& getCursor)
32             {
33                 for (size_t i = 0; i < EnumValue(CursorID::Count); i++)
34                 {
35                     _cursors[i] = getCursor(static_cast<CursorID>(i));
36                 }
37             }
38 
~CursorSetHolder()39             ~CursorSetHolder()
40             {
41                 for (size_t i = 0; i < EnumValue(CursorID::Count); i++)
42                 {
43                     SDL_FreeCursor(_cursors[i]);
44                 }
45             }
46 
getScaledCursor(CursorID cursorId)47             SDL_Cursor* getScaledCursor(CursorID cursorId)
48             {
49                 return _cursors[EnumValue(cursorId)];
50             }
51         };
52 
53         constexpr static int32_t BASE_CURSOR_WIDTH = 32;
54         constexpr static int32_t BASE_CURSOR_HEIGHT = 32;
55 
56         CursorID _currentCursor = CursorID::Undefined;
57         uint8_t _currentCursorScale = 1;
58 
59         std::map<uint8_t, CursorSetHolder> _scaledCursors;
60 
61     public:
62         ~CursorRepository();
63         void LoadCursors();
64         CursorID GetCurrentCursor();
65         void SetCurrentCursor(CursorID cursorId);
66         void SetCursorScale(uint8_t cursorScale);
67 
68     private:
69         SDL_Cursor* Create(const CursorData* cursorInfo, uint8_t scale);
70         void GenerateScaledCursorSetHolder(uint8_t scale);
71         static const CursorData* GetCursorData(CursorID cursorId);
72     };
73 } // namespace OpenRCT2::Ui
74