浏览代码

Created UI windowing interface

Thomas Buck 10 年前
父节点
当前提交
3c90bc49a8
共有 18 个文件被更改,包括 355 次插入214 次删除
  1. 4
    0
      ChangeLog.md
  2. 10
    16
      include/Console.h
  3. 7
    5
      include/Game.h
  4. 3
    14
      include/Menu.h
  5. 0
    3
      include/MenuFolder.h
  6. 0
    6
      include/OpenRaider.h
  7. 54
    0
      include/UI.h
  8. 3
    0
      include/Window.h
  9. 2
    2
      include/WindowSDL.h
  10. 1
    0
      src/CMakeLists.txt
  11. 42
    22
      src/Console.cpp
  12. 9
    0
      src/Game.cpp
  13. 6
    14
      src/Menu.cpp
  14. 15
    10
      src/MenuFolder.cpp
  15. 3
    96
      src/OpenRaider.cpp
  16. 165
    0
      src/UI.cpp
  17. 11
    6
      src/WindowSDL.cpp
  18. 20
    20
      src/commands/CommandEngine.cpp

+ 4
- 0
ChangeLog.md 查看文件

@@ -2,6 +2,10 @@
2 2
 
3 3
 ## OpenRaider (0.1.3) xythobuz <xythobuz@xythobuz.de>
4 4
 
5
+    [ 20140901 ]
6
+    * Created abstract UI class handling “windows” like menu and console. Windows
7
+      can be stacked arbitrarily. The top most gets keyboard/mouse/action events.
8
+
5 9
     [ 20140831 ]
6 10
     * Moved command specific code from OpenRaider to static Command methods
7 11
 

+ 10
- 16
include/Console.h 查看文件

@@ -12,20 +12,16 @@
12 12
 #include <sstream>
13 13
 #include <vector>
14 14
 
15
+#include "UI.h"
16
+
15 17
 /*!
16 18
  * \brief Console 'overlay'
17 19
  */
