mirror of https://github.com/OpenRCT2/OpenRCT2.git
clang-format UI root
This commit is contained in:
parent
e558660860
commit
9c022606f1
|
@ -7,9 +7,10 @@
|
|||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <openrct2/interface/Cursors.h>
|
||||
#include "CursorRepository.h"
|
||||
|
||||
#include <openrct2/interface/Cursors.h>
|
||||
|
||||
// clang-format off
|
||||
namespace OpenRCT2::Ui
|
||||
{
|
||||
|
|
|
@ -7,15 +7,14 @@
|
|||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <cmath>
|
||||
#include "CursorRepository.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <openrct2/common.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/core/Guard.hpp>
|
||||
#include <openrct2/interface/Cursors.h>
|
||||
|
||||
#include "CursorRepository.h"
|
||||
|
||||
using namespace OpenRCT2::Ui;
|
||||
|
||||
CursorRepository::~CursorRepository()
|
||||
|
@ -40,25 +39,25 @@ void CursorRepository::SetCurrentCursor(CURSOR_ID cursorId)
|
|||
{
|
||||
if (_currentCursor != cursorId)
|
||||
{
|
||||
SDL_Cursor * cursor = _scaledCursors.at(_currentCursorScale).getScaledCursor(cursorId);
|
||||
SDL_Cursor* cursor = _scaledCursors.at(_currentCursorScale).getScaledCursor(cursorId);
|
||||
SDL_SetCursor(cursor);
|
||||
_currentCursor = cursorId;
|
||||
}
|
||||
}
|
||||
|
||||
static bool getBit(const uint8_t * data, size_t x, size_t y, size_t width)
|
||||
static bool getBit(const uint8_t* data, size_t x, size_t y, size_t width)
|
||||
{
|
||||
size_t position = y * width + x;
|
||||
return (data[position / 8] & (1 << (7 - (x % 8)))) != 0;
|
||||
}
|
||||
|
||||
static void setBit(uint8_t * data, size_t x, size_t y, size_t width)
|
||||
static void setBit(uint8_t* data, size_t x, size_t y, size_t width)
|
||||
{
|
||||
size_t position = y * width + x;
|
||||
data[position / 8] |= (1 << (7 - (position % 8)));
|
||||
}
|
||||
|
||||
static void drawRect(uint8_t * data, size_t x, size_t y, size_t width, size_t scale)
|
||||
static void drawRect(uint8_t* data, size_t x, size_t y, size_t width, size_t scale)
|
||||
{
|
||||
for (size_t outY = (y * scale); outY < ((1 + y) * scale); outY++)
|
||||
{
|
||||
|
@ -69,17 +68,18 @@ static void drawRect(uint8_t * data, size_t x, size_t y, size_t width, size_t sc
|
|||
}
|
||||
}
|
||||
|
||||
static uint8_t * scaleDataArray(const uint8_t data[], size_t width, size_t height, size_t scale)
|
||||
static uint8_t* scaleDataArray(const uint8_t data[], size_t width, size_t height, size_t scale)
|
||||
{
|
||||
size_t length = width * height;
|
||||
auto * ret = static_cast<uint8_t *>(calloc(sizeof(uint8_t), length * scale * scale));
|
||||
auto* ret = static_cast<uint8_t*>(calloc(sizeof(uint8_t), length * scale * scale));
|
||||
|
||||
for (size_t y = 0; y < height * 8; y++)
|
||||
{
|
||||
for (size_t x = 0; x < width; x++)
|
||||
{
|
||||
bool value = getBit(data, x, y, width);
|
||||
if (!value) continue;
|
||||
if (!value)
|
||||
continue;
|
||||
|
||||
drawRect(ret, x, y, width, scale);
|
||||
}
|
||||
|
@ -88,27 +88,26 @@ static uint8_t * scaleDataArray(const uint8_t data[], size_t width, size_t heigh
|
|||
return ret;
|
||||
}
|
||||
|
||||
SDL_Cursor * CursorRepository::Create(const CursorData * cursorInfo, uint8_t scale)
|
||||
SDL_Cursor* CursorRepository::Create(const CursorData* cursorInfo, uint8_t scale)
|
||||
{
|
||||
SDL_Cursor * cursor;
|
||||
SDL_Cursor* cursor;
|
||||
|
||||
auto integer_scale = (int) round(scale);
|
||||
auto integer_scale = (int)round(scale);
|
||||
|
||||
auto data = scaleDataArray(cursorInfo->Data, CURSOR_BIT_WIDTH, CURSOR_HEIGHT, static_cast<size_t>(integer_scale));
|
||||
auto mask = scaleDataArray(cursorInfo->Mask, CURSOR_BIT_WIDTH, CURSOR_HEIGHT, static_cast<size_t>(integer_scale));
|
||||
|
||||
cursor = SDL_CreateCursor(
|
||||
data,
|
||||
mask,
|
||||
BASE_CURSOR_WIDTH * integer_scale,
|
||||
BASE_CURSOR_HEIGHT * integer_scale,
|
||||
cursorInfo->HotSpot.X * integer_scale,
|
||||
cursorInfo->HotSpot.Y * integer_scale);
|
||||
data,
|
||||
mask,
|
||||
BASE_CURSOR_WIDTH * integer_scale,
|
||||
BASE_CURSOR_HEIGHT * integer_scale,
|
||||
cursorInfo->HotSpot.X * integer_scale,
|
||||
cursorInfo->HotSpot.Y * integer_scale);
|
||||
|
||||
free(data);
|
||||
free(mask);
|
||||
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
@ -125,8 +124,7 @@ void CursorRepository::GenerateScaledCursorSetHolder(uint8_t scale)
|
|||
{
|
||||
if (_scaledCursors.find(scale) == _scaledCursors.end())
|
||||
{
|
||||
std::function<SDL_Cursor *(CURSOR_ID)> cursorGenerator = [this, scale](CURSOR_ID cursorId)
|
||||
{
|
||||
std::function<SDL_Cursor*(CURSOR_ID)> cursorGenerator = [this, scale](CURSOR_ID cursorId) {
|
||||
switch (cursorId)
|
||||
{
|
||||
// We can't scale the system cursors, but they should be appropriately scaled anyway
|
||||
|
|
|
@ -9,11 +9,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <openrct2/interface/Cursors.h>
|
||||
|
||||
struct SDL_Cursor;
|
||||
|
@ -26,9 +24,10 @@ namespace OpenRCT2::Ui
|
|||
class CursorSetHolder
|
||||
{
|
||||
private:
|
||||
SDL_Cursor * _cursors[CURSOR_COUNT] = {nullptr};
|
||||
SDL_Cursor* _cursors[CURSOR_COUNT] = { nullptr };
|
||||
|
||||
public:
|
||||
CursorSetHolder(const std::function<SDL_Cursor *(CURSOR_ID)> & getCursor)
|
||||
CursorSetHolder(const std::function<SDL_Cursor*(CURSOR_ID)>& getCursor)
|
||||
{
|
||||
for (size_t i = 0; i < CURSOR_COUNT; i++)
|
||||
{
|
||||
|
@ -44,16 +43,16 @@ namespace OpenRCT2::Ui
|
|||
}
|
||||
}
|
||||
|
||||
SDL_Cursor * getScaledCursor(CURSOR_ID cursorId)
|
||||
SDL_Cursor* getScaledCursor(CURSOR_ID cursorId)
|
||||
{
|
||||
return _cursors[cursorId];
|
||||
}
|
||||
};
|
||||
|
||||
constexpr static int32_t BASE_CURSOR_WIDTH = 32;
|
||||
constexpr static int32_t BASE_CURSOR_WIDTH = 32;
|
||||
constexpr static int32_t BASE_CURSOR_HEIGHT = 32;
|
||||
|
||||
CURSOR_ID _currentCursor = CURSOR_UNDEFINED;
|
||||
CURSOR_ID _currentCursor = CURSOR_UNDEFINED;
|
||||
uint8_t _currentCursorScale = 1;
|
||||
|
||||
std::map<uint8_t, CursorSetHolder> _scaledCursors;
|
||||
|
@ -66,8 +65,8 @@ namespace OpenRCT2::Ui
|
|||
void SetCursorScale(uint8_t cursorScale);
|
||||
|
||||
private:
|
||||
SDL_Cursor * Create(const CursorData * cursorInfo, uint8_t scale);
|
||||
SDL_Cursor* Create(const CursorData* cursorInfo, uint8_t scale);
|
||||
void GenerateScaledCursorSetHolder(uint8_t scale);
|
||||
static const CursorData * GetCursorData(CURSOR_ID cursorId);
|
||||
static const CursorData* GetCursorData(CURSOR_ID cursorId);
|
||||
};
|
||||
}
|
||||
} // namespace OpenRCT2::Ui
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
SDL_GetError();
|
||||
}
|
||||
|
||||
explicit SDLException(const char * message)
|
||||
explicit SDLException(const char* message)
|
||||
: runtime_error(message)
|
||||
{
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public:
|
|||
* Throws an SDL exception with a message containing the given call information
|
||||
* and the message given by SDL_GetError.
|
||||
*/
|
||||
static void Throw(const char * call)
|
||||
static void Throw(const char* call)
|
||||
{
|
||||
std::string message = std::string(call) + ": " + std::string(SDL_GetError());
|
||||
throw SDLException(message);
|
||||
|
|
|
@ -7,24 +7,25 @@
|
|||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <openrct2/common.h>
|
||||
#include "TextComposition.h"
|
||||
|
||||
#include "UiContext.h"
|
||||
#include "interface/InGameConsole.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <openrct2-ui/interface/Window.h>
|
||||
#include <openrct2/common.h>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include "TextComposition.h"
|
||||
|
||||
#include <openrct2/interface/InteractiveConsole.h>
|
||||
#include <openrct2-ui/interface/Window.h>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
#include "interface/InGameConsole.h"
|
||||
#include "UiContext.h"
|
||||
|
||||
#ifdef __MACOSX__
|
||||
// macOS uses COMMAND rather than CTRL for many keyboard shortcuts
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_GUI
|
||||
// macOS uses COMMAND rather than CTRL for many keyboard shortcuts
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_GUI
|
||||
#else
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_CTRL
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_CTRL
|
||||
#endif
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
@ -35,7 +36,7 @@ bool TextComposition::IsActive()
|
|||
return SDL_IsTextInputActive() && _session.Buffer != nullptr;
|
||||
}
|
||||
|
||||
TextInputSession * TextComposition::Start(utf8 * buffer, size_t bufferSize)
|
||||
TextInputSession* TextComposition::Start(utf8* buffer, size_t bufferSize)
|
||||
{
|
||||
Guard::ArgumentNotNull(buffer);
|
||||
|
||||
|
@ -62,126 +63,129 @@ void TextComposition::Stop()
|
|||
_imeActive = false;
|
||||
}
|
||||
|
||||
void TextComposition::HandleMessage(const SDL_Event * e)
|
||||
void TextComposition::HandleMessage(const SDL_Event* e)
|
||||
{
|
||||
auto& console = GetInGameConsole();
|
||||
|
||||
switch (e->type) {
|
||||
case SDL_TEXTEDITING:
|
||||
// When inputting Korean characters, `edit.length` is always zero
|
||||
String::Set(_imeBuffer, sizeof(_imeBuffer), e->edit.text);
|
||||
_imeStart = e->edit.start;
|
||||
_imeLength = e->edit.length;
|
||||
_imeActive = ((e->edit.length != 0 || String::SizeOf(e->edit.text) != 0) && _imeBuffer[0] != '\0');
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
// will receive an `SDL_TEXTINPUT` event when a composition is committed
|
||||
_imeActive = false;
|
||||
_imeBuffer[0] = '\0';
|
||||
if (_session.Buffer != nullptr)
|
||||
{
|
||||
// HACK ` will close console, so don't input any text
|
||||
if (e->text.text[0] == '`' && console.IsOpen()) {
|
||||
break;
|
||||
}
|
||||
|
||||
utf8 * newText = String::Duplicate(e->text.text);
|
||||
utf8_remove_formatting(newText, false);
|
||||
Insert(newText);
|
||||
Memory::Free(newText);
|
||||
|
||||
console.RefreshCaret();
|
||||
window_update_textbox();
|
||||
}
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
switch (e->type)
|
||||
{
|
||||
if (_imeActive)
|
||||
{
|
||||
case SDL_TEXTEDITING:
|
||||
// When inputting Korean characters, `edit.length` is always zero
|
||||
String::Set(_imeBuffer, sizeof(_imeBuffer), e->edit.text);
|
||||
_imeStart = e->edit.start;
|
||||
_imeLength = e->edit.length;
|
||||
_imeActive = ((e->edit.length != 0 || String::SizeOf(e->edit.text) != 0) && _imeBuffer[0] != '\0');
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t modifier = e->key.keysym.mod;
|
||||
SDL_Keycode key = e->key.keysym.sym;
|
||||
if (key == SDLK_KP_ENTER)
|
||||
{
|
||||
// Map Keypad enter to regular enter.
|
||||
key = SDLK_RETURN;
|
||||
}
|
||||
|
||||
GetContext()->GetUiContext()->SetKeysPressed(key, e->key.keysym.scancode);
|
||||
|
||||
// Text input
|
||||
if (_session.Buffer == nullptr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear the input on <CTRL>Backspace (Windows/Linux) or <MOD>Backspace (macOS)
|
||||
if (key == SDLK_BACKSPACE && (modifier & KEYBOARD_PRIMARY_MODIFIER))
|
||||
{
|
||||
Clear();
|
||||
console.RefreshCaret();
|
||||
window_update_textbox();
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case SDLK_BACKSPACE:
|
||||
// If backspace and we have input text with a cursor position nonzero
|
||||
if (_session.SelectionStart > 0)
|
||||
case SDL_TEXTINPUT:
|
||||
// will receive an `SDL_TEXTINPUT` event when a composition is committed
|
||||
_imeActive = false;
|
||||
_imeBuffer[0] = '\0';
|
||||
if (_session.Buffer != nullptr)
|
||||
{
|
||||
size_t endOffset = _session.SelectionStart;
|
||||
CursorLeft();
|
||||
_session.SelectionSize = endOffset - _session.SelectionStart;
|
||||
Delete();
|
||||
// HACK ` will close console, so don't input any text
|
||||
if (e->text.text[0] == '`' && console.IsOpen())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
utf8* newText = String::Duplicate(e->text.text);
|
||||
utf8_remove_formatting(newText, false);
|
||||
Insert(newText);
|
||||
Memory::Free(newText);
|
||||
|
||||
console.RefreshCaret();
|
||||
window_update_textbox();
|
||||
}
|
||||
break;
|
||||
case SDLK_HOME:
|
||||
CursorHome();
|
||||
console.RefreshCaret();
|
||||
break;
|
||||
case SDLK_END:
|
||||
CursorEnd();
|
||||
console.RefreshCaret();
|
||||
break;
|
||||
case SDLK_DELETE:
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
size_t startOffset = _session.SelectionStart;
|
||||
CursorRight();
|
||||
_session.SelectionSize = _session.SelectionStart - startOffset;
|
||||
_session.SelectionStart = startOffset;
|
||||
Delete();
|
||||
console.RefreshCaret();
|
||||
window_update_textbox();
|
||||
break;
|
||||
}
|
||||
case SDLK_RETURN:
|
||||
window_cancel_textbox();
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
CursorLeft();
|
||||
console.RefreshCaret();
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
CursorRight();
|
||||
console.RefreshCaret();
|
||||
break;
|
||||
case SDLK_v:
|
||||
if ((modifier & KEYBOARD_PRIMARY_MODIFIER) && SDL_HasClipboardText())
|
||||
if (_imeActive)
|
||||
{
|
||||
utf8 * text = SDL_GetClipboardText();
|
||||
utf8_remove_formatting(text, false);
|
||||
Insert(text);
|
||||
SDL_free(text);
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t modifier = e->key.keysym.mod;
|
||||
SDL_Keycode key = e->key.keysym.sym;
|
||||
if (key == SDLK_KP_ENTER)
|
||||
{
|
||||
// Map Keypad enter to regular enter.
|
||||
key = SDLK_RETURN;
|
||||
}
|
||||
|
||||
GetContext()->GetUiContext()->SetKeysPressed(key, e->key.keysym.scancode);
|
||||
|
||||
// Text input
|
||||
if (_session.Buffer == nullptr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear the input on <CTRL>Backspace (Windows/Linux) or <MOD>Backspace (macOS)
|
||||
if (key == SDLK_BACKSPACE && (modifier & KEYBOARD_PRIMARY_MODIFIER))
|
||||
{
|
||||
Clear();
|
||||
console.RefreshCaret();
|
||||
window_update_textbox();
|
||||
}
|
||||
break;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case SDLK_BACKSPACE:
|
||||
// If backspace and we have input text with a cursor position nonzero
|
||||
if (_session.SelectionStart > 0)
|
||||
{
|
||||
size_t endOffset = _session.SelectionStart;
|
||||
CursorLeft();
|
||||
_session.SelectionSize = endOffset - _session.SelectionStart;
|
||||
Delete();
|
||||
|
||||
console.RefreshCaret();
|
||||
window_update_textbox();
|
||||
}
|
||||
break;
|
||||
case SDLK_HOME:
|
||||
CursorHome();
|
||||
console.RefreshCaret();
|
||||
break;
|
||||
case SDLK_END:
|
||||
CursorEnd();
|
||||
console.RefreshCaret();
|
||||
break;
|
||||
case SDLK_DELETE:
|
||||
{
|
||||
size_t startOffset = _session.SelectionStart;
|
||||
CursorRight();
|
||||
_session.SelectionSize = _session.SelectionStart - startOffset;
|
||||
_session.SelectionStart = startOffset;
|
||||
Delete();
|
||||
console.RefreshCaret();
|
||||
window_update_textbox();
|
||||
break;
|
||||
}
|
||||
case SDLK_RETURN:
|
||||
window_cancel_textbox();
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
CursorLeft();
|
||||
console.RefreshCaret();
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
CursorRight();
|
||||
console.RefreshCaret();
|
||||
break;
|
||||
case SDLK_v:
|
||||
if ((modifier & KEYBOARD_PRIMARY_MODIFIER) && SDL_HasClipboardText())
|
||||
{
|
||||
utf8* text = SDL_GetClipboardText();
|
||||
utf8_remove_formatting(text, false);
|
||||
Insert(text);
|
||||
SDL_free(text);
|
||||
window_update_textbox();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextComposition::CursorHome()
|
||||
|
@ -192,7 +196,7 @@ void TextComposition::CursorHome()
|
|||
void TextComposition::CursorEnd()
|
||||
{
|
||||
size_t selectionOffset = _session.Size;
|
||||
const utf8 * ch = _session.Buffer + _session.SelectionStart;
|
||||
const utf8* ch = _session.Buffer + _session.SelectionStart;
|
||||
while (!utf8_is_codepoint_start(ch) && selectionOffset > 0)
|
||||
{
|
||||
ch--;
|
||||
|
@ -207,13 +211,12 @@ void TextComposition::CursorLeft()
|
|||
size_t selectionOffset = _session.SelectionStart;
|
||||
if (selectionOffset > 0)
|
||||
{
|
||||
const utf8 * ch = _session.Buffer + selectionOffset;
|
||||
const utf8* ch = _session.Buffer + selectionOffset;
|
||||
do
|
||||
{
|
||||
ch--;
|
||||
selectionOffset--;
|
||||
}
|
||||
while (!utf8_is_codepoint_start(ch) && selectionOffset > 0);
|
||||
} while (!utf8_is_codepoint_start(ch) && selectionOffset > 0);
|
||||
|
||||
_session.SelectionStart = selectionOffset;
|
||||
}
|
||||
|
@ -225,22 +228,21 @@ void TextComposition::CursorRight()
|
|||
size_t selectionMaxOffset = _session.Size;
|
||||
if (selectionOffset < selectionMaxOffset)
|
||||
{
|
||||
const utf8 * ch = _session.Buffer + _session.SelectionStart;
|
||||
const utf8* ch = _session.Buffer + _session.SelectionStart;
|
||||
do
|
||||
{
|
||||
ch++;
|
||||
selectionOffset++;
|
||||
}
|
||||
while (!utf8_is_codepoint_start(ch) && selectionOffset < selectionMaxOffset);
|
||||
} while (!utf8_is_codepoint_start(ch) && selectionOffset < selectionMaxOffset);
|
||||
|
||||
_session.SelectionSize = std::max<size_t>(0, _session.SelectionSize - (selectionOffset - _session.SelectionStart));
|
||||
_session.SelectionStart = selectionOffset;
|
||||
}
|
||||
}
|
||||
|
||||
void TextComposition::Insert(const utf8 * text)
|
||||
void TextComposition::Insert(const utf8* text)
|
||||
{
|
||||
const utf8 * ch = text;
|
||||
const utf8* ch = text;
|
||||
uint32_t codepoint;
|
||||
while ((codepoint = utf8_get_next(ch, &ch)) != 0)
|
||||
{
|
||||
|
@ -254,12 +256,12 @@ void TextComposition::InsertCodepoint(codepoint_t codepoint)
|
|||
size_t remainingSize = _session.BufferSize - _session.Size;
|
||||
if (codepointLength <= remainingSize)
|
||||
{
|
||||
utf8 * buffer = _session.Buffer;
|
||||
utf8 * insertPtr = buffer + _session.SelectionStart;
|
||||
utf8* buffer = _session.Buffer;
|
||||
utf8* insertPtr = buffer + _session.SelectionStart;
|
||||
if (_session.SelectionStart < _session.Size)
|
||||
{
|
||||
// Shift bytes (including null terminator) right to make room for new codepoint
|
||||
utf8 * targetShiftPtr = insertPtr + codepointLength;
|
||||
utf8* targetShiftPtr = insertPtr + codepointLength;
|
||||
size_t shiftSize = _session.Size - _session.SelectionStart + 1;
|
||||
memmove(targetShiftPtr, insertPtr, shiftSize);
|
||||
}
|
||||
|
@ -278,7 +280,7 @@ void TextComposition::InsertCodepoint(codepoint_t codepoint)
|
|||
|
||||
void TextComposition::Clear()
|
||||
{
|
||||
utf8 * buffer = _session.Buffer;
|
||||
utf8* buffer = _session.Buffer;
|
||||
buffer[0] = 0;
|
||||
_session.Size = 0;
|
||||
_session.Length = 0;
|
||||
|
@ -292,21 +294,21 @@ void TextComposition::Delete()
|
|||
size_t selectionMaxOffset = _session.Size;
|
||||
|
||||
// Find out how many bytes to delete.
|
||||
const utf8 * ch = _session.Buffer + _session.SelectionStart;
|
||||
const utf8* ch = _session.Buffer + _session.SelectionStart;
|
||||
do
|
||||
{
|
||||
ch++;
|
||||
selectionOffset++;
|
||||
}
|
||||
while (!utf8_is_codepoint_start(ch) && selectionOffset < selectionMaxOffset);
|
||||
} while (!utf8_is_codepoint_start(ch) && selectionOffset < selectionMaxOffset);
|
||||
|
||||
utf8 * buffer = _session.Buffer;
|
||||
utf8 * targetShiftPtr = buffer + _session.SelectionStart;
|
||||
utf8 * sourceShiftPtr = targetShiftPtr + _session.SelectionSize;
|
||||
utf8* buffer = _session.Buffer;
|
||||
utf8* targetShiftPtr = buffer + _session.SelectionStart;
|
||||
utf8* sourceShiftPtr = targetShiftPtr + _session.SelectionSize;
|
||||
size_t bytesToSkip = selectionOffset - _session.SelectionStart;
|
||||
|
||||
// std::min() is used to ensure that shiftSize doesn't underflow; it should be between 0 and _session.Size
|
||||
size_t shiftSize = _session.Size - std::min(_session.Size, (_session.SelectionStart - _session.SelectionSize + bytesToSkip));
|
||||
size_t shiftSize
|
||||
= _session.Size - std::min(_session.Size, (_session.SelectionStart - _session.SelectionSize + bytesToSkip));
|
||||
memmove(targetShiftPtr, sourceShiftPtr, shiftSize);
|
||||
_session.SelectionSize = 0;
|
||||
RecalculateLength();
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <openrct2/common.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/common.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
|
||||
union SDL_Event;
|
||||
|
@ -25,26 +25,26 @@ namespace OpenRCT2::Ui
|
|||
private:
|
||||
TextInputSession _session = {};
|
||||
|
||||
bool _imeActive = false;
|
||||
int32_t _imeStart = 0;
|
||||
int32_t _imeLength = 0;
|
||||
utf8 _imeBuffer[32] = {};
|
||||
bool _imeActive = false;
|
||||
int32_t _imeStart = 0;
|
||||
int32_t _imeLength = 0;
|
||||
utf8 _imeBuffer[32] = {};
|
||||
|
||||
public:
|
||||
bool IsActive();
|
||||
TextInputSession * Start(utf8 * buffer, size_t bufferSize);
|
||||
TextInputSession* Start(utf8* buffer, size_t bufferSize);
|
||||
void Stop();
|
||||
void HandleMessage(const SDL_Event * e);
|
||||
void HandleMessage(const SDL_Event* e);
|
||||
|
||||
private:
|
||||
void CursorHome();
|
||||
void CursorEnd();
|
||||
void CursorLeft();
|
||||
void CursorRight();
|
||||
void Insert(const utf8 * text);
|
||||
void Insert(const utf8* text);
|
||||
void InsertCodepoint(codepoint_t codepoint);
|
||||
void Clear();
|
||||
void Delete();
|
||||
void RecalculateLength();
|
||||
};
|
||||
}
|
||||
} // namespace OpenRCT2::Ui
|
||||
|
|
|
@ -7,24 +7,24 @@
|
|||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <openrct2/audio/AudioContext.h>
|
||||
#include "Ui.h"
|
||||
|
||||
#include "UiContext.h"
|
||||
#include "audio/AudioContext.h"
|
||||
#include "drawing/BitmapReader.h"
|
||||
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/OpenRCT2.h>
|
||||
#include <openrct2/PlatformEnvironment.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
#include "audio/AudioContext.h"
|
||||
#include "drawing/BitmapReader.h"
|
||||
#include "Ui.h"
|
||||
#include "UiContext.h"
|
||||
|
||||
#include <openrct2/audio/AudioContext.h>
|
||||
#include <openrct2/platform/platform.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
using namespace OpenRCT2::Audio;
|
||||
using namespace OpenRCT2::Ui;
|
||||
|
||||
template<typename T>
|
||||
static std::shared_ptr<T> to_shared(std::unique_ptr<T>&& src)
|
||||
template<typename T> static std::shared_ptr<T> to_shared(std::unique_ptr<T>&& src)
|
||||
{
|
||||
return std::shared_ptr<T>(std::move(src));
|
||||
}
|
||||
|
@ -33,9 +33,9 @@ static std::shared_ptr<T> to_shared(std::unique_ptr<T>&& src)
|
|||
* Main entry point for non-Windows systems. Windows instead uses its own DLL proxy.
|
||||
*/
|
||||
#if defined(_MSC_VER) && !defined(__DISABLE_DLL_PROXY__)
|
||||
int NormalisedMain(int argc, const char * * argv)
|
||||
int NormalisedMain(int argc, const char** argv)
|
||||
#else
|
||||
int main(int argc, const char * * argv)
|
||||
int main(int argc, const char** argv)
|
||||
#endif
|
||||
{
|
||||
int runGame = cmdline_run(argv, argc);
|
||||
|
@ -63,10 +63,9 @@ int main(int argc, const char * * argv)
|
|||
return gExitCode;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __ANDROID__
|
||||
extern "C" {
|
||||
int SDL_main(int argc, const char *argv[])
|
||||
int SDL_main(int argc, const char* argv[])
|
||||
{
|
||||
return main(argc, argv);
|
||||
}
|
||||
|
|
|
@ -8,5 +8,5 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
int NormalisedMain(int argc, const char * * argv);
|
||||
int NormalisedMain(int argc, const char** argv);
|
||||
#endif
|
||||
|
|
|
@ -9,29 +9,27 @@
|
|||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <openrct2/common.h>
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
#include "UiContext.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <dlfcn.h>
|
||||
#include <openrct2/common.h>
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace OpenRCT2::Ui
|
||||
{
|
||||
|
||||
class AndroidContext final : public IPlatformUiContext
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
AndroidContext()
|
||||
{
|
||||
}
|
||||
|
||||
void SetWindowIcon(SDL_Window * window) override
|
||||
void SetWindowIcon(SDL_Window* window) override
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -40,21 +38,21 @@ namespace OpenRCT2::Ui
|
|||
return false;
|
||||
}
|
||||
|
||||
void ShowMessageBox(SDL_Window * window, const std::string &message) override
|
||||
void ShowMessageBox(SDL_Window* window, const std::string& message) override
|
||||
{
|
||||
log_verbose(message.c_str());
|
||||
|
||||
STUB();
|
||||
}
|
||||
|
||||
std::string ShowFileDialog(SDL_Window * window, const FileDialogDesc &desc) override
|
||||
std::string ShowFileDialog(SDL_Window* window, const FileDialogDesc& desc) override
|
||||
{
|
||||
STUB();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string ShowDirectoryDialog(SDL_Window * window, const std::string &title) override
|
||||
std::string ShowDirectoryDialog(SDL_Window* window, const std::string& title) override
|
||||
{
|
||||
log_info(title.c_str());
|
||||
STUB();
|
||||
|
@ -63,10 +61,10 @@ namespace OpenRCT2::Ui
|
|||
}
|
||||
};
|
||||
|
||||
IPlatformUiContext * CreatePlatformUiContext()
|
||||
IPlatformUiContext* CreatePlatformUiContext()
|
||||
{
|
||||
return new AndroidContext();
|
||||
}
|
||||
}
|
||||
} // namespace OpenRCT2::Ui
|
||||
|
||||
#endif // __ANDROID__
|
||||
|
|
|
@ -9,18 +9,17 @@
|
|||
|
||||
#if (defined(__linux__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__)) && !defined(__ANDROID__)
|
||||
|
||||
#include "UiContext.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <openrct2/common.h>
|
||||
#include <openrct2/core/Path.hpp>
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
#include "UiContext.h"
|
||||
|
||||
|
||||
#include <SDL.h>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace OpenRCT2::Ui
|
||||
{
|
||||
|
@ -34,13 +33,12 @@ namespace OpenRCT2::Ui
|
|||
class LinuxContext final : public IPlatformUiContext
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
LinuxContext()
|
||||
{
|
||||
}
|
||||
|
||||
void SetWindowIcon(SDL_Window * window) override
|
||||
void SetWindowIcon(SDL_Window* window) override
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -50,25 +48,25 @@ namespace OpenRCT2::Ui
|
|||
// See http://syprog.blogspot.ru/2011/12/listing-loaded-shared-objects-in-linux.html
|
||||
struct lmap
|
||||
{
|
||||
void * base_address;
|
||||
char * path;
|
||||
void * unused;
|
||||
lmap * next;
|
||||
lmap * prev;
|
||||
void* base_address;
|
||||
char* path;
|
||||
void* unused;
|
||||
lmap* next;
|
||||
lmap* prev;
|
||||
};
|
||||
|
||||
struct dummy
|
||||
{
|
||||
void * pointers[3];
|
||||
dummy * ptr;
|
||||
void* pointers[3];
|
||||
dummy* ptr;
|
||||
};
|
||||
|
||||
bool result = false;
|
||||
void * processHandle = dlopen(nullptr, RTLD_NOW);
|
||||
void* processHandle = dlopen(nullptr, RTLD_NOW);
|
||||
if (processHandle != nullptr)
|
||||
{
|
||||
dummy * p = ((dummy *)processHandle)->ptr;
|
||||
lmap * pl = (lmap *)p->ptr;
|
||||
dummy* p = ((dummy*)processHandle)->ptr;
|
||||
lmap* pl = (lmap*)p->ptr;
|
||||
while (pl != nullptr)
|
||||
{
|
||||
if (strstr(pl->path, "gameoverlayrenderer.so") != nullptr)
|
||||
|
@ -86,115 +84,121 @@ namespace OpenRCT2::Ui
|
|||
#endif
|
||||
}
|
||||
|
||||
void ShowMessageBox(SDL_Window * window, const std::string &message) override
|
||||
void ShowMessageBox(SDL_Window* window, const std::string& message) override
|
||||
{
|
||||
log_verbose(message.c_str());
|
||||
|
||||
std::string executablePath;
|
||||
DIALOG_TYPE dtype = GetDialogApp(&executablePath);
|
||||
|
||||
switch (dtype) {
|
||||
case DIALOG_TYPE::KDIALOG:
|
||||
switch (dtype)
|
||||
{
|
||||
std::string cmd = String::Format("%s --title \"OpenRCT2\" --msgbox \"%s\"", executablePath.c_str(), message.c_str());
|
||||
Execute(cmd);
|
||||
break;
|
||||
}
|
||||
case DIALOG_TYPE::ZENITY:
|
||||
{
|
||||
std::string cmd = String::Format("%s --title=\"OpenRCT2\" --info --text=\"%s\"", executablePath.c_str(), message.c_str());
|
||||
Execute(cmd);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "OpenRCT2", message.c_str(), window);
|
||||
break;
|
||||
case DIALOG_TYPE::KDIALOG:
|
||||
{
|
||||
std::string cmd
|
||||
= String::Format("%s --title \"OpenRCT2\" --msgbox \"%s\"", executablePath.c_str(), message.c_str());
|
||||
Execute(cmd);
|
||||
break;
|
||||
}
|
||||
case DIALOG_TYPE::ZENITY:
|
||||
{
|
||||
std::string cmd = String::Format(
|
||||
"%s --title=\"OpenRCT2\" --info --text=\"%s\"", executablePath.c_str(), message.c_str());
|
||||
Execute(cmd);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "OpenRCT2", message.c_str(), window);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ShowFileDialog(SDL_Window * window, const FileDialogDesc &desc) override
|
||||
std::string ShowFileDialog(SDL_Window* window, const FileDialogDesc& desc) override
|
||||
{
|
||||
std::string result;
|
||||
std::string executablePath;
|
||||
DIALOG_TYPE dtype = GetDialogApp(&executablePath);
|
||||
switch (dtype) {
|
||||
case DIALOG_TYPE::KDIALOG:
|
||||
switch (dtype)
|
||||
{
|
||||
std::string action =
|
||||
(desc.Type == FILE_DIALOG_TYPE::OPEN) ? "--getopenfilename" :
|
||||
"--getsavefilename";
|
||||
std::string filter = GetKDialogFilterString(desc.Filters);
|
||||
std::string cmd = String::StdFormat("%s --title '%s' %s '%s' '%s'",
|
||||
executablePath.c_str(),
|
||||
desc.Title.c_str(),
|
||||
action.c_str(),
|
||||
desc.InitialDirectory.c_str(),
|
||||
filter.c_str());
|
||||
std::string output;
|
||||
if (Execute(cmd, &output) == 0)
|
||||
case DIALOG_TYPE::KDIALOG:
|
||||
{
|
||||
result = output;
|
||||
std::string action = (desc.Type == FILE_DIALOG_TYPE::OPEN) ? "--getopenfilename" : "--getsavefilename";
|
||||
std::string filter = GetKDialogFilterString(desc.Filters);
|
||||
std::string cmd = String::StdFormat(
|
||||
"%s --title '%s' %s '%s' '%s'",
|
||||
executablePath.c_str(),
|
||||
desc.Title.c_str(),
|
||||
action.c_str(),
|
||||
desc.InitialDirectory.c_str(),
|
||||
filter.c_str());
|
||||
std::string output;
|
||||
if (Execute(cmd, &output) == 0)
|
||||
{
|
||||
result = output;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIALOG_TYPE::ZENITY:
|
||||
{
|
||||
std::string action = "--file-selection";
|
||||
std::string flags;
|
||||
if (desc.Type == FILE_DIALOG_TYPE::SAVE)
|
||||
{
|
||||
flags = "--confirm-overwrite --save";
|
||||
}
|
||||
std::string filters = GetZenityFilterString(desc.Filters);
|
||||
std::string cmd = String::StdFormat("%s %s --filename='%s/' %s --title='%s' / %s",
|
||||
executablePath.c_str(),
|
||||
action.c_str(),
|
||||
desc.InitialDirectory.c_str(),
|
||||
flags.c_str(),
|
||||
desc.Title.c_str(),
|
||||
filters.c_str());
|
||||
std::string output;
|
||||
if (Execute(cmd, &output) == 0)
|
||||
case DIALOG_TYPE::ZENITY:
|
||||
{
|
||||
std::string action = "--file-selection";
|
||||
std::string flags;
|
||||
if (desc.Type == FILE_DIALOG_TYPE::SAVE)
|
||||
{
|
||||
// The default file extension is taken from the **first** available filter, since
|
||||
// we cannot obtain it from zenity's output. This means that the FileDialogDesc::Filters
|
||||
// array must be carefully populated, at least the first element.
|
||||
std::string pattern = desc.Filters[0].Pattern;
|
||||
std::string defaultExtension = pattern.substr(pattern.find_last_of('.'));
|
||||
|
||||
const utf8 * filename = Path::GetFileName(output.c_str());
|
||||
|
||||
// If there is no extension, append the pattern
|
||||
const utf8 * extension = Path::GetExtension(filename);
|
||||
result = output;
|
||||
if (extension[0] == '\0' && !defaultExtension.empty())
|
||||
flags = "--confirm-overwrite --save";
|
||||
}
|
||||
std::string filters = GetZenityFilterString(desc.Filters);
|
||||
std::string cmd = String::StdFormat(
|
||||
"%s %s --filename='%s/' %s --title='%s' / %s",
|
||||
executablePath.c_str(),
|
||||
action.c_str(),
|
||||
desc.InitialDirectory.c_str(),
|
||||
flags.c_str(),
|
||||
desc.Title.c_str(),
|
||||
filters.c_str());
|
||||
std::string output;
|
||||
if (Execute(cmd, &output) == 0)
|
||||
{
|
||||
if (desc.Type == FILE_DIALOG_TYPE::SAVE)
|
||||
{
|
||||
result = output.append(defaultExtension);
|
||||
// The default file extension is taken from the **first** available filter, since
|
||||
// we cannot obtain it from zenity's output. This means that the FileDialogDesc::Filters
|
||||
// array must be carefully populated, at least the first element.
|
||||
std::string pattern = desc.Filters[0].Pattern;
|
||||
std::string defaultExtension = pattern.substr(pattern.find_last_of('.'));
|
||||
|
||||
const utf8* filename = Path::GetFileName(output.c_str());
|
||||
|
||||
// If there is no extension, append the pattern
|
||||
const utf8* extension = Path::GetExtension(filename);
|
||||
result = output;
|
||||
if (extension[0] == '\0' && !defaultExtension.empty())
|
||||
{
|
||||
result = output.append(defaultExtension);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = output;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = output;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ThrowMissingDialogApp();
|
||||
break;
|
||||
default:
|
||||
ThrowMissingDialogApp();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!result.empty())
|
||||
{
|
||||
if (desc.Type == FILE_DIALOG_TYPE::OPEN && access(result.c_str(), F_OK) == -1)
|
||||
{
|
||||
std::string msg = String::StdFormat("\"%s\" not found: %s, please choose another file\n", result.c_str(), strerror(errno));
|
||||
std::string msg = String::StdFormat(
|
||||
"\"%s\" not found: %s, please choose another file\n", result.c_str(), strerror(errno));
|
||||
ShowMessageBox(window, msg);
|
||||
return ShowFileDialog(window, desc);
|
||||
}
|
||||
else if (desc.Type == FILE_DIALOG_TYPE::SAVE && access(result.c_str(), F_OK) != -1 && dtype == DIALOG_TYPE::KDIALOG)
|
||||
else if (
|
||||
desc.Type == FILE_DIALOG_TYPE::SAVE && access(result.c_str(), F_OK) != -1 && dtype == DIALOG_TYPE::KDIALOG)
|
||||
{
|
||||
std::string cmd = String::StdFormat("%s --yesno \"Overwrite %s?\"", executablePath.c_str(), result.c_str());
|
||||
if (Execute(cmd) != 0)
|
||||
|
@ -206,41 +210,44 @@ namespace OpenRCT2::Ui
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string ShowDirectoryDialog(SDL_Window * window, const std::string &title) override
|
||||
std::string ShowDirectoryDialog(SDL_Window* window, const std::string& title) override
|
||||
{
|
||||
std::string result;
|
||||
std::string executablePath;
|
||||
DIALOG_TYPE dtype = GetDialogApp(&executablePath);
|
||||
switch (dtype) {
|
||||
case DIALOG_TYPE::KDIALOG:
|
||||
switch (dtype)
|
||||
{
|
||||
std::string output;
|
||||
std::string cmd = String::Format("%s --title '%s' --getexistingdirectory /", executablePath.c_str(), title.c_str());
|
||||
if (Execute(cmd, &output) == 0)
|
||||
case DIALOG_TYPE::KDIALOG:
|
||||
{
|
||||
result = output;
|
||||
std::string output;
|
||||
std::string cmd
|
||||
= String::Format("%s --title '%s' --getexistingdirectory /", executablePath.c_str(), title.c_str());
|
||||
if (Execute(cmd, &output) == 0)
|
||||
{
|
||||
result = output;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIALOG_TYPE::ZENITY:
|
||||
{
|
||||
std::string output;
|
||||
std::string cmd = String::Format("%s --title='%s' --file-selection --directory /", executablePath.c_str(), title.c_str());
|
||||
if (Execute(cmd, &output) == 0)
|
||||
case DIALOG_TYPE::ZENITY:
|
||||
{
|
||||
result = output;
|
||||
std::string output;
|
||||
std::string cmd = String::Format(
|
||||
"%s --title='%s' --file-selection --directory /", executablePath.c_str(), title.c_str());
|
||||
if (Execute(cmd, &output) == 0)
|
||||
{
|
||||
result = output;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ThrowMissingDialogApp();
|
||||
break;
|
||||
default:
|
||||
ThrowMissingDialogApp();
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
static DIALOG_TYPE GetDialogApp(std::string * executablePath)
|
||||
static DIALOG_TYPE GetDialogApp(std::string* executablePath)
|
||||
{
|
||||
// Prefer zenity as it offers more required features, e.g., overwrite
|
||||
// confirmation and selecting only existing files.
|
||||
|
@ -258,11 +265,11 @@ namespace OpenRCT2::Ui
|
|||
return DIALOG_TYPE::NONE;
|
||||
}
|
||||
|
||||
static int32_t Execute(const std::string &command, std::string * output = nullptr)
|
||||
static int32_t Execute(const std::string& command, std::string* output = nullptr)
|
||||
{
|
||||
#ifndef __EMSCRIPTEN__
|
||||
log_verbose("executing \"%s\"...\n", command.c_str());
|
||||
FILE * fpipe = popen(command.c_str(), "r");
|
||||
FILE* fpipe = popen(command.c_str(), "r");
|
||||
if (fpipe == nullptr)
|
||||
{
|
||||
return -1;
|
||||
|
@ -313,7 +320,7 @@ namespace OpenRCT2::Ui
|
|||
{
|
||||
std::stringstream filtersb;
|
||||
bool first = true;
|
||||
for (const auto &filter : filters)
|
||||
for (const auto& filter : filters)
|
||||
{
|
||||
// KDialog wants filters space-delimited and we don't expect ';' anywhere else
|
||||
std::string pattern = filter.Pattern;
|
||||
|
@ -342,7 +349,7 @@ namespace OpenRCT2::Ui
|
|||
{
|
||||
// Zenity seems to be case sensitive, while KDialog isn't
|
||||
std::stringstream filtersb;
|
||||
for (const auto &filter : filters)
|
||||
for (const auto& filter : filters)
|
||||
{
|
||||
filtersb << " --file-filter='" << filter.Name << " | ";
|
||||
for (char c : filter.Pattern)
|
||||
|
@ -353,10 +360,7 @@ namespace OpenRCT2::Ui
|
|||
}
|
||||
else if (isalpha(c))
|
||||
{
|
||||
filtersb << '['
|
||||
<< (char)tolower(c)
|
||||
<< (char)toupper(c)
|
||||
<< ']';
|
||||
filtersb << '[' << (char)tolower(c) << (char)toupper(c) << ']';
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -377,7 +381,7 @@ namespace OpenRCT2::Ui
|
|||
}
|
||||
};
|
||||
|
||||
IPlatformUiContext * CreatePlatformUiContext()
|
||||
IPlatformUiContext* CreatePlatformUiContext()
|
||||
{
|
||||
return new LinuxContext();
|
||||
}
|
||||
|
|
|
@ -20,17 +20,17 @@
|
|||
#undef CreateWindow
|
||||
|
||||
// Then the rest
|
||||
#include "UiContext.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_syswm.h>
|
||||
#include <openrct2/common.h>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Path.hpp>
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
#include "UiContext.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <shlobj.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_syswm.h>
|
||||
#include <sstream>
|
||||
|
||||
// Native resource IDs
|
||||
#include "../../resources/resource.h"
|
||||
|
@ -63,7 +63,7 @@ namespace OpenRCT2::Ui
|
|||
_win32module = GetModuleHandleA(nullptr);
|
||||
}
|
||||
|
||||
void SetWindowIcon(SDL_Window * window) override
|
||||
void SetWindowIcon(SDL_Window* window) override
|
||||
{
|
||||
if (_win32module != nullptr)
|
||||
{
|
||||
|
@ -84,14 +84,14 @@ namespace OpenRCT2::Ui
|
|||
return (GetModuleHandleA("GameOverlayRenderer.dll") != nullptr);
|
||||
}
|
||||
|
||||
void ShowMessageBox(SDL_Window * window, const std::string &message) override
|
||||
void ShowMessageBox(SDL_Window* window, const std::string& message) override
|
||||
{
|
||||
HWND hwnd = GetHWND(window);
|
||||
std::wstring messageW = String::ToUtf16(message);
|
||||
MessageBoxW(hwnd, messageW.c_str(), L"OpenRCT2", MB_OK);
|
||||
}
|
||||
|
||||
std::string ShowFileDialog(SDL_Window * window, const FileDialogDesc &desc) override
|
||||
std::string ShowFileDialog(SDL_Window* window, const FileDialogDesc& desc) override
|
||||
{
|
||||
std::wstring wcFilename = String::ToUtf16(desc.DefaultFilename);
|
||||
wcFilename.resize(std::max<size_t>(wcFilename.size(), MAX_PATH));
|
||||
|
@ -149,14 +149,13 @@ namespace OpenRCT2::Ui
|
|||
return resultFilename;
|
||||
}
|
||||
|
||||
std::string ShowDirectoryDialog(SDL_Window * window, const std::string &title) override
|
||||
std::string ShowDirectoryDialog(SDL_Window* window, const std::string& title) override
|
||||
{
|
||||
std::string result;
|
||||
|
||||
// Initialize COM and get a pointer to the shell memory allocator
|
||||
LPMALLOC lpMalloc;
|
||||
if (SUCCEEDED(CoInitializeEx(0, COINIT_APARTMENTTHREADED)) &&
|
||||
SUCCEEDED(SHGetMalloc(&lpMalloc)))
|
||||
if (SUCCEEDED(CoInitializeEx(0, COINIT_APARTMENTTHREADED)) && SUCCEEDED(SHGetMalloc(&lpMalloc)))
|
||||
{
|
||||
std::wstring titleW = String::ToUtf16(title);
|
||||
BROWSEINFOW bi = {};
|
||||
|
@ -184,7 +183,7 @@ namespace OpenRCT2::Ui
|
|||
}
|
||||
|
||||
private:
|
||||
HWND GetHWND(SDL_Window * window)
|
||||
HWND GetHWND(SDL_Window* window)
|
||||
{
|
||||
HWND result = nullptr;
|
||||
if (window != nullptr)
|
||||
|
@ -207,16 +206,13 @@ namespace OpenRCT2::Ui
|
|||
std::wstringstream filtersb;
|
||||
for (auto filter : filters)
|
||||
{
|
||||
filtersb << String::ToUtf16(filter.Name)
|
||||
<< '\0'
|
||||
<< String::ToUtf16(filter.Pattern)
|
||||
<< '\0';
|
||||
filtersb << String::ToUtf16(filter.Name) << '\0' << String::ToUtf16(filter.Pattern) << '\0';
|
||||
}
|
||||
return filtersb.str();
|
||||
}
|
||||
};
|
||||
|
||||
IPlatformUiContext * CreatePlatformUiContext()
|
||||
IPlatformUiContext* CreatePlatformUiContext()
|
||||
{
|
||||
return new Win32Context();
|
||||
}
|
||||
|
|
|
@ -7,42 +7,42 @@
|
|||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "UiContext.h"
|
||||
|
||||
#include "CursorRepository.h"
|
||||
#include "SDLException.h"
|
||||
#include "TextComposition.h"
|
||||
#include "WindowManager.h"
|
||||
#include "drawing/engines/DrawingEngineFactory.hpp"
|
||||
#include "input/KeyboardShortcuts.h"
|
||||
#include "interface/InGameConsole.h"
|
||||
#include "interface/Theme.h"
|
||||
#include "title/TitleSequencePlayer.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <openrct2-ui/interface/Window.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2/Version.h>
|
||||
#include <openrct2/audio/AudioMixer.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include <openrct2/drawing/IDrawingEngine.h>
|
||||
#include <openrct2/drawing/Drawing.h>
|
||||
#include <openrct2/localisation/StringIds.h>
|
||||
#include <openrct2/drawing/IDrawingEngine.h>
|
||||
#include <openrct2/interface/Chat.h>
|
||||
#include <openrct2/interface/InteractiveConsole.h>
|
||||
#include <openrct2/localisation/StringIds.h>
|
||||
#include <openrct2/platform/Platform2.h>
|
||||
#include <openrct2/title/TitleSequencePlayer.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
#include <openrct2/ui/WindowManager.h>
|
||||
#include <openrct2/Version.h>
|
||||
#include "CursorRepository.h"
|
||||
#include "drawing/engines/DrawingEngineFactory.hpp"
|
||||
#include "input/KeyboardShortcuts.h"
|
||||
#include "interface/Theme.h"
|
||||
#include "SDLException.h"
|
||||
#include "TextComposition.h"
|
||||
#include "UiContext.h"
|
||||
#include "WindowManager.h"
|
||||
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2/interface/InteractiveConsole.h>
|
||||
#include <openrct2-ui/interface/Window.h>
|
||||
|
||||
#include "interface/InGameConsole.h"
|
||||
#include "title/TitleSequencePlayer.h"
|
||||
#include <vector>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
using namespace OpenRCT2::Drawing;
|
||||
|
@ -50,10 +50,10 @@ using namespace OpenRCT2::Input;
|
|||
using namespace OpenRCT2::Ui;
|
||||
|
||||
#ifdef __MACOSX__
|
||||
// macOS uses COMMAND rather than CTRL for many keyboard shortcuts
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_GUI
|
||||
// macOS uses COMMAND rather than CTRL for many keyboard shortcuts
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_GUI
|
||||
#else
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_CTRL
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_CTRL
|
||||
#endif
|
||||
|
||||
class UiContext final : public IUiContext
|
||||
|
@ -61,40 +61,43 @@ class UiContext final : public IUiContext
|
|||
private:
|
||||
constexpr static uint32_t TOUCH_DOUBLE_TIMEOUT = 300;
|
||||
|
||||
IPlatformUiContext * const _platformUiContext;
|
||||
IWindowManager * const _windowManager;
|
||||
IPlatformUiContext* const _platformUiContext;
|
||||
IWindowManager* const _windowManager;
|
||||
|
||||
CursorRepository _cursorRepository;
|
||||
|
||||
SDL_Window * _window = nullptr;
|
||||
int32_t _width = 0;
|
||||
int32_t _height = 0;
|
||||
int32_t _scaleQuality = 0;
|
||||
SDL_Window* _window = nullptr;
|
||||
int32_t _width = 0;
|
||||
int32_t _height = 0;
|
||||
int32_t _scaleQuality = 0;
|
||||
|
||||
std::vector<Resolution> _fsResolutions;
|
||||
|
||||
bool _steamOverlayActive = false;
|
||||
|
||||
// Input
|
||||
KeyboardShortcuts _keyboardShortcuts;
|
||||
TextComposition _textComposition;
|
||||
CursorState _cursorState = {};
|
||||
uint32_t _lastKeyPressed = 0;
|
||||
const uint8_t * _keysState = nullptr;
|
||||
uint8_t _keysPressed[256] = {};
|
||||
uint32_t _lastGestureTimestamp = 0;
|
||||
float _gestureRadius = 0;
|
||||
KeyboardShortcuts _keyboardShortcuts;
|
||||
TextComposition _textComposition;
|
||||
CursorState _cursorState = {};
|
||||
uint32_t _lastKeyPressed = 0;
|
||||
const uint8_t* _keysState = nullptr;
|
||||
uint8_t _keysPressed[256] = {};
|
||||
uint32_t _lastGestureTimestamp = 0;
|
||||
float _gestureRadius = 0;
|
||||
|
||||
InGameConsole _inGameConsole;
|
||||
InGameConsole _inGameConsole;
|
||||
std::unique_ptr<ITitleSequencePlayer> _titleSequencePlayer;
|
||||
|
||||
public:
|
||||
InGameConsole& GetInGameConsole() { return _inGameConsole; }
|
||||
InGameConsole& GetInGameConsole()
|
||||
{
|
||||
return _inGameConsole;
|
||||
}
|
||||
|
||||
explicit UiContext(const std::shared_ptr<IPlatformEnvironment>& env)
|
||||
: _platformUiContext(CreatePlatformUiContext()),
|
||||
_windowManager(CreateWindowManager()),
|
||||
_keyboardShortcuts(env)
|
||||
: _platformUiContext(CreatePlatformUiContext())
|
||||
, _windowManager(CreateWindowManager())
|
||||
, _keyboardShortcuts(env)
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||
{
|
||||
|
@ -118,7 +121,7 @@ public:
|
|||
_inGameConsole.Update();
|
||||
}
|
||||
|
||||
void Draw(rct_drawpixelinfo * dpi) override
|
||||
void Draw(rct_drawpixelinfo* dpi) override
|
||||
{
|
||||
auto bgColour = theme_get_colour(WC_CHAT, 0);
|
||||
chat_draw(dpi, bgColour);
|
||||
|
@ -126,7 +129,7 @@ public:
|
|||
}
|
||||
|
||||
// Window
|
||||
void * GetWindow() override
|
||||
void* GetWindow() override
|
||||
{
|
||||
return _window;
|
||||
}
|
||||
|
@ -193,8 +196,7 @@ public:
|
|||
bool IsMinimised() override
|
||||
{
|
||||
uint32_t windowFlags = GetWindowFlags();
|
||||
return (windowFlags & SDL_WINDOW_MINIMIZED) ||
|
||||
(windowFlags & SDL_WINDOW_HIDDEN);
|
||||
return (windowFlags & SDL_WINDOW_MINIMIZED) || (windowFlags & SDL_WINDOW_HIDDEN);
|
||||
}
|
||||
|
||||
bool IsSteamOverlayActive() override
|
||||
|
@ -203,17 +205,17 @@ public:
|
|||
}
|
||||
|
||||
// Input
|
||||
const CursorState * GetCursorState() override
|
||||
const CursorState* GetCursorState() override
|
||||
{
|
||||
return &_cursorState;
|
||||
}
|
||||
|
||||
const uint8_t * GetKeysState() override
|
||||
const uint8_t* GetKeysState() override
|
||||
{
|
||||
return _keysState;
|
||||
}
|
||||
|
||||
const uint8_t * GetKeysPressed() override
|
||||
const uint8_t* GetKeysPressed() override
|
||||
{
|
||||
return _keysPressed;
|
||||
}
|
||||
|
@ -238,7 +240,7 @@ public:
|
|||
SDL_ShowCursor(value ? SDL_ENABLE : SDL_DISABLE);
|
||||
}
|
||||
|
||||
void GetCursorPosition(int32_t * x, int32_t * y) override
|
||||
void GetCursorPosition(int32_t* x, int32_t* y) override
|
||||
{
|
||||
SDL_GetMouseState(x, y);
|
||||
}
|
||||
|
@ -284,7 +286,7 @@ public:
|
|||
return _textComposition.IsActive();
|
||||
}
|
||||
|
||||
TextInputSession * StartTextInput(utf8 * buffer, size_t bufferSize) override
|
||||
TextInputSession* StartTextInput(utf8* buffer, size_t bufferSize) override
|
||||
{
|
||||
return _textComposition.Start(buffer, bufferSize);
|
||||
}
|
||||
|
@ -306,197 +308,203 @@ public:
|
|||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e))
|
||||
{
|
||||
switch (e.type) {
|
||||
case SDL_QUIT:
|
||||
context_quit();
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
// HACK: Fix #2158, OpenRCT2 does not draw if it does not think that the window is
|
||||
// visible - due a bug in SDL 2.0.3 this hack is required if the
|
||||
// window is maximised, minimised and then restored again.
|
||||
if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
||||
{
|
||||
if (SDL_GetWindowFlags(_window) & SDL_WINDOW_MAXIMIZED)
|
||||
{
|
||||
SDL_RestoreWindow(_window);
|
||||
SDL_MaximizeWindow(_window);
|
||||
}
|
||||
if ((SDL_GetWindowFlags(_window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||
{
|
||||
SDL_RestoreWindow(_window);
|
||||
SDL_SetWindowFullscreen(_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
|
||||
{
|
||||
OnResize(e.window.data1, e.window.data2);
|
||||
}
|
||||
|
||||
switch (e.window.event) {
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
case SDL_WINDOWEVENT_MOVED:
|
||||
case SDL_WINDOWEVENT_MAXIMIZED:
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
{
|
||||
// Update default display index
|
||||
int32_t displayIndex = SDL_GetWindowDisplayIndex(_window);
|
||||
if (displayIndex != gConfigGeneral.default_display)
|
||||
{
|
||||
gConfigGeneral.default_display = displayIndex;
|
||||
config_save_default();
|
||||
}
|
||||
switch (e.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
context_quit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gConfigSound.audio_focus && gConfigSound.sound_enabled)
|
||||
{
|
||||
case SDL_WINDOWEVENT:
|
||||
// HACK: Fix #2158, OpenRCT2 does not draw if it does not think that the window is
|
||||
// visible - due a bug in SDL 2.0.3 this hack is required if the
|
||||
// window is maximised, minimised and then restored again.
|
||||
if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
||||
{
|
||||
Mixer_SetVolume(1);
|
||||
if (SDL_GetWindowFlags(_window) & SDL_WINDOW_MAXIMIZED)
|
||||
{
|
||||
SDL_RestoreWindow(_window);
|
||||
SDL_MaximizeWindow(_window);
|
||||
}
|
||||
if ((SDL_GetWindowFlags(_window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||
{
|
||||
SDL_RestoreWindow(_window);
|
||||
SDL_SetWindowFullscreen(_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
}
|
||||
}
|
||||
if (e.window.event == SDL_WINDOWEVENT_FOCUS_LOST)
|
||||
|
||||
if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
|
||||
{
|
||||
Mixer_SetVolume(0);
|
||||
OnResize(e.window.data1, e.window.data2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
_cursorState.x = (int32_t)(e.motion.x / gConfigGeneral.window_scale);
|
||||
_cursorState.y = (int32_t)(e.motion.y / gConfigGeneral.window_scale);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
if (_inGameConsole.IsOpen())
|
||||
|
||||
switch (e.window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
case SDL_WINDOWEVENT_MOVED:
|
||||
case SDL_WINDOWEVENT_MAXIMIZED:
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
{
|
||||
// Update default display index
|
||||
int32_t displayIndex = SDL_GetWindowDisplayIndex(_window);
|
||||
if (displayIndex != gConfigGeneral.default_display)
|
||||
{
|
||||
gConfigGeneral.default_display = displayIndex;
|
||||
config_save_default();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gConfigSound.audio_focus && gConfigSound.sound_enabled)
|
||||
{
|
||||
if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
||||
{
|
||||
Mixer_SetVolume(1);
|
||||
}
|
||||
if (e.window.event == SDL_WINDOWEVENT_FOCUS_LOST)
|
||||
{
|
||||
Mixer_SetVolume(0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
_cursorState.x = (int32_t)(e.motion.x / gConfigGeneral.window_scale);
|
||||
_cursorState.y = (int32_t)(e.motion.y / gConfigGeneral.window_scale);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
if (_inGameConsole.IsOpen())
|
||||
{
|
||||
_inGameConsole.Scroll(e.wheel.y * 3); // Scroll 3 lines at a time
|
||||
break;
|
||||
}
|
||||
_cursorState.wheel -= e.wheel.y;
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
_inGameConsole.Scroll(e.wheel.y * 3); // Scroll 3 lines at a time
|
||||
int32_t x = (int32_t)(e.button.x / gConfigGeneral.window_scale);
|
||||
int32_t y = (int32_t)(e.button.y / gConfigGeneral.window_scale);
|
||||
switch (e.button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
store_mouse_input(MOUSE_STATE_LEFT_PRESS, x, y);
|
||||
_cursorState.left = CURSOR_PRESSED;
|
||||
_cursorState.old = 1;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
_cursorState.middle = CURSOR_PRESSED;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_PRESS, x, y);
|
||||
_cursorState.right = CURSOR_PRESSED;
|
||||
_cursorState.old = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
_cursorState.wheel -= e.wheel.y;
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
int32_t x = (int32_t)(e.button.x / gConfigGeneral.window_scale);
|
||||
int32_t y = (int32_t)(e.button.y / gConfigGeneral.window_scale);
|
||||
switch (e.button.button) {
|
||||
case SDL_BUTTON_LEFT:
|
||||
store_mouse_input(MOUSE_STATE_LEFT_PRESS, x, y);
|
||||
_cursorState.left = CURSOR_PRESSED;
|
||||
_cursorState.old = 1;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
_cursorState.middle = CURSOR_PRESSED;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_PRESS, x, y);
|
||||
_cursorState.right = CURSOR_PRESSED;
|
||||
_cursorState.old = 2;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
int32_t x = (int32_t)(e.button.x / gConfigGeneral.window_scale);
|
||||
int32_t y = (int32_t)(e.button.y / gConfigGeneral.window_scale);
|
||||
switch (e.button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
store_mouse_input(MOUSE_STATE_LEFT_RELEASE, x, y);
|
||||
_cursorState.left = CURSOR_RELEASED;
|
||||
_cursorState.old = 3;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
_cursorState.middle = CURSOR_RELEASED;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_RELEASE, x, y);
|
||||
_cursorState.right = CURSOR_RELEASED;
|
||||
_cursorState.old = 4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
int32_t x = (int32_t)(e.button.x / gConfigGeneral.window_scale);
|
||||
int32_t y = (int32_t)(e.button.y / gConfigGeneral.window_scale);
|
||||
switch (e.button.button) {
|
||||
case SDL_BUTTON_LEFT:
|
||||
store_mouse_input(MOUSE_STATE_LEFT_RELEASE, x, y);
|
||||
_cursorState.left = CURSOR_RELEASED;
|
||||
_cursorState.old = 3;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
_cursorState.middle = CURSOR_RELEASED;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_RELEASE, x, y);
|
||||
_cursorState.right = CURSOR_RELEASED;
|
||||
_cursorState.old = 4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Apple sends touchscreen events for trackpads, so ignore these events on macOS
|
||||
// Apple sends touchscreen events for trackpads, so ignore these events on macOS
|
||||
#ifndef __MACOSX__
|
||||
case SDL_FINGERMOTION:
|
||||
_cursorState.x = (int32_t)(e.tfinger.x * _width);
|
||||
_cursorState.y = (int32_t)(e.tfinger.y * _height);
|
||||
break;
|
||||
case SDL_FINGERDOWN:
|
||||
{
|
||||
int32_t x = (int32_t)(e.tfinger.x * _width);
|
||||
int32_t y = (int32_t)(e.tfinger.y * _height);
|
||||
|
||||
_cursorState.touchIsDouble = (!_cursorState.touchIsDouble &&
|
||||
e.tfinger.timestamp - _cursorState.touchDownTimestamp < TOUCH_DOUBLE_TIMEOUT);
|
||||
|
||||
if (_cursorState.touchIsDouble)
|
||||
case SDL_FINGERMOTION:
|
||||
_cursorState.x = (int32_t)(e.tfinger.x * _width);
|
||||
_cursorState.y = (int32_t)(e.tfinger.y * _height);
|
||||
break;
|
||||
case SDL_FINGERDOWN:
|
||||
{
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_PRESS, x, y);
|
||||
_cursorState.right = CURSOR_PRESSED;
|
||||
_cursorState.old = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
store_mouse_input(MOUSE_STATE_LEFT_PRESS, x, y);
|
||||
_cursorState.left = CURSOR_PRESSED;
|
||||
_cursorState.old = 1;
|
||||
}
|
||||
_cursorState.touch = true;
|
||||
_cursorState.touchDownTimestamp = e.tfinger.timestamp;
|
||||
break;
|
||||
}
|
||||
case SDL_FINGERUP:
|
||||
{
|
||||
int32_t x = (int32_t)(e.tfinger.x * _width);
|
||||
int32_t y = (int32_t)(e.tfinger.y * _height);
|
||||
int32_t x = (int32_t)(e.tfinger.x * _width);
|
||||
int32_t y = (int32_t)(e.tfinger.y * _height);
|
||||
|
||||
if (_cursorState.touchIsDouble)
|
||||
_cursorState.touchIsDouble
|
||||
= (!_cursorState.touchIsDouble
|
||||
&& e.tfinger.timestamp - _cursorState.touchDownTimestamp < TOUCH_DOUBLE_TIMEOUT);
|
||||
|
||||
if (_cursorState.touchIsDouble)
|
||||
{
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_PRESS, x, y);
|
||||
_cursorState.right = CURSOR_PRESSED;
|
||||
_cursorState.old = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
store_mouse_input(MOUSE_STATE_LEFT_PRESS, x, y);
|
||||
_cursorState.left = CURSOR_PRESSED;
|
||||
_cursorState.old = 1;
|
||||
}
|
||||
_cursorState.touch = true;
|
||||
_cursorState.touchDownTimestamp = e.tfinger.timestamp;
|
||||
break;
|
||||
}
|
||||
case SDL_FINGERUP:
|
||||
{
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_RELEASE, x, y);
|
||||
_cursorState.right = CURSOR_RELEASED;
|
||||
_cursorState.old = 4;
|
||||
int32_t x = (int32_t)(e.tfinger.x * _width);
|
||||
int32_t y = (int32_t)(e.tfinger.y * _height);
|
||||
|
||||
if (_cursorState.touchIsDouble)
|
||||
{
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_RELEASE, x, y);
|
||||
_cursorState.right = CURSOR_RELEASED;
|
||||
_cursorState.old = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
store_mouse_input(MOUSE_STATE_LEFT_RELEASE, x, y);
|
||||
_cursorState.left = CURSOR_RELEASED;
|
||||
_cursorState.old = 3;
|
||||
}
|
||||
_cursorState.touch = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
store_mouse_input(MOUSE_STATE_LEFT_RELEASE, x, y);
|
||||
_cursorState.left = CURSOR_RELEASED;
|
||||
_cursorState.old = 3;
|
||||
}
|
||||
_cursorState.touch = true;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SDL_KEYDOWN:
|
||||
_textComposition.HandleMessage(&e);
|
||||
break;
|
||||
case SDL_MULTIGESTURE:
|
||||
if (e.mgesture.numFingers == 2)
|
||||
{
|
||||
if (e.mgesture.timestamp > _lastGestureTimestamp + 1000)
|
||||
case SDL_KEYDOWN:
|
||||
_textComposition.HandleMessage(&e);
|
||||
break;
|
||||
case SDL_MULTIGESTURE:
|
||||
if (e.mgesture.numFingers == 2)
|
||||
{
|
||||
_gestureRadius = 0;
|
||||
}
|
||||
_lastGestureTimestamp = e.mgesture.timestamp;
|
||||
_gestureRadius += e.mgesture.dDist;
|
||||
if (e.mgesture.timestamp > _lastGestureTimestamp + 1000)
|
||||
{
|
||||
_gestureRadius = 0;
|
||||
}
|
||||
_lastGestureTimestamp = e.mgesture.timestamp;
|
||||
_gestureRadius += e.mgesture.dDist;
|
||||
|
||||
// Zoom gesture
|
||||
constexpr int32_t tolerance = 128;
|
||||
int32_t gesturePixels = (int32_t)(_gestureRadius * _width);
|
||||
if (abs(gesturePixels) > tolerance)
|
||||
{
|
||||
_gestureRadius = 0;
|
||||
main_window_zoom(gesturePixels > 0, true);
|
||||
// Zoom gesture
|
||||
constexpr int32_t tolerance = 128;
|
||||
int32_t gesturePixels = (int32_t)(_gestureRadius * _width);
|
||||
if (abs(gesturePixels) > tolerance)
|
||||
{
|
||||
_gestureRadius = 0;
|
||||
main_window_zoom(gesturePixels > 0, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_TEXTEDITING:
|
||||
_textComposition.HandleMessage(&e);
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
_textComposition.HandleMessage(&e);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
case SDL_TEXTEDITING:
|
||||
_textComposition.HandleMessage(&e);
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
_textComposition.HandleMessage(&e);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -569,22 +577,22 @@ public:
|
|||
CreateWindow(x, y);
|
||||
}
|
||||
|
||||
void ShowMessageBox(const std::string &message) override
|
||||
void ShowMessageBox(const std::string& message) override
|
||||
{
|
||||
_platformUiContext->ShowMessageBox(_window, message);
|
||||
}
|
||||
|
||||
std::string ShowFileDialog(const FileDialogDesc &desc) override
|
||||
std::string ShowFileDialog(const FileDialogDesc& desc) override
|
||||
{
|
||||
return _platformUiContext->ShowFileDialog(_window, desc);
|
||||
}
|
||||
|
||||
std::string ShowDirectoryDialog(const std::string &title) override
|
||||
std::string ShowDirectoryDialog(const std::string& title) override
|
||||
{
|
||||
return _platformUiContext->ShowDirectoryDialog(_window, title);
|
||||
}
|
||||
|
||||
IWindowManager * GetWindowManager() override
|
||||
IWindowManager* GetWindowManager() override
|
||||
{
|
||||
return _windowManager;
|
||||
}
|
||||
|
@ -594,7 +602,7 @@ public:
|
|||
return (SDL_SetClipboardText(target) == 0);
|
||||
}
|
||||
|
||||
ITitleSequencePlayer * GetTitleSequencePlayer() override
|
||||
ITitleSequencePlayer* GetTitleSequencePlayer() override
|
||||
{
|
||||
if (_titleSequencePlayer == nullptr)
|
||||
{
|
||||
|
@ -612,8 +620,10 @@ private:
|
|||
// Get saved window size
|
||||
int32_t width = gConfigGeneral.window_width;
|
||||
int32_t height = gConfigGeneral.window_height;
|
||||
if (width <= 0) width = 640;
|
||||
if (height <= 0) height = 480;
|
||||
if (width <= 0)
|
||||
width = 640;
|
||||
if (height <= 0)
|
||||
height = 480;
|
||||
|
||||
// Create window in window first rather than fullscreen so we have the display the window is on first
|
||||
uint32_t flags = SDL_WINDOW_RESIZABLE;
|
||||
|
@ -664,9 +674,7 @@ private:
|
|||
#ifndef __MACOSX__
|
||||
SDL_WINDOW_MAXIMIZED |
|
||||
#endif
|
||||
SDL_WINDOW_MINIMIZED |
|
||||
SDL_WINDOW_FULLSCREEN |
|
||||
SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
SDL_WINDOW_MINIMIZED | SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
|
||||
if (!(flags & nonWindowFlags))
|
||||
{
|
||||
|
@ -706,20 +714,16 @@ private:
|
|||
}
|
||||
|
||||
// Sort by area
|
||||
std::sort(resolutions.begin(), resolutions.end(),
|
||||
[](const Resolution &a, const Resolution &b) -> bool
|
||||
{
|
||||
int32_t areaA = a.Width * a.Height;
|
||||
int32_t areaB = b.Width * b.Height;
|
||||
return areaA < areaB;
|
||||
});
|
||||
std::sort(resolutions.begin(), resolutions.end(), [](const Resolution& a, const Resolution& b) -> bool {
|
||||
int32_t areaA = a.Width * a.Height;
|
||||
int32_t areaB = b.Width * b.Height;
|
||||
return areaA < areaB;
|
||||
});
|
||||
|
||||
// Remove duplicates
|
||||
auto last = std::unique(resolutions.begin(), resolutions.end(),
|
||||
[](const Resolution &a, const Resolution &b) -> bool
|
||||
{
|
||||
return (a.Width == b.Width && a.Height == b.Height);
|
||||
});
|
||||
auto last = std::unique(resolutions.begin(), resolutions.end(), [](const Resolution& a, const Resolution& b) -> bool {
|
||||
return (a.Width == b.Width && a.Height == b.Height);
|
||||
});
|
||||
resolutions.erase(last, resolutions.end());
|
||||
|
||||
// Update config fullscreen resolution if not set
|
||||
|
@ -737,7 +741,7 @@ private:
|
|||
Resolution result = { 640, 480 };
|
||||
int32_t closestAreaDiff = -1;
|
||||
int32_t destinationArea = inWidth * inHeight;
|
||||
for (const Resolution &resolution : _fsResolutions)
|
||||
for (const Resolution& resolution : _fsResolutions)
|
||||
{
|
||||
// Check if exact match
|
||||
if (resolution.Width == inWidth && resolution.Height == inHeight)
|
||||
|
@ -763,16 +767,16 @@ private:
|
|||
}
|
||||
|
||||
static void DrawRainWindow(
|
||||
IRainDrawer * rainDrawer,
|
||||
rct_window * original_w,
|
||||
IRainDrawer* rainDrawer,
|
||||
rct_window* original_w,
|
||||
int16_t left,
|
||||
int16_t right,
|
||||
int16_t top,
|
||||
int16_t bottom,
|
||||
DrawRainFunc drawFunc)
|
||||
{
|
||||
rct_window * w{};
|
||||
for (auto i = window_get_index(original_w) + 1; ; i++)
|
||||
rct_window* w{};
|
||||
for (auto i = window_get_index(original_w) + 1;; i++)
|
||||
{
|
||||
if (i >= g_window_list.size())
|
||||
{
|
||||
|
@ -818,7 +822,8 @@ private:
|
|||
}
|
||||
|
||||
int16_t w_right = RCT_WINDOW_RIGHT(w);
|
||||
if (right > w_right) {
|
||||
if (right > w_right)
|
||||
{
|
||||
DrawRainWindow(rainDrawer, original_w, left, w_right, top, bottom, drawFunc);
|
||||
|
||||
left = w_right;
|
||||
|
@ -826,7 +831,8 @@ private:
|
|||
return;
|
||||
}
|
||||
|
||||
if (top < w->y) {
|
||||
if (top < w->y)
|
||||
{
|
||||
DrawRainWindow(rainDrawer, original_w, left, right, top, w->y, drawFunc);
|
||||
|
||||
top = w->y;
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <openrct2/common.h>
|
||||
#include <string>
|
||||
|
||||
struct SDL_Window;
|
||||
|
||||
|
@ -22,9 +22,9 @@ namespace OpenRCT2
|
|||
|
||||
namespace Ui
|
||||
{
|
||||
struct FileDialogDesc;
|
||||
class InGameConsole;
|
||||
interface IUiContext;
|
||||
struct FileDialogDesc;
|
||||
class InGameConsole;
|
||||
interface IUiContext;
|
||||
|
||||
interface IPlatformUiContext
|
||||
{
|
||||
|
@ -32,13 +32,13 @@ namespace OpenRCT2
|
|||
virtual void SetWindowIcon(SDL_Window * window) abstract;
|
||||
virtual bool IsSteamOverlayAttached() abstract;
|
||||
|
||||
virtual void ShowMessageBox(SDL_Window * window, const std::string &message) abstract;
|
||||
virtual std::string ShowFileDialog(SDL_Window * window, const FileDialogDesc &desc) abstract;
|
||||
virtual std::string ShowDirectoryDialog(SDL_Window * window, const std::string &title) abstract;
|
||||
virtual void ShowMessageBox(SDL_Window * window, const std::string& message) abstract;
|
||||
virtual std::string ShowFileDialog(SDL_Window * window, const FileDialogDesc& desc) abstract;
|
||||
virtual std::string ShowDirectoryDialog(SDL_Window * window, const std::string& title) abstract;
|
||||
};
|
||||
|
||||
std::unique_ptr<IUiContext> CreateUiContext(const std::shared_ptr<IPlatformEnvironment>& env);
|
||||
IPlatformUiContext * CreatePlatformUiContext();
|
||||
IPlatformUiContext* CreatePlatformUiContext();
|
||||
|
||||
InGameConsole& GetInGameConsole();
|
||||
} // namespace Ui
|
||||
|
|
|
@ -28,18 +28,18 @@ namespace OpenRCT2::Ui
|
|||
class macOSContext final : public IPlatformUiContext
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
macOSContext()
|
||||
{
|
||||
@autoreleasepool {
|
||||
if ([NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)]) {
|
||||
if ([NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)])
|
||||
{
|
||||
[NSWindow setAllowsAutomaticWindowTabbing:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetWindowIcon(SDL_Window * window) override
|
||||
void SetWindowIcon(SDL_Window* window) override
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -49,49 +49,51 @@ namespace OpenRCT2::Ui
|
|||
return false;
|
||||
}
|
||||
|
||||
void ShowMessageBox(SDL_Window * window, const std::string &message) override
|
||||
void ShowMessageBox(SDL_Window* window, const std::string& message) override
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
|
||||
@autoreleasepool {
|
||||
NSAlert* alert = [[[NSAlert alloc] init] autorelease];
|
||||
[alert addButtonWithTitle:@"OK"];
|
||||
alert.messageText = [NSString stringWithUTF8String:message.c_str()];
|
||||
[alert runModal];
|
||||
}
|
||||
}
|
||||
|
||||
std::string ShowFileDialog(SDL_Window * window, const FileDialogDesc &desc) override
|
||||
std::string ShowFileDialog(SDL_Window* window, const FileDialogDesc& desc) override
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
NSMutableArray *extensions = [NSMutableArray new];
|
||||
for (const OpenRCT2::Ui::FileDialogDesc::Filter &filter: desc.Filters) {
|
||||
if (filter.Pattern != "") {
|
||||
NSString *fp = [NSString stringWithUTF8String:filter.Pattern.c_str()];
|
||||
@autoreleasepool {
|
||||
NSMutableArray* extensions = [NSMutableArray new];
|
||||
for (const OpenRCT2::Ui::FileDialogDesc::Filter& filter : desc.Filters)
|
||||
{
|
||||
if (filter.Pattern != "")
|
||||
{
|
||||
NSString* fp = [NSString stringWithUTF8String:filter.Pattern.c_str()];
|
||||
fp = [fp stringByReplacingOccurrencesOfString:@"*." withString:@""];
|
||||
[extensions addObjectsFromArray:[fp componentsSeparatedByString:@";"]];
|
||||
}
|
||||
}
|
||||
|
||||
NSString *directory;
|
||||
NSSavePanel *panel;
|
||||
NSString* directory;
|
||||
NSSavePanel* panel;
|
||||
if (desc.Type == FILE_DIALOG_TYPE::SAVE)
|
||||
{
|
||||
NSString *filePath = [NSString stringWithUTF8String:desc.DefaultFilename.c_str()];
|
||||
NSString* filePath = [NSString stringWithUTF8String:desc.DefaultFilename.c_str()];
|
||||
directory = filePath.stringByDeletingLastPathComponent;
|
||||
NSString *basename = filePath.lastPathComponent;
|
||||
NSString* basename = filePath.lastPathComponent;
|
||||
panel = [NSSavePanel savePanel];
|
||||
panel.nameFieldStringValue = [NSString stringWithFormat:@"%@.%@", basename, extensions.firstObject];
|
||||
}
|
||||
else if (desc.Type == FILE_DIALOG_TYPE::OPEN)
|
||||
{
|
||||
directory = [NSString stringWithUTF8String:desc.InitialDirectory.c_str()];
|
||||
NSOpenPanel *open = [NSOpenPanel openPanel];
|
||||
NSOpenPanel* open = [NSOpenPanel openPanel];
|
||||
open.canChooseDirectories = false;
|
||||
open.canChooseFiles = true;
|
||||
open.allowsMultipleSelection = false;
|
||||
panel = open;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
@ -101,36 +103,39 @@ namespace OpenRCT2::Ui
|
|||
if ([panel runModal] == NSModalResponseCancel)
|
||||
{
|
||||
return std::string();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return panel.URL.path.UTF8String;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string ShowDirectoryDialog(SDL_Window * window, const std::string &title) override
|
||||
std::string ShowDirectoryDialog(SDL_Window* window, const std::string& title) override
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
@autoreleasepool {
|
||||
NSOpenPanel* panel = [NSOpenPanel openPanel];
|
||||
panel.canChooseFiles = false;
|
||||
panel.canChooseDirectories = true;
|
||||
panel.allowsMultipleSelection = false;
|
||||
if ([panel runModal] == NSModalResponseOK)
|
||||
{
|
||||
NSString *selectedPath = panel.URL.path;
|
||||
const char *path = selectedPath.UTF8String;
|
||||
NSString* selectedPath = panel.URL.path;
|
||||
const char* path = selectedPath.UTF8String;
|
||||
return path;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static int32_t Execute(const std::string &command, std::string * output = nullptr)
|
||||
static int32_t Execute(const std::string& command, std::string* output = nullptr)
|
||||
{
|
||||
log_verbose("executing \"%s\"...\n", command.c_str());
|
||||
FILE * fpipe = popen(command.c_str(), "r");
|
||||
FILE* fpipe = popen(command.c_str(), "r");
|
||||
if (fpipe == nullptr)
|
||||
{
|
||||
return -1;
|
||||
|
@ -174,7 +179,7 @@ namespace OpenRCT2::Ui
|
|||
}
|
||||
};
|
||||
|
||||
IPlatformUiContext * CreatePlatformUiContext()
|
||||
IPlatformUiContext* CreatePlatformUiContext()
|
||||
{
|
||||
return new macOSContext();
|
||||
}
|
||||
|
|
|
@ -7,19 +7,21 @@
|
|||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <openrct2/ui/WindowManager.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
#include <openrct2/core/Console.hpp>
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/interface/Viewport.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2/world/Sprite.h>
|
||||
#include "WindowManager.h"
|
||||
|
||||
#include "input/Input.h"
|
||||
#include "input/KeyboardShortcuts.h"
|
||||
#include "interface/Theme.h"
|
||||
#include "WindowManager.h"
|
||||
#include "windows/Window.h"
|
||||
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/core/Console.hpp>
|
||||
#include <openrct2/interface/Viewport.h>
|
||||
#include <openrct2/ui/WindowManager.h>
|
||||
#include <openrct2/world/Sprite.h>
|
||||
|
||||
using namespace OpenRCT2::Ui;
|
||||
|
||||
class WindowManager final : public IWindowManager
|
||||
|
@ -32,405 +34,407 @@ public:
|
|||
window_new_ride_init_vars();
|
||||
}
|
||||
|
||||
rct_window * OpenWindow(rct_windowclass wc) override
|
||||
rct_window* OpenWindow(rct_windowclass wc) override
|
||||
{
|
||||
switch (wc)
|
||||
{
|
||||
case WC_ABOUT:
|
||||
return window_about_open();
|
||||
case WC_BOTTOM_TOOLBAR:
|
||||
return window_game_bottom_toolbar_open();
|
||||
case WC_CHANGELOG:
|
||||
return window_changelog_open();
|
||||
case WC_CHEATS:
|
||||
return window_cheats_open();
|
||||
case WC_CLEAR_SCENERY:
|
||||
return window_clear_scenery_open();
|
||||
case WC_CUSTOM_CURRENCY_CONFIG:
|
||||
return custom_currency_window_open();
|
||||
case WC_DEBUG_PAINT:
|
||||
return window_debug_paint_open();
|
||||
case WC_EDITOR_INVENTION_LIST:
|
||||
return window_editor_inventions_list_open();
|
||||
case WC_EDITOR_OBJECT_SELECTION:
|
||||
return window_editor_object_selection_open();
|
||||
case WC_EDTIOR_OBJECTIVE_OPTIONS:
|
||||
return window_editor_objective_options_open();
|
||||
case WC_EDITOR_SCENARIO_OPTIONS:
|
||||
return window_editor_scenario_options_open();
|
||||
case WC_FINANCES:
|
||||
return window_finances_open();
|
||||
case WC_FOOTPATH:
|
||||
return window_footpath_open();
|
||||
case WC_GUEST_LIST:
|
||||
return window_guest_list_open();
|
||||
case WC_LAND:
|
||||
return window_land_open();
|
||||
case WC_LAND_RIGHTS:
|
||||
return window_land_rights_open();
|
||||
case WC_MAIN_WINDOW:
|
||||
return window_main_open();
|
||||
case WC_MAP:
|
||||
return window_map_open();
|
||||
case WC_MAPGEN:
|
||||
return window_mapgen_open();
|
||||
case WC_MULTIPLAYER:
|
||||
return window_multiplayer_open();
|
||||
case WC_MUSIC_CREDITS:
|
||||
return window_music_credits_open();
|
||||
case WC_CONSTRUCT_RIDE:
|
||||
return window_new_ride_open();
|
||||
case WC_PARK_INFORMATION:
|
||||
return window_park_entrance_open();
|
||||
case WC_RECENT_NEWS:
|
||||
return window_news_open();
|
||||
case WC_RIDE_CONSTRUCTION:
|
||||
return window_ride_construction_open();
|
||||
case WC_RESEARCH:
|
||||
return window_research_open();
|
||||
case WC_RIDE_LIST:
|
||||
return window_ride_list_open();
|
||||
case WC_NOTIFICATION_OPTIONS:
|
||||
return window_news_options_open();
|
||||
case WC_OPTIONS:
|
||||
return window_options_open();
|
||||
case WC_SAVE_PROMPT:
|
||||
return window_save_prompt_open();
|
||||
case WC_SCENERY:
|
||||
return window_scenery_open();
|
||||
case WC_SERVER_LIST:
|
||||
return window_server_list_open();
|
||||
case WC_SERVER_START:
|
||||
return window_server_start_open();
|
||||
case WC_KEYBOARD_SHORTCUT_LIST:
|
||||
return window_shortcut_keys_open();
|
||||
case WC_STAFF_LIST:
|
||||
return window_staff_list_open();
|
||||
case WC_THEMES:
|
||||
return window_themes_open();
|
||||
case WC_TILE_INSPECTOR:
|
||||
return window_tile_inspector_open();
|
||||
case WC_TITLE_EXIT:
|
||||
return window_title_exit_open();
|
||||
case WC_TITLE_LOGO:
|
||||
return window_title_logo_open();
|
||||
case WC_TITLE_MENU:
|
||||
return window_title_menu_open();
|
||||
case WC_TITLE_OPTIONS:
|
||||
return window_title_options_open();
|
||||
case WC_TOP_TOOLBAR:
|
||||
return window_top_toolbar_open();
|
||||
case WC_VIEW_CLIPPING:
|
||||
return window_view_clipping_open();
|
||||
case WC_VIEWPORT:
|
||||
return window_viewport_open();
|
||||
case WC_WATER:
|
||||
return window_water_open();
|
||||
default:
|
||||
Console::Error::WriteLine("Unhandled window class (%d)", wc);
|
||||
return nullptr;
|
||||
case WC_ABOUT:
|
||||
return window_about_open();
|
||||
case WC_BOTTOM_TOOLBAR:
|
||||
return window_game_bottom_toolbar_open();
|
||||
case WC_CHANGELOG:
|
||||
return window_changelog_open();
|
||||
case WC_CHEATS:
|
||||
return window_cheats_open();
|
||||
case WC_CLEAR_SCENERY:
|
||||
return window_clear_scenery_open();
|
||||
case WC_CUSTOM_CURRENCY_CONFIG:
|
||||
return custom_currency_window_open();
|
||||
case WC_DEBUG_PAINT:
|
||||
return window_debug_paint_open();
|
||||
case WC_EDITOR_INVENTION_LIST:
|
||||
return window_editor_inventions_list_open();
|
||||
case WC_EDITOR_OBJECT_SELECTION:
|
||||
return window_editor_object_selection_open();
|
||||
case WC_EDTIOR_OBJECTIVE_OPTIONS:
|
||||
return window_editor_objective_options_open();
|
||||
case WC_EDITOR_SCENARIO_OPTIONS:
|
||||
return window_editor_scenario_options_open();
|
||||
case WC_FINANCES:
|
||||
return window_finances_open();
|
||||
case WC_FOOTPATH:
|
||||
return window_footpath_open();
|
||||
case WC_GUEST_LIST:
|
||||
return window_guest_list_open();
|
||||
case WC_LAND:
|
||||
return window_land_open();
|
||||
case WC_LAND_RIGHTS:
|
||||
return window_land_rights_open();
|
||||
case WC_MAIN_WINDOW:
|
||||
return window_main_open();
|
||||
case WC_MAP:
|
||||
return window_map_open();
|
||||
case WC_MAPGEN:
|
||||
return window_mapgen_open();
|
||||
case WC_MULTIPLAYER:
|
||||
return window_multiplayer_open();
|
||||
case WC_MUSIC_CREDITS:
|
||||
return window_music_credits_open();
|
||||
case WC_CONSTRUCT_RIDE:
|
||||
return window_new_ride_open();
|
||||
case WC_PARK_INFORMATION:
|
||||
return window_park_entrance_open();
|
||||
case WC_RECENT_NEWS:
|
||||
return window_news_open();
|
||||
case WC_RIDE_CONSTRUCTION:
|
||||
return window_ride_construction_open();
|
||||
case WC_RESEARCH:
|
||||
return window_research_open();
|
||||
case WC_RIDE_LIST:
|
||||
return window_ride_list_open();
|
||||
case WC_NOTIFICATION_OPTIONS:
|
||||
return window_news_options_open();
|
||||
case WC_OPTIONS:
|
||||
return window_options_open();
|
||||
case WC_SAVE_PROMPT:
|
||||
return window_save_prompt_open();
|
||||
case WC_SCENERY:
|
||||
return window_scenery_open();
|
||||
case WC_SERVER_LIST:
|
||||
return window_server_list_open();
|
||||
case WC_SERVER_START:
|
||||
return window_server_start_open();
|
||||
case WC_KEYBOARD_SHORTCUT_LIST:
|
||||
return window_shortcut_keys_open();
|
||||
case WC_STAFF_LIST:
|
||||
return window_staff_list_open();
|
||||
case WC_THEMES:
|
||||
return window_themes_open();
|
||||
case WC_TILE_INSPECTOR:
|
||||
return window_tile_inspector_open();
|
||||
case WC_TITLE_EXIT:
|
||||
return window_title_exit_open();
|
||||
case WC_TITLE_LOGO:
|
||||
return window_title_logo_open();
|
||||
case WC_TITLE_MENU:
|
||||
return window_title_menu_open();
|
||||
case WC_TITLE_OPTIONS:
|
||||
return window_title_options_open();
|
||||
case WC_TOP_TOOLBAR:
|
||||
return window_top_toolbar_open();
|
||||
case WC_VIEW_CLIPPING:
|
||||
return window_view_clipping_open();
|
||||
case WC_VIEWPORT:
|
||||
return window_viewport_open();
|
||||
case WC_WATER:
|
||||
return window_water_open();
|
||||
default:
|
||||
Console::Error::WriteLine("Unhandled window class (%d)", wc);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
rct_window * OpenView(uint8_t view) override
|
||||
rct_window* OpenView(uint8_t view) override
|
||||
{
|
||||
switch (view)
|
||||
{
|
||||
case WV_PARK_AWARDS:
|
||||
return window_park_awards_open();
|
||||
case WV_PARK_RATING:
|
||||
return window_park_rating_open();
|
||||
case WV_PARK_OBJECTIVE:
|
||||
return window_park_objective_open();
|
||||
case WV_PARK_GUESTS:
|
||||
return window_park_guests_open();
|
||||
case WV_FINANCES_RESEARCH:
|
||||
return window_finances_research_open();
|
||||
case WV_RIDE_RESEARCH:
|
||||
if (gConfigInterface.toolbar_show_research)
|
||||
{
|
||||
return this->OpenWindow(WC_RESEARCH);
|
||||
}
|
||||
else
|
||||
{
|
||||
return window_new_ride_open_research();
|
||||
}
|
||||
case WV_MAZE_CONSTRUCTION:
|
||||
return window_maze_construction_open();
|
||||
case WV_NETWORK_PASSWORD:
|
||||
return window_network_status_open_password();
|
||||
case WV_EDITOR_BOTTOM_TOOLBAR:
|
||||
return window_editor_bottom_toolbar_open();
|
||||
case WV_EDITOR_MAIN:
|
||||
return window_editor_main_open();
|
||||
default:
|
||||
return nullptr;
|
||||
case WV_PARK_AWARDS:
|
||||
return window_park_awards_open();
|
||||
case WV_PARK_RATING:
|
||||
return window_park_rating_open();
|
||||
case WV_PARK_OBJECTIVE:
|
||||
return window_park_objective_open();
|
||||
case WV_PARK_GUESTS:
|
||||
return window_park_guests_open();
|
||||
case WV_FINANCES_RESEARCH:
|
||||
return window_finances_research_open();
|
||||
case WV_RIDE_RESEARCH:
|
||||
if (gConfigInterface.toolbar_show_research)
|
||||
{
|
||||
return this->OpenWindow(WC_RESEARCH);
|
||||
}
|
||||
else
|
||||
{
|
||||
return window_new_ride_open_research();
|
||||
}
|
||||
case WV_MAZE_CONSTRUCTION:
|
||||
return window_maze_construction_open();
|
||||
case WV_NETWORK_PASSWORD:
|
||||
return window_network_status_open_password();
|
||||
case WV_EDITOR_BOTTOM_TOOLBAR:
|
||||
return window_editor_bottom_toolbar_open();
|
||||
case WV_EDITOR_MAIN:
|
||||
return window_editor_main_open();
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
rct_window * OpenDetails(uint8_t type, int32_t id) override
|
||||
rct_window* OpenDetails(uint8_t type, int32_t id) override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case WD_BANNER:
|
||||
return window_banner_open(id);
|
||||
case WD_DEMOLISH_RIDE:
|
||||
return window_ride_demolish_prompt_open(id);
|
||||
case WD_REFURBISH_RIDE:
|
||||
return window_ride_refurbish_prompt_open(id);
|
||||
case WD_NEW_CAMPAIGN:
|
||||
return window_new_campaign_open(id);
|
||||
case WD_SIGN:
|
||||
return window_sign_open(id);
|
||||
case WD_SIGN_SMALL:
|
||||
return window_sign_small_open(id);
|
||||
case WD_BANNER:
|
||||
return window_banner_open(id);
|
||||
case WD_DEMOLISH_RIDE:
|
||||
return window_ride_demolish_prompt_open(id);
|
||||
case WD_REFURBISH_RIDE:
|
||||
return window_ride_refurbish_prompt_open(id);
|
||||
case WD_NEW_CAMPAIGN:
|
||||
return window_new_campaign_open(id);
|
||||
case WD_SIGN:
|
||||
return window_sign_open(id);
|
||||
case WD_SIGN_SMALL:
|
||||
return window_sign_small_open(id);
|
||||
|
||||
case WD_PLAYER:
|
||||
return window_player_open(id);
|
||||
case WD_PLAYER:
|
||||
return window_player_open(id);
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
rct_window * ShowError(rct_string_id title, rct_string_id message) override
|
||||
rct_window* ShowError(rct_string_id title, rct_string_id message) override
|
||||
{
|
||||
return window_error_open(title, message);
|
||||
}
|
||||
|
||||
rct_window * OpenIntent(Intent * intent) override
|
||||
rct_window* OpenIntent(Intent* intent) override
|
||||
{
|
||||
switch (intent->GetWindowClass())
|
||||
{
|
||||
case WC_PEEP:
|
||||
return window_guest_open((rct_peep*)intent->GetPointerExtra(INTENT_EXTRA_PEEP));
|
||||
case WC_FIRE_PROMPT:
|
||||
return window_staff_fire_prompt_open((rct_peep*)intent->GetPointerExtra(INTENT_EXTRA_PEEP));
|
||||
case WC_INSTALL_TRACK:
|
||||
return window_install_track_open(intent->GetStringExtra(INTENT_EXTRA_PATH).c_str());
|
||||
case WC_GUEST_LIST:
|
||||
return window_guest_list_open_with_filter(intent->GetSIntExtra(INTENT_EXTRA_GUEST_LIST_FILTER), intent->GetSIntExtra(INTENT_EXTRA_RIDE_ID));
|
||||
case WC_LOADSAVE:
|
||||
{
|
||||
uint32_t type = intent->GetUIntExtra(INTENT_EXTRA_LOADSAVE_TYPE);
|
||||
std::string defaultName = intent->GetStringExtra(INTENT_EXTRA_PATH);
|
||||
loadsave_callback callback = (loadsave_callback) intent->GetPointerExtra(INTENT_EXTRA_CALLBACK);
|
||||
rct_window *w = window_loadsave_open(type, defaultName.c_str());
|
||||
window_loadsave_set_loadsave_callback(callback);
|
||||
case WC_PEEP:
|
||||
return window_guest_open((rct_peep*)intent->GetPointerExtra(INTENT_EXTRA_PEEP));
|
||||
case WC_FIRE_PROMPT:
|
||||
return window_staff_fire_prompt_open((rct_peep*)intent->GetPointerExtra(INTENT_EXTRA_PEEP));
|
||||
case WC_INSTALL_TRACK:
|
||||
return window_install_track_open(intent->GetStringExtra(INTENT_EXTRA_PATH).c_str());
|
||||
case WC_GUEST_LIST:
|
||||
return window_guest_list_open_with_filter(
|
||||
intent->GetSIntExtra(INTENT_EXTRA_GUEST_LIST_FILTER), intent->GetSIntExtra(INTENT_EXTRA_RIDE_ID));
|
||||
case WC_LOADSAVE:
|
||||
{
|
||||
uint32_t type = intent->GetUIntExtra(INTENT_EXTRA_LOADSAVE_TYPE);
|
||||
std::string defaultName = intent->GetStringExtra(INTENT_EXTRA_PATH);
|
||||
loadsave_callback callback = (loadsave_callback)intent->GetPointerExtra(INTENT_EXTRA_CALLBACK);
|
||||
rct_window* w = window_loadsave_open(type, defaultName.c_str());
|
||||
window_loadsave_set_loadsave_callback(callback);
|
||||
|
||||
return w;
|
||||
}
|
||||
case WC_MANAGE_TRACK_DESIGN:
|
||||
return window_track_manage_open((track_design_file_ref *) intent->GetPointerExtra(INTENT_EXTRA_TRACK_DESIGN));
|
||||
case WC_NETWORK_STATUS:
|
||||
{
|
||||
std::string message = intent->GetStringExtra(INTENT_EXTRA_MESSAGE);
|
||||
close_callback callback = intent->GetCloseCallbackExtra(INTENT_EXTRA_CALLBACK);
|
||||
return window_network_status_open(message.c_str(), callback);
|
||||
}
|
||||
case WC_OBJECT_LOAD_ERROR:
|
||||
{
|
||||
std::string path = intent->GetStringExtra(INTENT_EXTRA_PATH);
|
||||
const rct_object_entry * objects = (rct_object_entry *) intent->GetPointerExtra(INTENT_EXTRA_LIST);
|
||||
size_t count = intent->GetUIntExtra(INTENT_EXTRA_LIST_COUNT);
|
||||
window_object_load_error_open(const_cast<utf8 *>(path.c_str()), count, objects);
|
||||
return w;
|
||||
}
|
||||
case WC_MANAGE_TRACK_DESIGN:
|
||||
return window_track_manage_open((track_design_file_ref*)intent->GetPointerExtra(INTENT_EXTRA_TRACK_DESIGN));
|
||||
case WC_NETWORK_STATUS:
|
||||
{
|
||||
std::string message = intent->GetStringExtra(INTENT_EXTRA_MESSAGE);
|
||||
close_callback callback = intent->GetCloseCallbackExtra(INTENT_EXTRA_CALLBACK);
|
||||
return window_network_status_open(message.c_str(), callback);
|
||||
}
|
||||
case WC_OBJECT_LOAD_ERROR:
|
||||
{
|
||||
std::string path = intent->GetStringExtra(INTENT_EXTRA_PATH);
|
||||
const rct_object_entry* objects = (rct_object_entry*)intent->GetPointerExtra(INTENT_EXTRA_LIST);
|
||||
size_t count = intent->GetUIntExtra(INTENT_EXTRA_LIST_COUNT);
|
||||
window_object_load_error_open(const_cast<utf8*>(path.c_str()), count, objects);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
case WC_RIDE:
|
||||
return window_ride_main_open(intent->GetSIntExtra(INTENT_EXTRA_RIDE_ID));
|
||||
case WC_TRACK_DESIGN_PLACE:
|
||||
return window_track_place_open((track_design_file_ref *) intent->GetPointerExtra(INTENT_EXTRA_TRACK_DESIGN));
|
||||
case WC_TRACK_DESIGN_LIST:
|
||||
{
|
||||
ride_list_item rideItem;
|
||||
rideItem.type = intent->GetUIntExtra(INTENT_EXTRA_RIDE_TYPE);
|
||||
rideItem.entry_index = intent->GetUIntExtra(INTENT_EXTRA_RIDE_ENTRY_INDEX);
|
||||
return window_track_list_open(rideItem);
|
||||
}
|
||||
case WC_SCENARIO_SELECT:
|
||||
return window_scenarioselect_open((scenarioselect_callback) intent->GetPointerExtra(INTENT_EXTRA_CALLBACK), false);
|
||||
case WD_VEHICLE:
|
||||
return window_ride_open_vehicle((rct_vehicle *) intent->GetPointerExtra(INTENT_EXTRA_VEHICLE));
|
||||
case WD_TRACK:
|
||||
return window_ride_open_track((rct_tile_element *) intent->GetPointerExtra(INTENT_EXTRA_TILE_ELEMENT));
|
||||
case INTENT_ACTION_NEW_RIDE_OF_TYPE:
|
||||
{
|
||||
// Open ride list window
|
||||
auto w = window_new_ride_open();
|
||||
return nullptr;
|
||||
}
|
||||
case WC_RIDE:
|
||||
return window_ride_main_open(intent->GetSIntExtra(INTENT_EXTRA_RIDE_ID));
|
||||
case WC_TRACK_DESIGN_PLACE:
|
||||
return window_track_place_open((track_design_file_ref*)intent->GetPointerExtra(INTENT_EXTRA_TRACK_DESIGN));
|
||||
case WC_TRACK_DESIGN_LIST:
|
||||
{
|
||||
ride_list_item rideItem;
|
||||
rideItem.type = intent->GetUIntExtra(INTENT_EXTRA_RIDE_TYPE);
|
||||
rideItem.entry_index = intent->GetUIntExtra(INTENT_EXTRA_RIDE_ENTRY_INDEX);
|
||||
return window_track_list_open(rideItem);
|
||||
}
|
||||
case WC_SCENARIO_SELECT:
|
||||
return window_scenarioselect_open(
|
||||
(scenarioselect_callback)intent->GetPointerExtra(INTENT_EXTRA_CALLBACK), false);
|
||||
case WD_VEHICLE:
|
||||
return window_ride_open_vehicle((rct_vehicle*)intent->GetPointerExtra(INTENT_EXTRA_VEHICLE));
|
||||
case WD_TRACK:
|
||||
return window_ride_open_track((rct_tile_element*)intent->GetPointerExtra(INTENT_EXTRA_TILE_ELEMENT));
|
||||
case INTENT_ACTION_NEW_RIDE_OF_TYPE:
|
||||
{
|
||||
// Open ride list window
|
||||
auto w = window_new_ride_open();
|
||||
|
||||
// Switch to right tab and scroll to ride location
|
||||
ride_list_item rideItem;
|
||||
rideItem.type = intent->GetUIntExtra(INTENT_EXTRA_RIDE_TYPE);
|
||||
rideItem.entry_index = intent->GetUIntExtra(INTENT_EXTRA_RIDE_ENTRY_INDEX);
|
||||
window_new_ride_focus(rideItem);
|
||||
// Switch to right tab and scroll to ride location
|
||||
ride_list_item rideItem;
|
||||
rideItem.type = intent->GetUIntExtra(INTENT_EXTRA_RIDE_TYPE);
|
||||
rideItem.entry_index = intent->GetUIntExtra(INTENT_EXTRA_RIDE_ENTRY_INDEX);
|
||||
window_new_ride_focus(rideItem);
|
||||
|
||||
return w;
|
||||
}
|
||||
default:
|
||||
Console::Error::WriteLine("Unhandled window class for intent (%d)", intent->GetWindowClass());
|
||||
return nullptr;
|
||||
return w;
|
||||
}
|
||||
default:
|
||||
Console::Error::WriteLine("Unhandled window class for intent (%d)", intent->GetWindowClass());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void BroadcastIntent(const Intent &intent) override
|
||||
void BroadcastIntent(const Intent& intent) override
|
||||
{
|
||||
switch (intent.GetWindowClass())
|
||||
{
|
||||
case INTENT_ACTION_MAP:
|
||||
window_map_reset();
|
||||
break;
|
||||
case INTENT_ACTION_MAP:
|
||||
window_map_reset();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_REFRESH_NEW_RIDES:
|
||||
window_new_ride_init_vars();
|
||||
break;
|
||||
case INTENT_ACTION_REFRESH_NEW_RIDES:
|
||||
window_new_ride_init_vars();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_REFRESH_RIDE_LIST:
|
||||
{
|
||||
auto window = window_find_by_class(WC_RIDE_LIST);
|
||||
if (window != nullptr)
|
||||
case INTENT_ACTION_REFRESH_RIDE_LIST:
|
||||
{
|
||||
window_ride_list_refresh_list(window);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case INTENT_ACTION_UPDATE_MAZE_CONSTRUCTION:
|
||||
window_maze_construction_update_pressed_widgets();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_RIDE_CONSTRUCTION_FOCUS:
|
||||
{
|
||||
auto rideIndex = intent.GetUIntExtra(INTENT_EXTRA_RIDE_ID);
|
||||
auto w = window_find_by_class(WC_RIDE_CONSTRUCTION);
|
||||
if (w == nullptr || w->number != rideIndex)
|
||||
{
|
||||
window_close_construction_windows();
|
||||
_currentRideIndex = rideIndex;
|
||||
w = OpenWindow(WC_RIDE_CONSTRUCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
ride_construction_invalidate_current_track();
|
||||
_currentRideIndex = rideIndex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_PIECES:
|
||||
window_ride_construction_update_enabled_track_pieces();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_ACTIVE_ELEMENTS:
|
||||
window_ride_construction_update_active_elements_impl();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_INIT_SCENERY:
|
||||
window_scenery_init();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_SET_DEFAULT_SCENERY_CONFIG:
|
||||
window_scenery_set_default_placement_configuration();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_REFRESH_SCENERY:
|
||||
window_scenery_reset_selected_scenery_items();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_INVALIDATE_TICKER_NEWS:
|
||||
window_game_bottom_toolbar_invalidate_news_item();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_REFRESH_GUEST_LIST:
|
||||
window_guest_list_refresh_list();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_REFRESH_STAFF_LIST:
|
||||
{
|
||||
auto w = window_find_by_class(WC_STAFF_LIST);
|
||||
if (w != nullptr)
|
||||
{
|
||||
w->no_list_items = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case INTENT_ACTION_CLEAR_TILE_INSPECTOR_CLIPBOARD:
|
||||
window_tile_inspector_clear_clipboard();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_INVALIDATE_VEHICLE_WINDOW:
|
||||
{
|
||||
rct_vehicle * vehicle = static_cast<rct_vehicle *>(intent.GetPointerExtra(INTENT_EXTRA_VEHICLE));
|
||||
int32_t viewVehicleIndex;
|
||||
Ride * ride;
|
||||
rct_window * w;
|
||||
|
||||
w = window_find_by_number(WC_RIDE, vehicle->ride);
|
||||
if (w == nullptr)
|
||||
return;
|
||||
|
||||
ride = get_ride(vehicle->ride);
|
||||
viewVehicleIndex = w->ride.view - 1;
|
||||
if (viewVehicleIndex < 0 || viewVehicleIndex >= ride->num_vehicles)
|
||||
return;
|
||||
|
||||
if (vehicle->sprite_index != ride->vehicles[viewVehicleIndex])
|
||||
return;
|
||||
|
||||
window_invalidate(w);
|
||||
break;
|
||||
}
|
||||
|
||||
case INTENT_ACTION_RIDE_PAINT_RESET_VEHICLE:
|
||||
{
|
||||
auto rideIndex = intent.GetUIntExtra(INTENT_EXTRA_RIDE_ID);
|
||||
auto w = window_find_by_number(WC_RIDE, rideIndex);
|
||||
if (w != nullptr)
|
||||
{
|
||||
if (w->page == 4) // WINDOW_RIDE_PAGE_COLOUR
|
||||
{
|
||||
w->vehicleIndex = 0;
|
||||
auto window = window_find_by_class(WC_RIDE_LIST);
|
||||
if (window != nullptr)
|
||||
{
|
||||
window_ride_list_refresh_list(window);
|
||||
}
|
||||
window_invalidate(w);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case INTENT_ACTION_UPDATE_CLIMATE:
|
||||
gToolbarDirtyFlags |= BTM_TB_DIRTY_FLAG_CLIMATE;
|
||||
window_invalidate_by_class(WC_GUEST_LIST);
|
||||
break;
|
||||
case INTENT_ACTION_UPDATE_MAZE_CONSTRUCTION:
|
||||
window_maze_construction_update_pressed_widgets();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_UPDATE_PARK_RATING:
|
||||
gToolbarDirtyFlags |= BTM_TB_DIRTY_FLAG_PARK_RATING;
|
||||
window_invalidate_by_class(WC_PARK_INFORMATION);
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_UPDATE_DATE:
|
||||
gToolbarDirtyFlags |= BTM_TB_DIRTY_FLAG_DATE;
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_UPDATE_CASH:
|
||||
window_invalidate_by_class(WC_FINANCES);
|
||||
gToolbarDirtyFlags |= BTM_TB_DIRTY_FLAG_MONEY;
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_UPDATE_BANNER:
|
||||
{
|
||||
uint8_t bannerIndex = static_cast<uint8_t>(intent.GetUIntExtra(INTENT_EXTRA_BANNER_INDEX));
|
||||
|
||||
rct_window * w = window_find_by_number(WC_BANNER, bannerIndex);
|
||||
if (w != nullptr)
|
||||
case INTENT_ACTION_RIDE_CONSTRUCTION_FOCUS:
|
||||
{
|
||||
window_invalidate(w);
|
||||
auto rideIndex = intent.GetUIntExtra(INTENT_EXTRA_RIDE_ID);
|
||||
auto w = window_find_by_class(WC_RIDE_CONSTRUCTION);
|
||||
if (w == nullptr || w->number != rideIndex)
|
||||
{
|
||||
window_close_construction_windows();
|
||||
_currentRideIndex = rideIndex;
|
||||
w = OpenWindow(WC_RIDE_CONSTRUCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
ride_construction_invalidate_current_track();
|
||||
_currentRideIndex = rideIndex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INTENT_ACTION_UPDATE_RESEARCH:
|
||||
window_invalidate_by_class(WC_FINANCES);
|
||||
window_invalidate_by_class(WC_RESEARCH);
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_PIECES:
|
||||
window_ride_construction_update_enabled_track_pieces();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_ACTIVE_ELEMENTS:
|
||||
window_ride_construction_update_active_elements_impl();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_INIT_SCENERY:
|
||||
window_scenery_init();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_SET_DEFAULT_SCENERY_CONFIG:
|
||||
window_scenery_set_default_placement_configuration();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_REFRESH_SCENERY:
|
||||
window_scenery_reset_selected_scenery_items();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_INVALIDATE_TICKER_NEWS:
|
||||
window_game_bottom_toolbar_invalidate_news_item();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_REFRESH_GUEST_LIST:
|
||||
window_guest_list_refresh_list();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_REFRESH_STAFF_LIST:
|
||||
{
|
||||
auto w = window_find_by_class(WC_STAFF_LIST);
|
||||
if (w != nullptr)
|
||||
{
|
||||
w->no_list_items = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case INTENT_ACTION_CLEAR_TILE_INSPECTOR_CLIPBOARD:
|
||||
window_tile_inspector_clear_clipboard();
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_INVALIDATE_VEHICLE_WINDOW:
|
||||
{
|
||||
rct_vehicle* vehicle = static_cast<rct_vehicle*>(intent.GetPointerExtra(INTENT_EXTRA_VEHICLE));
|
||||
int32_t viewVehicleIndex;
|
||||
Ride* ride;
|
||||
rct_window* w;
|
||||
|
||||
w = window_find_by_number(WC_RIDE, vehicle->ride);
|
||||
if (w == nullptr)
|
||||
return;
|
||||
|
||||
ride = get_ride(vehicle->ride);
|
||||
viewVehicleIndex = w->ride.view - 1;
|
||||
if (viewVehicleIndex < 0 || viewVehicleIndex >= ride->num_vehicles)
|
||||
return;
|
||||
|
||||
if (vehicle->sprite_index != ride->vehicles[viewVehicleIndex])
|
||||
return;
|
||||
|
||||
window_invalidate(w);
|
||||
break;
|
||||
}
|
||||
|
||||
case INTENT_ACTION_RIDE_PAINT_RESET_VEHICLE:
|
||||
{
|
||||
auto rideIndex = intent.GetUIntExtra(INTENT_EXTRA_RIDE_ID);
|
||||
auto w = window_find_by_number(WC_RIDE, rideIndex);
|
||||
if (w != nullptr)
|
||||
{
|
||||
if (w->page == 4) // WINDOW_RIDE_PAGE_COLOUR
|
||||
{
|
||||
w->vehicleIndex = 0;
|
||||
}
|
||||
window_invalidate(w);
|
||||
}
|
||||
}
|
||||
|
||||
case INTENT_ACTION_UPDATE_CLIMATE:
|
||||
gToolbarDirtyFlags |= BTM_TB_DIRTY_FLAG_CLIMATE;
|
||||
window_invalidate_by_class(WC_GUEST_LIST);
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_UPDATE_PARK_RATING:
|
||||
gToolbarDirtyFlags |= BTM_TB_DIRTY_FLAG_PARK_RATING;
|
||||
window_invalidate_by_class(WC_PARK_INFORMATION);
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_UPDATE_DATE:
|
||||
gToolbarDirtyFlags |= BTM_TB_DIRTY_FLAG_DATE;
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_UPDATE_CASH:
|
||||
window_invalidate_by_class(WC_FINANCES);
|
||||
gToolbarDirtyFlags |= BTM_TB_DIRTY_FLAG_MONEY;
|
||||
break;
|
||||
|
||||
case INTENT_ACTION_UPDATE_BANNER:
|
||||
{
|
||||
uint8_t bannerIndex = static_cast<uint8_t>(intent.GetUIntExtra(INTENT_EXTRA_BANNER_INDEX));
|
||||
|
||||
rct_window* w = window_find_by_number(WC_BANNER, bannerIndex);
|
||||
if (w != nullptr)
|
||||
{
|
||||
window_invalidate(w);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INTENT_ACTION_UPDATE_RESEARCH:
|
||||
window_invalidate_by_class(WC_FINANCES);
|
||||
window_invalidate_by_class(WC_RESEARCH);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -438,12 +442,12 @@ public:
|
|||
{
|
||||
switch (windowClass)
|
||||
{
|
||||
case WC_NETWORK_STATUS:
|
||||
window_network_status_close();
|
||||
break;
|
||||
case WC_NETWORK_STATUS:
|
||||
window_network_status_close();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -516,7 +520,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
IWindowManager * OpenRCT2::Ui::CreateWindowManager()
|
||||
IWindowManager* OpenRCT2::Ui::CreateWindowManager()
|
||||
{
|
||||
return new WindowManager();
|
||||
}
|
||||
|
|
|
@ -13,5 +13,5 @@ namespace OpenRCT2::Ui
|
|||
{
|
||||
interface IWindowManager;
|
||||
|
||||
IWindowManager * CreateWindowManager();
|
||||
}
|
||||
IWindowManager* CreateWindowManager();
|
||||
} // namespace OpenRCT2::Ui
|
||||
|
|
Loading…
Reference in New Issue