18
-class Console {
20
+class Console : public UI {
19 21
 public:
20 22
 
21
-    /*!
22
-     * \brief Constructs an object of Console
23
-     */
24 23
     Console();
25
-
26
-    void setVisible(bool visible);
27
-
28
-    bool isVisible();
24
+    ~Console();
29 25
 
30 26
     template<typename T>
31 27
     Console &operator<<(const T t) {
@@ -40,13 +36,12 @@ public:
40 36
         return (*this);
41 37
     }
42 38
 
43
-    void display();
44
-
45
-    void handleKeyboard(KeyboardButton key, bool pressed);
46
-
47
-    void handleText(char *text, bool notFinished);
48
-
49
-    void handleMouseScroll(int xrel, int yrel);
39
+    virtual void moveToTop();
40
+    virtual void makeInvisible();
41
+    virtual void display();
42
+    virtual void handleKeyboard(KeyboardButton key, bool pressed);
43
+    virtual void handleText(char *text, bool notFinished);
44
+    virtual void handleMouseScroll(int xrel, int yrel);
50 45
 
51 46
     const static char endl = '\n';
52 47
 
@@ -54,7 +49,6 @@ private:
54 49
 
55 50
     void moveInHistory(bool up);
56 51
 
57
-    bool mVisible;
58 52
     std::string mInputBuffer;
59 53
     std::string mPartialInput;
60 54
     std::vector<std::string> mHistory;

+ 7
- 5
include/Game.h 查看文件

@@ -12,16 +12,16 @@
12 12
 #include <vector>
13 13
 
14 14
 #include "Entity.h"
15
+#include "UI.h"
15 16
 #include "TombRaider.h"
16 17
 
17 18
 /*!
18 19
  * \brief Game abstraction
19 20
  */
20
-class Game {
21
+class Game : public UI {
21 22
 public:
22 23
 
23 24
     Game();
24
-
25 25
     ~Game();
26 26
 
27 27
     int initialize();
@@ -32,9 +32,11 @@ public:
32 32
 
33 33
     void destroy();
34 34
 
35
-    void handleAction(ActionEvents action, bool isFinished);
36
-
37
-    void handleMouseMotion(int xrel, int yrel);
35
+    virtual void display();
36
+    virtual void handleAction(ActionEvents action, bool isFinished);
37
+    virtual void handleMouseMotion(int xrel, int yrel);
38
+    virtual void moveToTop() { }
39
+    virtual void makeInvisible() { }
38 40
 
39 41
     unsigned int getTextureStart();
40 42
     unsigned int getTextureOffset();

+ 3
- 14
include/Menu.h 查看文件

@@ -10,28 +10,18 @@
10 10
 
11 11
 #include <functional>
12 12
 
13
+#include "UI.h"
14
+
13 15
 /*!
14 16
  * \brief Menu 'overlay'
15 17
  */
16
-class Menu {
18
+class Menu : public UI {
17 19
 public:
18 20
 
19 21
     virtual ~Menu() { }
20 22
 
21
-    virtual void setVisible(bool visible);
22
-
23
-    virtual bool isVisible();
24
-
25 23
     virtual int initialize() = 0;
26 24
 
27
-    virtual void display() = 0;
28
-
29
-    virtual void handleKeyboard(KeyboardButton key, bool pressed) = 0;
30
-
31
-    virtual void handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) = 0;
32
-
33
-    virtual void handleMouseScroll(int xrel, int yrel) = 0;
34
-
35 25
 protected:
36 26
 
37 27
     virtual void showDialog(std::string msg, std::string btn1, std::string btn2,
@@ -48,7 +38,6 @@ protected:
48 38
 
49 39
     virtual void displayDialog();
50 40
 
51
-    bool mVisible;
52 41
     bool dialogState;
53 42
     std::string dialogText;
54 43
     std::string dialogButton1;

+ 0
- 3
include/MenuFolder.h 查看文件

@@ -30,11 +30,8 @@ public:
30 30
     virtual int initialize();
31 31
 
32 32
     virtual void display();
33
-
34 33
     virtual void handleKeyboard(KeyboardButton key, bool pressed);
35
-
36 34
     virtual void handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released);
37
-
38 35
     virtual void handleMouseScroll(int xrel, int yrel);
39 36
 
40 37
 private:

+ 0
- 6
include/OpenRaider.h 查看文件

@@ -39,12 +39,6 @@ public:
39 39
     void run();
40 40
     void frame();
41 41
 
42
-    void handleKeyboard(KeyboardButton key, bool pressed);
43
-    void handleText(char *text, bool notFinished);
44
-    void handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released);
45
-    void handleMouseMotion(int xrel, int yrel);
46
-    void handleMouseScroll(int xrel, int yrel);
47
-
48 42
     //! \fixme should be private
49 43
     char *mBaseDir;
50 44
     char *mPakDir;

+ 54
- 0
include/UI.h 查看文件

@@ -0,0 +1,54 @@
1
+/*!
2
+ * \file include/UI.h
3
+ * \brief Abstract UI interface
4
+ *
5
+ * \author xythobuz
6
+ */
7
+
8
+#ifndef _UI_H_
9
+#define _UI_H_
10
+
11
+#include <functional>
12
+#include <memory>
13
+#include <vector>
14
+
15
+class UI {
16
+public:
17
+    virtual ~UI();
18
+
19
+    virtual void display();
20
+    virtual void handleKeyboard(KeyboardButton key, bool pressed);
21
+    virtual void handleText(char *text, bool notFinished);
22
+    virtual void handleAction(ActionEvents action, bool isFinished);
23
+    virtual void handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released);
24
+    virtual void handleMouseMotion(int xrel, int yrel);
25
+    virtual void handleMouseScroll(int xrel, int yrel);
26
+
27
+    virtual bool isOnTop();
28
+    virtual void moveToTop();
29
+    virtual void makeInvisible();
30
+
31
+    static void addWindow(UI* window);
32
+    static void removeWindow(UI *window);
33
+    static void displayInOrder();
34
+    static void passKeyboard(KeyboardButton key, bool pressed);
35
+    static void passText(char *text, bool notFinished);
36
+    static void passMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released);
37
+    static void passMouseMotion(int xrel, int yrel);
38
+    static void passMouseScroll(int xrel, int yrel);
39
+
40
+protected:
41
+    long zPos;
42
+
43
+private:
44
+    static void findInList(UI *w, std::function<void (unsigned long i)> func);
45
+    static bool isOnTop(unsigned long windowID);
46
+    static void moveToTop(unsigned long windowID);
47
+    static void makeInvisible(unsigned long windowID);
48
+    static bool compareUIs(UI* a, UI* b);
49
+
50
+    static std::vector<UI*> windows;
51
+};
52
+
53
+#endif
54
+

+ 3
- 0
include/Window.h 查看文件

@@ -30,6 +30,8 @@ public:
30 30
 
31 31
     virtual void setTextInput(bool on) = 0;
32 32
 
33
+    virtual bool getTextInput() = 0;
34
+
33 35
     virtual void delay(unsigned int ms) = 0;
34 36
 
35 37
     virtual void swapBuffersGL() = 0;
@@ -54,6 +56,7 @@ protected:
54 56
     bool mInit;
55 57
     bool mFullscreen;
56 58
     bool mMousegrab;
59
+    bool mTextInput;
57 60
     unsigned int mWidth;
58 61
     unsigned int mHeight;
59 62
 };

+ 2
- 2
include/WindowSDL.h 查看文件

@@ -42,6 +42,8 @@ public:
42 42
 
43 43
     virtual void setTextInput(bool on);
44 44
 
45
+    virtual bool getTextInput();
46
+
45 47
     virtual void delay(unsigned int ms);
46 48
 
47 49
     virtual void swapBuffersGL();
@@ -49,8 +51,6 @@ public:
49 51
 private:
50 52
     SDL_Window *mWindow;      //!< This is the pointer to the SDL surface
51 53
     SDL_GLContext mGLContext; //!< The OpenGL Context
52
-
53
-    bool mTextInput;
54 54
 };
55 55
 
56 56
 #endif

+ 1
- 0
src/CMakeLists.txt 查看文件

@@ -70,6 +70,7 @@ set (SRCS ${SRCS} "Sprite.cpp")
70 70
 set (SRCS ${SRCS} "StaticMesh.cpp")
71 71
 set (SRCS ${SRCS} "TextureManager.cpp")
72 72
 set (SRCS ${SRCS} "TombRaider.cpp")
73
+set (SRCS ${SRCS} "UI.cpp")
73 74
 set (SRCS ${SRCS} "ViewVolume.cpp")
74 75
 set (SRCS ${SRCS} "Window.cpp")
75 76
 set (SRCS ${SRCS} "World.cpp")

+ 42
- 22
src/Console.cpp 查看文件

@@ -17,43 +17,50 @@
17 17
 #include "Console.h"
18 18
 
19 19
 Console::Console() {
20
-    mVisible = false;
20
+    zPos = -1;
21 21
     mHistoryPointer = 0;
22 22
     mLineOffset = 0;
23
+
24
+    UI::addWindow(this);
23 25
 }
24 26
 
25
-void Console::setVisible(bool visible) {
26
-    mVisible = visible;
27
-    getWindow().setTextInput(mVisible);
27
+Console::~Console() {
28
+    UI::removeWindow(this);
28 29
 }
29 30
 
30
-bool Console::isVisible() {
31
-    return mVisible;
31
+void Console::moveToTop() {
32
+    if (!getWindow().getTextInput())
33
+        getWindow().setTextInput(true);
34
+
35
+    UI::moveToTop();
32 36
 }
33 37
 
34
-#define LINE_GEOMETRY(window) \
35
-    unsigned int firstLine = 35; \
36
-    unsigned int lastLine = (window.getHeight() / 2) - 55; \
37
-    unsigned int inputLine = (window.getHeight() / 2) - 30; \
38
-    unsigned int lineSteps = 20; \
39
-    unsigned int lineCount = (lastLine - firstLine + lineSteps) / lineSteps; \
40
-    while (((lineCount * lineSteps) + firstLine) < inputLine) { \
41
-        lineSteps++; \
42
-        lineCount = (lastLine - firstLine + lineSteps) / lineSteps; \
43
-    }
38
+void Console::makeInvisible() {
39
+    if (getWindow().getTextInput())
40
+        getWindow().setTextInput(false);
44 41
 
45
-void Console::display() {
46
-    if (!mVisible)
47
-        return;
42
+    UI::makeInvisible();
43
+}
48 44
 
45
+void Console::display() {
49 46
     // Calculate line drawing geometry
50 47
     // Depends on window height, so recalculate every time
51
-    LINE_GEOMETRY(getWindow());
48
+    unsigned int firstLine = 35;
49
+    unsigned int lastLine = (::getWindow().getHeight() / 2) - 55;
50
+    unsigned int inputLine = (::getWindow().getHeight() / 2) - 30;
51
+    unsigned int lineSteps = 20;
52
+    unsigned int lineCount = (lastLine - firstLine + lineSteps) / lineSteps;
53
+    while (((lineCount * lineSteps) + firstLine) < inputLine) {
54
+        lineSteps++;
55
+        lineCount = (lastLine - firstLine + lineSteps) / lineSteps;
56
+    }
57
+
58
+    ::getWindow().glEnter2D();
52 59
 
53 60
     // Draw half-transparent *overlay*
54 61
     glColor4f(0.0f, 0.0f, 0.0f, 0.75f);
55 62
     glDisable(GL_TEXTURE_2D);
56
-    glRecti(0, 0, getWindow().getWidth(), getWindow().getHeight() / 2);
63
+    glRecti(0, 0, ::getWindow().getWidth(), ::getWindow().getHeight() / 2);
57 64
     glEnable(GL_TEXTURE_2D);
58 65
 
59 66
     unsigned long scrollIndicator;
@@ -87,6 +94,8 @@ void Console::display() {
87 94
 
88 95
     // Draw current input
89 96
     getFont().drawText(10, inputLine, 0.75f, BLUE, "> " + mInputBuffer + mPartialInput);
97
+
98
+    ::getWindow().glExit2D();
90 99
 }
91 100
 
92 101
 void Console::handleKeyboard(KeyboardButton key, bool pressed) {
@@ -178,7 +187,18 @@ void Console::handleText(char *text, bool notFinished) {
178 187
 
179 188
 void Console::handleMouseScroll(int xrel, int yrel) {
180 189
     assert((xrel != 0) || (yrel != 0));
181
-    LINE_GEOMETRY(getWindow());
190
+
191
+    // Calculate line drawing geometry
192
+    // Depends on window height, so recalculate every time
193
+    unsigned int firstLine = 35;
194
+    unsigned int lastLine = (::getWindow().getHeight() / 2) - 55;
195
+    unsigned int inputLine = (::getWindow().getHeight() / 2) - 30;
196
+    unsigned int lineSteps = 20;
197
+    unsigned int lineCount = (lastLine - firstLine + lineSteps) / lineSteps;
198
+    while (((lineCount * lineSteps) + firstLine) < inputLine) {
199
+        lineSteps++;
200
+        lineCount = (lastLine - firstLine + lineSteps) / lineSteps;
201
+    }
182 202
 
183 203
     if (mHistory.size() > lineCount) {
184 204
         if (yrel > 0) {

+ 9
- 0
src/Game.cpp 查看文件

@@ -30,14 +30,19 @@ std::map<int, int> gMapTex2Bump;
30 30
 #endif
31 31
 
32 32
 Game::Game() {
33
+    zPos = 0;
33 34
     mLoaded = false;
34 35
     mLara = -1;
35 36
     mTextureStart = 0;
36 37
     mTextureOffset = 0;
38
+
39
+    UI::addWindow(this);
37 40
 }
38 41
 
39 42
 Game::~Game() {
40 43
     destroy();
44
+
45
+    UI::removeWindow(this);
41 46
 }
42 47
 
43 48
 unsigned int Game::getTextureStart() {
@@ -57,6 +62,10 @@ int Game::initialize() {
57 62
     return 0;
58 63
 }
59 64
 
65
+void Game::display() {
66
+    getRender().display();
67
+}
68
+
60 69
 void Game::destroy() {
61 70
     mLoaded = false;
62 71
     mLara = -1;

+ 6
- 14
src/Menu.cpp 查看文件

@@ -11,14 +11,6 @@
11 11
 #include "Window.h"
12 12
 #include "Menu.h"
13 13
 
14
-void Menu::setVisible(bool visible) {
15
-    mVisible = visible;
16
-}
17
-
18
-bool Menu::isVisible() {
19
-    return mVisible;
20
-}
21
-
22 14
 void Menu::showDialog(std::string msg, std::string btn1, std::string btn2,
23 15
         std::function<int (bool state)> callback) {
24 16
     // Only show one dialog at a time
@@ -94,7 +86,7 @@ bool Menu::handleMouseScrollDialog(int xrel, int yrel) {
94 86
 
95 87
 void Menu::displayDialog() {
96 88
     if (dialogText.length() > 0) {
97
-        unsigned int wMax = ((unsigned int)(getWindow().getWidth() * 0.66f));
89
+        unsigned int wMax = ((unsigned int)(::getWindow().getWidth() * 0.66f));
98 90
 
99 91
         unsigned int w0 = getFont().widthText(1.0f, dialogText) + 20;
100 92
         if (w0 > wMax)
@@ -146,8 +138,8 @@ void Menu::displayDialog() {
146 138
             hOverlay = h0 + h1;
147 139
         }
148 140
 
149
-        unsigned int xOverlay = (getWindow().getWidth() - wOverlay) / 2;
150
-        unsigned int yOverlay = (getWindow().getHeight() - hOverlay) / 2;
141
+        unsigned int xOverlay = (::getWindow().getWidth() - wOverlay) / 2;
142
+        unsigned int yOverlay = (::getWindow().getHeight() - hOverlay) / 2;
151 143
 
152 144
         glColor4f(0.0f, 0.0f, 0.0f, 0.75f);
153 145
         glDisable(GL_TEXTURE_2D);
@@ -162,13 +154,13 @@ void Menu::displayDialog() {
162 154
                 getFont().drawTextWrapped(xOverlay + 10 + w1, yOverlay + 10 + h0,
163 155
                     1.0f, dialogState ? RED : BLUE, w2, dialogButton2);
164 156
             } else {
165
-                getFont().drawTextWrapped((getWindow().getWidth() - w1) / 2,
157
+                getFont().drawTextWrapped((::getWindow().getWidth() - w1) / 2,
166 158
                     yOverlay + 10 + h0, 1.0f, dialogState ? BLUE : RED, w1, dialogButton1);
167
-                getFont().drawTextWrapped((getWindow().getWidth() - w2) / 2,
159
+                getFont().drawTextWrapped((::getWindow().getWidth() - w2) / 2,
168 160
                     yOverlay + 10 + h0 + h1, 1.0f, dialogState ? RED : BLUE, w2, dialogButton2);
169 161
             }
170 162
         } else {
171
-            getFont().drawTextWrapped((getWindow().getWidth() - w1) / 2,
163
+            getFont().drawTextWrapped((::getWindow().getWidth() - w1) / 2,
172 164
                     yOverlay + 10 + h0, 1.0f, RED, w1, dialogButton1);
173 165
         }
174 166
     }

+ 15
- 10
src/MenuFolder.cpp 查看文件

@@ -14,17 +14,21 @@
14 14
 #include "MenuFolder.h"
15 15
 
16 16
 MenuFolder::MenuFolder() {
17
-    mVisible = false;
17
+    zPos = -1;
18 18
     mCursor = 0;
19 19
     mMin = 0;
20 20
     mapFolder = nullptr;
21 21
     hiddenState = false;
22 22
     dialogState = false;
23
+
24
+    UI::addWindow(this);
23 25
 }
24 26
 
25 27
 MenuFolder::~MenuFolder() {
26 28
     delete mapFolder;
27 29
     mapFolder = nullptr;
30
+
31
+    UI::removeWindow(this);
28 32
 }
29 33
 
30 34
 int MenuFolder::initialize() {
@@ -71,20 +75,19 @@ int MenuFolder::initialize(Folder *folder, bool filter) {
71 75
 }
72 76
 
73 77
 void MenuFolder::display() {
74
-    if (!mVisible)
75
-        return;
78
+    ::getWindow().glEnter2D();
76 79
 
77 80
     // Draw half-transparent overlay
78 81
     glColor4f(0.0f, 0.0f, 0.0f, 0.75f);
79 82
     glDisable(GL_TEXTURE_2D);
80
-    glRecti(0, 0, (GLint)getWindow().getWidth(), (GLint)getWindow().getHeight());
83
+    glRecti(0, 0, (GLint)::getWindow().getWidth(), (GLint)::getWindow().getHeight());
81 84
     glEnable(GL_TEXTURE_2D);
82 85
 
83 86
     // Draw heading
84
-    getFont().drawTextCentered(0, 10, 1.2f, BLUE, getWindow().getWidth(), VERSION);
87
+    getFont().drawTextCentered(0, 10, 1.2f, BLUE, ::getWindow().getWidth(), VERSION);
85 88
 
86 89
     // Estimate displayable number of items
87
-    int items = (getWindow().getHeight() - 60) / 25;
90
+    int items = (::getWindow().getHeight() - 60) / 25;
88 91
 
89 92
     // Print list of "..", folders, files
90 93
     for (long i = mMin; (i < (mMin + items))
@@ -101,6 +104,8 @@ void MenuFolder::display() {
101 104
     }
102 105
 
103 106
     displayDialog();
107
+
108
+    ::getWindow().glExit2D();
104 109
 }
105 110
 
106 111
 void MenuFolder::loadOrOpen() {
@@ -117,7 +122,7 @@ void MenuFolder::loadOrOpen() {
117 122
         tmp += mapFolder->getFile((unsigned long)mCursor - 1 - mapFolder->folderCount()).getPath();
118 123
         int error = getOpenRaider().command(tmp.c_str());
119 124
         if (error == 0) {
120
-            setVisible(false);
125
+            makeInvisible();
121 126
         } else {
122 127
             std::ostringstream err;
123 128
             err << "Error loading map: " << error << "!";
@@ -134,7 +139,7 @@ void MenuFolder::handleKeyboard(KeyboardButton key, bool pressed) {
134 139
         return;
135 140
 
136 141
     assert(mapFolder != nullptr);
137
-    int items = (getWindow().getHeight() - 60) / 25;
142
+    int items = (::getWindow().getHeight() - 60) / 25;
138 143
 
139 144
     if (key == upKey) {
140 145
         if (mCursor > 0)
@@ -164,7 +169,7 @@ void MenuFolder::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton
164 169
     if (handleMouseClickDialog(x, y, button, released))
165 170
         return;
166 171
 
167
-    int items = (getWindow().getHeight() - 60) / 25;
172
+    int items = (::getWindow().getHeight() - 60) / 25;
168 173
 
169 174
     if (released || (button != leftmouseKey))
170 175
         return;
@@ -185,7 +190,7 @@ void MenuFolder::handleMouseScroll(int xrel, int yrel) {
185 190
 
186 191
     assert((xrel != 0) || (yrel != 0));
187 192
     assert(mapFolder != nullptr);
188
-    int items = (getWindow().getHeight() - 60) / 25;
193
+    int items = (::getWindow().getHeight() - 60) / 25;
189 194
 
190 195
     if ((mapFolder->folderCount() + mapFolder->fileCount() + 1) > items) {
191 196
         if (yrel < 0) {

+ 3
- 96
src/OpenRaider.cpp 查看文件

@@ -136,7 +136,7 @@ int OpenRaider::initialize() {
136 136
     mFPS = true;
137 137
 #endif
138 138
 
139
-    getMenu().setVisible(true);
139
+    getMenu().moveToTop();
140 140
     systemTimerReset();
141 141
 
142 142
     return 0;
@@ -159,15 +159,10 @@ void OpenRaider::frame() {
159 159
     // Get keyboard and mouse input
160 160
     getWindow().eventHandling();
161 161
 
162
-    // Draw game scene
163
-    getRender().display();
162
+    UI::displayInOrder();
164 163
 
165
-    // Draw 2D overlays (console and menu)
166 164
     getWindow().glEnter2D();
167 165
 
168
-    getConsole().display();
169
-    getMenu().display();
170
-
171 166
     // Draw FPS counter
172 167
     if (mFPS) {
173 168
         std::ostringstream fpsText;
@@ -177,7 +172,7 @@ void OpenRaider::frame() {
177 172
 
178 173
 #ifdef DEBUG
179 174
     // Draw debug infos
180
-    if (getGame().isLoaded() && (!getMenu().isVisible())) {
175
+    if (getGame().isLoaded() && (!getMenu().isOnTop())) {
181 176
         for (int i = 0; i < 3; i++) {
182 177
             std::ostringstream axis;
183 178
             axis << getGame().getLara().getPos(i) / 256.0f << " (" << getGame().getLara().getAngle(i) << ")";
@@ -201,91 +196,3 @@ void OpenRaider::frame() {
201 196
     }
202 197
 }
203 198
 
204
-void OpenRaider::handleKeyboard(KeyboardButton key, bool pressed) {
205
-    assert(key < unknownKey);
206
-    assert(mRunning == true);
207
-
208
-    if ((keyBindings[menuAction] == key) && pressed) {
209
-        getMenu().setVisible(!getMenu().isVisible());
210
-    } else if (!getMenu().isVisible()) {
211
-        if ((keyBindings[consoleAction] == key) && pressed) {
212
-            getConsole().setVisible(!getConsole().isVisible());
213
-        } else if (!getConsole().isVisible()) {
214
-            for (int i = forwardAction; i < ActionEventCount; i++) {
215
-                if (keyBindings[i] == key) {
216
-                    getGame().handleAction((ActionEvents)i, !pressed);
217
-                }
218
-            }
219
-        } else {
220
-            getConsole().handleKeyboard(key, pressed);
221
-        }
222
-    } else {
223
-        getMenu().handleKeyboard(key, pressed);
224
-    }
225
-
226
-    bool mousegrab = !(getMenu().isVisible() || getConsole().isVisible());
227
-    if (mousegrab != getWindow().getMousegrab())
228
-        getWindow().setMousegrab(mousegrab);
229
-}
230
-
231
-void OpenRaider::handleText(char *text, bool notFinished) {
232
-    assert(text != NULL);
233
-    assert(text[0] != '\0');
234
-    assert(mRunning == true);
235
-
236
-    if ((getConsole().isVisible()) && (!getMenu().isVisible())) {
237
-        getConsole().handleText(text, notFinished);
238
-    }
239
-
240
-    bool mousegrab = !(getMenu().isVisible() || getConsole().isVisible());
241
-    if (mousegrab != getWindow().getMousegrab())
242
-        getWindow().setMousegrab(mousegrab);
243
-}
244
-
245
-void OpenRaider::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) {
246
-    assert(button < unknownKey);
247
-    assert(mRunning == true);
248
-
249
-    if (getMenu().isVisible()) {
250
-        getMenu().handleMouseClick(x, y, button, released);
251
-    } else if (!getConsole().isVisible()) {
252
-        for (int i = forwardAction; i < ActionEventCount; i++) {
253
-            if (keyBindings[i] == button) {
254
-                getGame().handleAction((ActionEvents)i, released);
255
-            }
256
-        }
257
-    }
258
-
259
-    bool mousegrab = !(getMenu().isVisible() || getConsole().isVisible());
260
-    if (mousegrab != getWindow().getMousegrab())
261
-        getWindow().setMousegrab(mousegrab);
262
-}
263
-
264
-void OpenRaider::handleMouseMotion(int xrel, int yrel) {
265
-    assert((xrel != 0) || (yrel != 0));
266
-    assert(mRunning == true);
267
-
268
-    if ((!getConsole().isVisible()) && (!getMenu().isVisible())) {
269
-        getGame().handleMouseMotion(xrel, yrel);
270
-    }
271
-
272
-    bool mousegrab = !(getMenu().isVisible() || getConsole().isVisible());
273
-    if (mousegrab != getWindow().getMousegrab())
274
-        getWindow().setMousegrab(mousegrab);
275
-}
276
-
277
-void OpenRaider::handleMouseScroll(int xrel, int yrel) {
278
-    assert((xrel != 0) || (yrel != 0));
279
-    assert(mRunning == true);
280
-
281
-    if (getMenu().isVisible()) {
282
-        getMenu().handleMouseScroll(xrel, yrel);
283
-    } else if (getConsole().isVisible()) {
284
-        getConsole().handleMouseScroll(xrel, yrel);
285
-    }
286
-
287
-    bool mousegrab = !(getMenu().isVisible() || getConsole().isVisible());
288
-    if (mousegrab != getWindow().getMousegrab())
289
-        getWindow().setMousegrab(mousegrab);
290
-}
291
-

+ 165
- 0
src/UI.cpp 查看文件

@@ -0,0 +1,165 @@
1
+/*!
2
+ * \file src/UI.cpp
3
+ * \brief UI interface manager
4
+ *
5
+ * \author xythobuz
6
+ */
7
+
8
+#include <algorithm>
9
+
10
+#include "global.h"
11
+#include "Console.h"
12
+#include "Menu.h"
13
+#include "OpenRaider.h"
14
+#include "Window.h"
15
+#include "UI.h"
16
+
17
+std::vector<UI*> UI::windows;
18
+
19
+UI::~UI() {
20
+}
21
+
22
+void UI::display() { }
23
+void UI::handleKeyboard(KeyboardButton key, bool pressed) { }
24
+void UI::handleText(char *text, bool notFinished) { }
25
+void UI::handleAction(ActionEvents action, bool isFinished) { }
26
+void UI::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) { }
27
+void UI::handleMouseMotion(int xrel, int yrel) { }
28
+void UI::handleMouseScroll(int xrel, int yrel) { }
29
+
30
+void UI::addWindow(UI* window) {
31
+    windows.push_back(window);
32
+}
33
+
34
+void UI::removeWindow(UI *window) {
35
+    findInList(window, [](unsigned long i){
36
+        windows.erase(windows.begin() + i);
37
+    });
38
+}
39
+
40
+bool UI::compareUIs(UI* a, UI* b) {
41
+    return a->zPos < b->zPos;
42
+}
43
+
44
+bool UI::isOnTop(unsigned long windowID) {
45
+    assert(windowID < windows.size());
46
+    auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
47
+    unsigned long maxPos = (unsigned long)(maxIterator - windows.begin());
48
+    return (maxPos == windowID);
49
+}
50
+
51
+void UI::moveToTop(unsigned long windowID) {
52
+    assert(windowID < windows.size());
53
+
54
+    auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
55
+    long max = (*maxIterator)->zPos;
56
+    unsigned long maxPos = (unsigned long)(maxIterator - windows.begin());
57
+
58
+    if (maxPos != windowID) {
59
+        windows.at(windowID)->zPos = max + 1;
60
+    }
61
+}
62
+
63
+void UI::makeInvisible(unsigned long windowID) {
64
+    assert(windowID < windows.size());
65
+    windows.at(windowID)->zPos = -1;
66
+}
67
+
68
+void UI::findInList(UI *w, std::function<void (unsigned long i)> func) {
69
+    for (unsigned long i = 0; i < windows.size(); i++) {
70
+        auto UIptr = &(*windows.at(i));
71
+        if (w == UIptr) {
72
+            func(i);
73
+            return;
74
+        }
75
+    }
76
+
77
+    assert(false); // called UI was not registered
78
+}
79
+
80
+bool UI::isOnTop() {
81
+    bool top = false;
82
+    findInList(this, [&](unsigned long i) {
83
+        top = UI::isOnTop(i);
84
+    });
85
+    return top;
86
+}
87
+
88
+void UI::moveToTop() {
89
+    findInList(this, [](unsigned long i) {
90
+        UI::moveToTop(i);
91
+    });
92
+}
93
+
94
+void UI::makeInvisible() {
95
+    findInList(this, [](unsigned long i) {
96
+        UI::makeInvisible(i);
97
+    });
98
+}
99
+
100
+void UI::passKeyboard(KeyboardButton key, bool pressed) {
101
+    if (pressed) {
102
+        if (getOpenRaider().keyBindings[menuAction] == key) {
103
+            if (getMenu().isOnTop()) {
104
+                getMenu().makeInvisible();
105
+            } else {
106
+                getMenu().moveToTop();
107
+            }
108
+        } else if (getOpenRaider().keyBindings[consoleAction] == key) {
109
+            if (getConsole().isOnTop()) {
110
+                getConsole().makeInvisible();
111
+            } else {
112
+                getConsole().moveToTop();
113
+            }
114
+        }
115
+    }
116
+
117
+    auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
118
+    (*maxIterator)->handleKeyboard(key, pressed);
119
+
120
+    for (int i = forwardAction; i < ActionEventCount; i++) {
121
+        if (getOpenRaider().keyBindings[i] == key) {
122
+            (*maxIterator)->handleAction((ActionEvents)i, !pressed);
123
+        }
124
+    }
125
+
126
+    bool mousegrab = (*maxIterator)->zPos == 0;
127
+    if (mousegrab != getWindow().getMousegrab())
128
+        getWindow().setMousegrab(mousegrab);
129
+}
130
+
131
+void UI::passText(char *text, bool notFinished) {
132
+    auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
133
+    (*maxIterator)->handleText(text, notFinished);
134
+}
135
+
136
+void UI::passMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) {
137
+    auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
138
+    (*maxIterator)->handleMouseClick(x, y, button, released);
139
+
140
+    for (int i = forwardAction; i < ActionEventCount; i++) {
141
+        if (getOpenRaider().keyBindings[i] == button) {
142
+            (*maxIterator)->handleAction((ActionEvents)i, released);
143
+        }
144
+    }
145
+}
146
+
147
+void UI::passMouseMotion(int xrel, int yrel) {
148
+    auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
149
+    (*maxIterator)->handleMouseMotion(xrel, yrel);
150
+}
151
+
152
+void UI::passMouseScroll(int xrel, int yrel) {
153
+    auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
154
+    (*maxIterator)->handleMouseScroll(xrel, yrel);
155
+}
156
+
157
+void UI::displayInOrder() {
158
+    std::sort(windows.begin(), windows.end(), compareUIs);
159
+    for (auto &x : windows) {
160
+        if (x->zPos >= 0) {
161
+            x->display();
162
+        }
163
+    }
164
+}
165
+

+ 11
- 6
src/WindowSDL.cpp 查看文件

@@ -9,7 +9,7 @@
9 9
 #include <ctime>
10 10
 
11 11
 #include "global.h"
12
-#include "OpenRaider.h"
12
+#include "UI.h"
13 13
 #include "utils/strings.h"
14 14
 #include "WindowSDL.h"
15 15
 
@@ -127,7 +127,7 @@ void WindowSDL::eventHandling() {
127 127
     while(SDL_PollEvent(&event)) {
128 128
         switch (event.type) {
129 129
             case SDL_MOUSEMOTION:
130
-                getOpenRaider().handleMouseMotion(event.motion.xrel, event.motion.yrel);
130
+                UI::passMouseMotion(event.motion.xrel, event.motion.yrel);
131 131
                 break;
132 132
 
133 133
             case SDL_MOUSEBUTTONDOWN:
@@ -145,18 +145,18 @@ void WindowSDL::eventHandling() {
145 145
                     button = fifthmouseKey;
146 146
                 else
147 147
                     button = unknownKey;
148
-                getOpenRaider().handleMouseClick(event.button.x, event.button.y, button, (event.type == SDL_MOUSEBUTTONUP));
148
+                UI::passMouseClick(event.button.x, event.button.y, button, (event.type == SDL_MOUSEBUTTONUP));
149 149
                 break;
150 150
 
151 151
             case SDL_MOUSEWHEEL:
152 152
                 if ((event.wheel.x != 0) || (event.wheel.y != 0))
153
-                    getOpenRaider().handleMouseScroll(event.wheel.x, event.wheel.y);
153
+                    UI::passMouseScroll(event.wheel.x, event.wheel.y);
154 154
                 break;
155 155
 
156 156
             case SDL_TEXTINPUT:
157 157
             case SDL_TEXTEDITING:
158 158
                 if (event.text.text != NULL)
159
-                    getOpenRaider().handleText(event.text.text, (event.type == SDL_TEXTEDITING));
159
+                    UI::passText(event.text.text, (event.type == SDL_TEXTEDITING));
160 160
                 break;
161 161
 
162 162
             case SDL_KEYDOWN:
@@ -427,7 +427,7 @@ void WindowSDL::eventHandling() {
427 427
                         break;
428 428
 
429 429
                 }
430
-                getOpenRaider().handleKeyboard(key, (event.type == SDL_KEYDOWN));
430
+                UI::passKeyboard(key, (event.type == SDL_KEYDOWN));
431 431
                 break;
432 432
 
433 433
             case SDL_WINDOWEVENT:
@@ -451,6 +451,11 @@ void WindowSDL::setTextInput(bool on) {
451 451
         SDL_StopTextInput();
452 452
 }
453 453
 
454
+bool WindowSDL::getTextInput() {
455
+    assert(mInit == true);
456
+    return mTextInput;
457
+}
458
+
454 459
 void WindowSDL::delay(unsigned int ms) {
455 460
     assert(mInit == true);
456 461
 

+ 20
- 20
src/commands/CommandEngine.cpp 查看文件

@@ -50,7 +50,7 @@ std::string CommandScreenshot::brief() {
50 50
 
51 51
 void CommandScreenshot::printHelp() {
52 52
     getConsole() << "sshot-Command Usage:" << Console::endl;
53
-    getConsole() << "  sshot [console|menu]" << Console::endl;
53
+    getConsole() << "  sshot [console|menu] [console|menu]" << Console::endl;
54 54
     getConsole() << "Add console/menu to capture them too" << Console::endl;
55 55
 }
56 56
 
@@ -65,28 +65,28 @@ int CommandScreenshot::execute(std::istream& args) {
65 65
     filename += VERSION_SHORT;
66 66
 
67 67
     bool console = false, menu = false;
68
-    std::string temp;
69
-    args >> temp;
70
-    if (temp.compare("console") == 0)
71
-        console = true;
72
-    if (temp.compare("menu") == 0)
73
-        menu = true;
74
-
75
-    if (!console) {
76
-        getConsole().setVisible(false);
77
-        if (menu)
78
-            getMenu().setVisible(true);
79
-        getOpenRaider().frame();
80
-        getOpenRaider().frame(); // Double buffered
81
-    }
68
+    std::string temp, temp2;
69
+    args >> temp >> temp2;
70
+
71
+    getConsole().makeInvisible();
72
+    getMenu().makeInvisible();
73
+
74
+    if (temp == "console")
75
+        getConsole().moveToTop();
76
+    else if (temp == "menu")
77
+        getMenu().moveToTop();
82 78
 
79
+    if (temp2 == "console")
80
+        getConsole().moveToTop();
81
+    else if (temp2 == "menu")
82
+        getMenu().moveToTop();
83
+
84
+    getOpenRaider().frame();
85
+    getOpenRaider().frame(); // Double buffered
83 86
     getRender().screenShot(filename.c_str());
84 87
 
85
-    if (!console) {
86
-        getConsole().setVisible(true);
87
-        if (menu)
88
-            getMenu().setVisible(false);
89
-    }
88
+    getMenu().makeInvisible();
89
+    getConsole().moveToTop();
90 90
 
91 91
     getConsole() << "Screenshot stored..." << Console::endl;
92 92
     return 0;

正在加载...
取消
保存