Introduce shortcut contexts

This commit is contained in:
Tamás Bálint Misius 2019-09-25 14:21:50 +02:00
parent 348ef06a1f
commit 9e3158b4dc
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
17 changed files with 984 additions and 721 deletions

View File

@ -1946,11 +1946,6 @@ std::vector<bool> Client::GetPrefBoolArray(ByteString prop)
return std::vector<bool>(); return std::vector<bool>();
} }
Json::Value Client::GetPrefJson(ByteString prop, Json::Value defaultValue)
{
return GetPref(preferences, prop, defaultValue);
}
// Helper preference setting function. // Helper preference setting function.
// To actually save any changes to preferences, we need to directly do preferences[property] = thing // To actually save any changes to preferences, we need to directly do preferences[property] = thing
// any other way will set the value of a copy of preferences, not the original // any other way will set the value of a copy of preferences, not the original
@ -1984,18 +1979,6 @@ void Client::SetPref(ByteString prop, Json::Value value)
} }
} }
void Client::ClearPref(ByteString prop)
{
try
{
preferences[prop].clear();
}
catch (std::exception & e)
{
}
}
void Client::SetPref(ByteString prop, std::vector<Json::Value> value) void Client::SetPref(ByteString prop, std::vector<Json::Value> value)
{ {
try try

View File

@ -3,6 +3,8 @@
#include <vector> #include <vector>
#include <list> #include <list>
#include <tuple>
#include <utility>
#include "common/String.h" #include "common/String.h"
#include "common/Singleton.h" #include "common/Singleton.h"
@ -10,6 +12,77 @@
#include "User.h" #include "User.h"
template<class Item>
void JsonArrayItemToTupleItem(Item &i, Json::Value const &v);
template<>
inline void JsonArrayItemToTupleItem<bool>(bool &i, Json::Value const &v)
{
i = v.asBool();
}
template<>
inline void JsonArrayItemToTupleItem<int>(int &i, Json::Value const &v)
{
i = v.asInt();
}
template<>
inline void JsonArrayItemToTupleItem<ByteString>(ByteString &i, Json::Value const &v)
{
auto s = v.asString();
i = ByteString(s.begin(), s.end());
}
template<std::size_t Item = 0, class... Types>
typename std::enable_if<Item == sizeof...(Types), void>::type
JsonArrayToTuple(std::tuple<Types...> &, Json::Value const &)
{
}
template<std::size_t Item = 0, class... Types>
typename std::enable_if<Item < sizeof...(Types), void>::type
JsonArrayToTuple(std::tuple<Types...> &t, Json::Value const &va)
{
JsonArrayItemToTupleItem(std::get<Item>(t), va[(Json::ArrayIndex)Item]);
JsonArrayToTuple<Item + 1, Types...>(t, va);
}
template<class Item>
void JsonArrayItemFromTupleItem(Item const &i, Json::Value &v);
template<>
inline void JsonArrayItemFromTupleItem<bool>(bool const &i, Json::Value &v)
{
v = Json::Value((bool)i);
}
template<>
inline void JsonArrayItemFromTupleItem<int>(int const &i, Json::Value &v)
{
v = Json::Value((Json::Int)i);
}
template<>
inline void JsonArrayItemFromTupleItem<ByteString>(ByteString const &i, Json::Value &v)
{
v = Json::Value(std::string(i.begin(), i.end()));
}
template<std::size_t Item = 0, class... Types>
typename std::enable_if<Item == sizeof...(Types), void>::type
JsonArrayFromTuple(std::tuple<Types...> const &, Json::Value &)
{
}
template<std::size_t Item = 0, class... Types>
typename std::enable_if<Item < sizeof...(Types), void>::type
JsonArrayFromTuple(std::tuple<Types...> const &t, Json::Value &va)
{
JsonArrayItemFromTupleItem(std::get<Item>(t), va[(Json::ArrayIndex)Item]);
JsonArrayFromTuple<Item + 1, Types...>(t, va);
}
class SaveInfo; class SaveInfo;
class SaveFile; class SaveFile;
class SaveComment; class SaveComment;
@ -181,12 +254,40 @@ public:
std::vector<int> GetPrefIntegerArray(ByteString prop); std::vector<int> GetPrefIntegerArray(ByteString prop);
std::vector<unsigned int> GetPrefUIntegerArray(ByteString prop); std::vector<unsigned int> GetPrefUIntegerArray(ByteString prop);
std::vector<bool> GetPrefBoolArray(ByteString prop); std::vector<bool> GetPrefBoolArray(ByteString prop);
Json::Value GetPrefJson(ByteString prop, Json::Value defaultValue = Json::nullValue);
void SetPref(ByteString prop, Json::Value value); void SetPref(ByteString prop, Json::Value value);
void SetPref(ByteString property, std::vector<Json::Value> value); void SetPref(ByteString property, std::vector<Json::Value> value);
void SetPrefUnicode(ByteString prop, String value); void SetPrefUnicode(ByteString prop, String value);
void ClearPref(ByteString prop);
template<class Tuple>
std::vector<Tuple> GetPrefTupleArray(ByteString prop)
{
try
{
Json::Value arr = GetPref(preferences, prop);
std::vector<Tuple> ret(arr.size());
for (int i = 0; i < (int)arr.size(); i++)
{
JsonArrayToTuple(ret[i], arr[i]);
}
return ret;
}
catch (std::exception &)
{
}
return std::vector<Tuple>();
}
template<class Tuple>
void SetPref(ByteString prop, std::vector<Tuple> const &value)
{
std::vector<Json::Value> arr(value.size());
for (int i = 0; i < (int)arr.size(); i++)
{
JsonArrayFromTuple(value[i], arr[i]);
}
SetPref(prop, arr);
}
}; };
#endif // CLIENT_H #endif // CLIENT_H

View File

@ -661,7 +661,7 @@ bool GameController::MouseDown(int x, int y, unsigned button)
{ {
MouseDownEvent ev(x, y, button); MouseDownEvent ev(x, y, button);
bool ret = commandInterface->HandleEvent(LuaEvents::mousedown, &ev); bool ret = commandInterface->HandleEvent(LuaEvents::mousedown, &ev);
if (ret && y<YRES && x<XRES && !gameView->GetPlacingSave() && !gameView->GetPlacingZoom()) if (ret && y<YRES && x<XRES && gameView->IsIdle())
{ {
ui::Point point = gameModel->AdjustZoomCoords(ui::Point(x, y)); ui::Point point = gameModel->AdjustZoomCoords(ui::Point(x, y));
x = point.X; x = point.X;
@ -687,7 +687,7 @@ bool GameController::MouseUp(int x, int y, unsigned button, char type)
bool ret = commandInterface->HandleEvent(LuaEvents::mouseup, &ev); bool ret = commandInterface->HandleEvent(LuaEvents::mouseup, &ev);
if (type) if (type)
return ret; return ret;
if (ret && foundSignID != -1 && y<YRES && x<XRES && !gameView->GetPlacingSave()) if (ret && foundSignID != -1 && y<YRES && x<XRES && gameView->IsIdle())
{ {
ui::Point point = gameModel->AdjustZoomCoords(ui::Point(x, y)); ui::Point point = gameModel->AdjustZoomCoords(ui::Point(x, y));
x = point.X; x = point.X;
@ -752,7 +752,7 @@ bool GameController::KeyPress(int key, int scan, bool repeat, bool shift, bool c
if (ret) if (ret)
{ {
Simulation * sim = gameModel->GetSimulation(); Simulation * sim = gameModel->GetSimulation();
if (!gameView->GetPlacingSave()) if (gameView->IsIdle())
{ {
// Go right command // Go right command
if (key == SDLK_RIGHT) if (key == SDLK_RIGHT)

View File

@ -156,6 +156,8 @@ GameModel::GameModel():
mouseClickRequired = Client::Ref().GetPrefBool("MouseClickRequired", false); mouseClickRequired = Client::Ref().GetPrefBool("MouseClickRequired", false);
includePressure = Client::Ref().GetPrefBool("Simulation.IncludePressure", true); includePressure = Client::Ref().GetPrefBool("Simulation.IncludePressure", true);
keyconfig = Client::Ref().GetPrefTupleArray<decltype(keyconfig)::value_type>("Keyconfig");
} }
GameModel::~GameModel() GameModel::~GameModel()
@ -188,6 +190,8 @@ GameModel::~GameModel()
Client::Ref().SetPref("MouseClickRequired", mouseClickRequired); Client::Ref().SetPref("MouseClickRequired", mouseClickRequired);
Client::Ref().SetPref("Simulation.IncludePressure", includePressure); Client::Ref().SetPref("Simulation.IncludePressure", includePressure);
Client::Ref().SetPref("Keyconfig", keyconfig);
Favorite::Ref().SaveFavoritesToPrefs(); Favorite::Ref().SaveFavoritesToPrefs();
for (size_t i = 0; i < menuList.size(); i++) for (size_t i = 0; i < menuList.size(); i++)
@ -546,6 +550,7 @@ void GameModel::AddObserver(GameView * observer){
observer->NotifyColourActivePresetChanged(this); observer->NotifyColourActivePresetChanged(this);
observer->NotifyQuickOptionsChanged(this); observer->NotifyQuickOptionsChanged(this);
observer->NotifyLastToolChanged(this); observer->NotifyLastToolChanged(this);
observer->NotifyKeyconfigChanged(this);
UpdateQuickOptions(); UpdateQuickOptions();
} }
@ -691,11 +696,11 @@ void GameModel::SetSave(SaveInfo * newSave, bool invertIncludePressure)
UpdateQuickOptions(); UpdateQuickOptions();
} }
void GameModel::NotifyKeyBindingsChanged() void GameModel::notifyKeyconfigChanged()
{ {
for (auto observer : observers) for (auto observer : observers)
{ {
observer->NotifyKeyBindingsChanged(this); observer->NotifyKeyconfigChanged(this);
} }
} }
@ -1328,3 +1333,14 @@ void GameModel::SetIncludePressure(bool includePressure_)
{ {
includePressure = includePressure_; includePressure = includePressure_;
} }
Keyconfig GameModel::GetKeyconfig()
{
return keyconfig;
}
void GameModel::SetKeyconfig(Keyconfig keyconfig_)
{
keyconfig = keyconfig_;
notifyKeyconfigChanged();
}

View File

@ -7,6 +7,7 @@
#include "gui/interface/Colour.h" #include "gui/interface/Colour.h"
#include "client/User.h" #include "client/User.h"
#include "gui/interface/Point.h" #include "gui/interface/Point.h"
#include "Keyconfig.h"
class Menu; class Menu;
class Tool; class Tool;
@ -103,6 +104,10 @@ private:
void notifyToolTipChanged(); void notifyToolTipChanged();
void notifyQuickOptionsChanged(); void notifyQuickOptionsChanged();
void notifyLastToolChanged(); void notifyLastToolChanged();
void notifyKeyconfigChanged();
Keyconfig keyconfig;
public: public:
GameModel(); GameModel();
~GameModel(); ~GameModel();
@ -159,6 +164,9 @@ public:
int GetBrushID(); int GetBrushID();
void SetBrushID(int i); void SetBrushID(int i);
Keyconfig GetKeyconfig();
void SetKeyconfig(Keyconfig keyconfig);
void SetVote(int direction); void SetVote(int direction);
SaveInfo * GetSave(); SaveInfo * GetSave();
SaveFile * GetSaveFile(); SaveFile * GetSaveFile();
@ -208,7 +216,6 @@ public:
void SetMouseClickRequired(bool mouseClickRequired); void SetMouseClickRequired(bool mouseClickRequired);
bool GetIncludePressure(); bool GetIncludePressure();
void SetIncludePressure(bool includePressure); void SetIncludePressure(bool includePressure);
void NotifyKeyBindingsChanged();
std::vector<Notification*> GetNotifications(); std::vector<Notification*> GetNotifications();
void AddNotification(Notification * notification); void AddNotification(Notification * notification);

View File

@ -36,7 +36,10 @@
#include "simulation/SimulationData.h" #include "simulation/SimulationData.h"
#include "simulation/ElementDefs.h" #include "simulation/ElementDefs.h"
#include "ElementClasses.h" #include "ElementClasses.h"
#include "gui/keyconfig/KeyconfigMap.h" // #include "gui/keyconfig/KeyconfigMap.h"
#include <algorithm>
#include <cassert>
#ifdef GetUserName #ifdef GetUserName
# undef GetUserName // dammit windows # undef GetUserName // dammit windows
@ -211,7 +214,6 @@ GameView::GameView():
drawMode(DrawPoints), drawMode(DrawPoints),
drawPoint1(0, 0), drawPoint1(0, 0),
drawPoint2(0, 0), drawPoint2(0, 0),
selectMode(SelectNone),
selectPoint1(0, 0), selectPoint1(0, 0),
selectPoint2(0, 0), selectPoint2(0, 0),
currentMouse(0, 0), currentMouse(0, 0),
@ -219,7 +221,6 @@ GameView::GameView():
placeSaveThumb(NULL), placeSaveThumb(NULL),
placeSaveOffset(0, 0) placeSaveOffset(0, 0)
{ {
int currentX = 1; int currentX = 1;
//Set up UI //Set up UI
class SearchAction : public ui::ButtonAction class SearchAction : public ui::ButtonAction
@ -464,9 +465,249 @@ GameView::GameView():
colourPicker = new ui::Button(ui::Point((XRES/2)-8, YRES+1), ui::Point(16, 16), "", "Pick Colour"); colourPicker = new ui::Button(ui::Point((XRES/2)-8, YRES+1), ui::Point(16, 16), "", "Pick Colour");
colourPicker->SetActionCallback(new ColourPickerAction(this)); colourPicker->SetActionCallback(new ColourPickerAction(this));
// write keyboard bindings prefs if they are absent AddFunction("DEFAULT_FUN_TOGGLE_CONSOLE", "Toggle Console", [this]() {
keyboardBindingModel.LoadBindingPrefs(); SDL_StopTextInput();
keyboardBindingModel.WriteDefaultPrefs(); SDL_StartTextInput();
c->ShowConsole();
});
AddFunction("DEFAULT_FUN_PAUSE_SIMULATION", "Pause Simulation", [this]() {
c->SetPaused();
});
AddFunction("DEFAULT_FUN_UNDO", "Undo", [this]() {
if (!isMouseDown)
{
c->HistoryRestore();
}
});
AddFunction("DEFAULT_FUN_REDO", "Redo", [this]() {
if (!isMouseDown)
{
c->HistoryForward();
}
});
AddFunction("DEFAULT_FUN_ENABLE_ZOOM", "Enable Zoom", [this]() {
// sticky = altBehaviour;
isMouseDown = false;
zoomCursorFixed = false;
c->SetZoomEnabled(true);
}, [this]() {
if (!zoomCursorFixed)
{
c->SetZoomEnabled(false);
}
});
AddFunction("DEFAULT_FUN_PROPERTY_TOOL", "Switch to Property Tool", [this]() {
c->SetActiveTool(1, "DEFAULT_UI_PROPERTY");
});
AddFunction("DEFAULT_FUN_TOGGLE_DEBUG_HUD", "Toggle Debug HUD", [this]() {
SetDebugHUD(!GetDebugHUD());
});
AddFunction("DEFAULT_FUN_RELOAD_SIMULATION", "Reload Simulation", [this]() {
c->ReloadSim();
});
AddFunction("DEFAULT_FUN_SAVE_AUTHORSHIP_INFO", "Show Authorship Info", [this]() {
switch (Client::Ref().GetAuthUser().UserElevation)
{
case User::ElevationModerator:
case User::ElevationAdmin:
new InformationMessage("Save authorship info", ByteString(Client::Ref().GetAuthorInfo().toStyledString()).FromUtf8(), true);
break;
default:
break;
}
});
AddFunction("DEFAULT_FUN_OPEN_ELEMENT_SEARCH", "Open Element Search", [this]() {
c->OpenElementSearch();
});
AddFunction("DEFAULT_FUN_FIND_MODE", "Toggle Find Mode", [this]() {
Tool *active = c->GetActiveTool(0);
if (!active->GetIdentifier().Contains("_PT_") || (ren->findingElement == active->GetToolID()))
{
ren->findingElement = 0;
}
else
{
ren->findingElement = active->GetToolID();
}
});
AddFunction("DEFAULT_FUN_FRAME_STEP", "Next Frame", [this]() {
c->FrameStep();
});
AddFunction("DEFAULT_FUN_SHOW_GRAVITY_GRID", "Toggle Gravity Grid", [this]() {
c->ShowGravityGrid();
});
AddFunction("DEFAULT_FUN_DECREASE_GRAVITY_GRID_SIZE", "Decrease Gravity Grid Size", [this]() {
c->AdjustGridSize(-1);
});
AddFunction("DEFAULT_FUN_INCREASE_GRAVITY_GRID_SIZE", "Increase Gravity Grid Size", [this]() {
c->AdjustGridSize(1);
});
AddFunction("DEFAULT_FUN_TOGGLE_INTRO_TEXT", "Toggle Intro Text", [this]() {
if (!introText)
{
introText = 8047;
}
else
{
introText = 0;
}
});
AddFunction("DEFAULT_FUN_TOGGLE_HUD", "Toggle HUD", [this]() {
showHud = !showHud;
});
AddFunction("DEFAULT_FUN_TOGGLE_DECORATIONS_LAYER", "Toggle Decorations Layer", [this]() {
c->SetDecoration();
});
AddFunction("DEFAULT_FUN_TOGGLE_DECORATION_TOOL", "Toggle Decoration Tool", [this]() {
if (colourPicker->GetParentWindow())
{
c->SetActiveMenu(lastMenu);
}
else
{
c->SetDecoration(true);
c->SetPaused(true);
c->SetActiveMenu(SC_DECO);
}
});
AddFunction("DEFAULT_FUN_TOGGLE_AIR_MODE", "Cycle Air Mode", [this]() {
c->SwitchAir();
});
AddFunction("DEFAULT_FUN_QUIT", "Quit", [this]() {
ui::Engine::Ref().ConfirmExit();
});
AddFunction("DEFAULT_FUN_TOGGLE_HEAT", "Toggle Ambient Heat", [this]() {
c->ToggleAHeat();
});
AddFunction("DEFAULT_FUN_TOGGLE_NEWTONIAN_GRAVITY", "Toggle Newtonian Gravity", [this]() {
c->ToggleNewtonianGravity();
});
AddFunction("DEFAULT_FUN_RESET_SPARK", "Reset Sparks", [this]() {
c->ResetSpark();
});
AddFunction("DEFAULT_FUN_RESET_AIR", "Reset Air", [this]() {
c->ResetAir();
});
AddFunction("DEFAULT_FUN_COPY", "Copy", [this]() {
PushContext("DEFAULT_CTX_EDIT_COPY");
selectPoint1 = selectPoint2 = ui::Point(-1, -1);
isMouseDown = false;
buttonTip = "\x0F\xEF\xEF\020Click-and-drag to specify an area to copy (right click = cancel)";
buttonTipShow = 120;
});
AddFunction("DEFAULT_FUN_CUT", "Cut", [this]() {
PushContext("DEFAULT_CTX_EDIT_CUT");
selectPoint1 = selectPoint2 = ui::Point(-1, -1);
isMouseDown = false;
buttonTip = "\x0F\xEF\xEF\020Click-and-drag to specify an area to copy then cut (right click = cancel)";
buttonTipShow = 120;
});
AddFunction("DEFAULT_FUN_PASTE", "Paste", [this]() {
if (c->LoadClipboard())
{
selectPoint1 = selectPoint2 = mousePosition;
isMouseDown = false;
}
});
AddFunction("DEFAULT_FUN_STAMP_TOOL", "Stamp", [this]() {
std::vector<ByteString> stampList = Client::Ref().GetStamps(0, 1);
if (stampList.size())
{
SaveFile *saveFile = Client::Ref().GetStamp(stampList[0]);
if (saveFile && saveFile->GetGameSave())
{
c->LoadStamp(saveFile->GetGameSave());
delete saveFile;
selectPoint1 = selectPoint2 = mousePosition;
isMouseDown = false;
}
}
});
AddFunction("DEFAULT_FUN_OPEN_STAMPS", "Open Stamp Browser", [this]() {
// selectMode = SelectNone;
selectPoint1 = selectPoint2 = ui::Point(-1, -1);
c->OpenStamps();
});
AddFunction("DEFAULT_FUN_INCREASE_BRUSH_ZOOM_SIZE", "Increase Brush or Zoom Window Size", [this]() {
if (zoomEnabled && !zoomCursorFixed)
{
c->AdjustZoomSize(1, !altBehaviour);
}
else
{
c->AdjustBrushSize(1, !altBehaviour, shiftBehaviour, ctrlBehaviour);
}
});
AddFunction("DEFAULT_FUN_DECREASE_BRUSH_ZOOM_SIZE", "Decrease Brush or Zoom Window Size", [this]() {
if (zoomEnabled && !zoomCursorFixed)
{
c->AdjustZoomSize(-1, !altBehaviour);
}
else
{
c->AdjustBrushSize(-1, !altBehaviour, shiftBehaviour, ctrlBehaviour);
}
});
AddFunction("DEFAULT_FUN_INSTALL_GAME", "Install Game", [this]() {
c->Install();
});
AddFunction("DEFAULT_FUN_INVERT_AIR_SIMULATION", "Reverse Air Vectors", [this]() {
c->InvertAirSim();
});
AddFunction("DEFAULT_FUN_TOGGLE_REPLACE_MODE", "Toggle Replace Mode", [this]() {
c->SetReplaceModeFlags(c->GetReplaceModeFlags() ^ SPECIFIC_DELETE);
});
AddFunction("DEFAULT_FUN_TOGGLE_SPECIFIC_DELETE_MODE", "Toggle Specific Delete Mode", [this]() {
c->SetReplaceModeFlags(c->GetReplaceModeFlags() ^ REPLACE_MODE);
});
AddFunction("DEFAULT_FUN_CYCLE_BRUSH", "Cycle Brush", [this]() {
c->ChangeBrush();
});
AddFunction("DEFAULT_FUN_RENDER_PRESET_ALTERNATIVEVELOCITY", "Alternative Velocity Display", [this]() {
c->LoadRenderPreset(0);
});
AddFunction("DEFAULT_FUN_RENDER_PRESET_VELOCITY", "Velocity Display", [this]() {
c->LoadRenderPreset(1);
});
AddFunction("DEFAULT_FUN_RENDER_PRESET_PRESSURE", "Pressure Display", [this]() {
c->LoadRenderPreset(2);
});
AddFunction("DEFAULT_FUN_RENDER_PRESET_PERSISTENT", "Persistent Display", [this]() {
c->LoadRenderPreset(3);
});
AddFunction("DEFAULT_FUN_RENDER_PRESET_FIRE", "Fire Display", [this]() {
c->LoadRenderPreset(4);
});
AddFunction("DEFAULT_FUN_RENDER_PRESET_BLOB", "Blob Display", [this]() {
c->LoadRenderPreset(5);
});
AddFunction("DEFAULT_FUN_RENDER_PRESET_HEAT", "Heat Display", [this]() {
c->LoadRenderPreset(6);
});
AddFunction("DEFAULT_FUN_RENDER_PRESET_FANCY", "Fancy Display", [this]() {
c->LoadRenderPreset(7);
});
AddFunction("DEFAULT_FUN_RENDER_PRESET_NOTHING", "Nothing Display", [this]() {
c->LoadRenderPreset(8);
});
AddFunction("DEFAULT_FUN_RENDER_PRESET_HEATGRADIENT", "Heat Gradient Display", [this]() {
c->LoadRenderPreset(9);
});
AddFunction("DEFAULT_FUN_RENDER_PRESET_LIFEGRADIENT", "Life Gradient Display", [this]() {
if (showDebug)
{
c->LoadRenderPreset(10);
}
});
AddContext("DEFAULT_CTX_IDLE", "When editing");
AddContext("DEFAULT_CTX_EDIT_COPY", "When copying");
AddContext("DEFAULT_CTX_EDIT_CUT", "When cutting");
AddContext("DEFAULT_CTX_EDIT_PASTE", "When pasting");
AddContext("DEFAULT_CTX_EDIT_STAMP", "When creating a stamp");
PushContext("DEFAULT_CTX_IDLE");
} }
GameView::~GameView() GameView::~GameView()
@ -594,10 +835,9 @@ public:
} }
}; };
void GameView::NotifyKeyBindingsChanged(GameModel * sender) void GameView::NotifyKeyconfigChanged(GameModel * sender)
{ {
// resync the model keyconfig = sender->GetKeyconfig();
keyboardBindingModel.LoadBindingPrefs();
} }
void GameView::NotifyQuickOptionsChanged(GameModel * sender) void GameView::NotifyQuickOptionsChanged(GameModel * sender)
@ -692,16 +932,6 @@ ui::Point GameView::GetMousePosition()
return currentMouse; return currentMouse;
} }
bool GameView::GetPlacingSave()
{
return selectMode != SelectNone;
}
bool GameView::GetPlacingZoom()
{
return zoomEnabled && !zoomCursorFixed;
}
void GameView::NotifyActiveToolsChanged(GameModel * sender) void GameView::NotifyActiveToolsChanged(GameModel * sender)
{ {
decoBrush = false; decoBrush = false;
@ -1156,14 +1386,21 @@ void GameView::OnMouseMove(int x, int y, int dx, int dy)
bool newMouseInZoom = c->MouseInZoom(ui::Point(x, y)); bool newMouseInZoom = c->MouseInZoom(ui::Point(x, y));
mousePosition = c->PointTranslate(ui::Point(x, y)); mousePosition = c->PointTranslate(ui::Point(x, y));
currentMouse = ui::Point(x, y); currentMouse = ui::Point(x, y);
if (selectMode != SelectNone) if (GetContext().BeginsWith("DEFAULT_CTX_EDIT_"))
{
if (GetContext() == "DEFAULT_CTX_EDIT_PASTE")
{ {
if (selectMode == PlaceSave)
selectPoint1 = c->PointTranslate(ui::Point(x, y)); selectPoint1 = c->PointTranslate(ui::Point(x, y));
}
if (selectPoint1.X != -1) if (selectPoint1.X != -1)
{
selectPoint2 = c->PointTranslate(ui::Point(x, y)); selectPoint2 = c->PointTranslate(ui::Point(x, y));
} }
else if (isMouseDown) }
else
{
if (isMouseDown)
{ {
if (newMouseInZoom == mouseInZoom) if (newMouseInZoom == mouseInZoom)
{ {
@ -1187,6 +1424,7 @@ void GameView::OnMouseMove(int x, int y, int dx, int dy)
c->MouseUp(x, y, 0, 2); c->MouseUp(x, y, 0, 2);
} }
} }
}
mouseInZoom = newMouseInZoom; mouseInZoom = newMouseInZoom;
// set active menu (delayed) // set active menu (delayed)
@ -1206,7 +1444,7 @@ void GameView::OnMouseDown(int x, int y, unsigned button)
button = SDL_BUTTON_MIDDLE; button = SDL_BUTTON_MIDDLE;
if (!(zoomEnabled && !zoomCursorFixed)) if (!(zoomEnabled && !zoomCursorFixed))
{ {
if (selectMode != SelectNone) if (GetContext().BeginsWith("DEFAULT_CTX_EDIT_"))
{ {
isMouseDown = true; isMouseDown = true;
if (button == SDL_BUTTON_LEFT && selectPoint1.X == -1) if (button == SDL_BUTTON_LEFT && selectPoint1.X == -1)
@ -1262,11 +1500,16 @@ void GameView::OnMouseUp(int x, int y, unsigned button)
else if (isMouseDown) else if (isMouseDown)
{ {
isMouseDown = false; isMouseDown = false;
if (selectMode != SelectNone) if (GetContext().BeginsWith("DEFAULT_CTX_EDIT_"))
{ {
if (button == SDL_BUTTON_LEFT && selectPoint1.X != -1 && selectPoint1.Y != -1 && selectPoint2.X != -1 && selectPoint2.Y != -1) if (button == SDL_BUTTON_LEFT && selectPoint1.X != -1 && selectPoint1.Y != -1 && selectPoint2.X != -1 && selectPoint2.Y != -1)
{ {
if (selectMode == PlaceSave) int x2 = (selectPoint1.X>selectPoint2.X) ? selectPoint1.X : selectPoint2.X;
int y2 = (selectPoint1.Y>selectPoint2.Y) ? selectPoint1.Y : selectPoint2.Y;
int x1 = (selectPoint2.X<selectPoint1.X) ? selectPoint2.X : selectPoint1.X;
int y1 = (selectPoint2.Y<selectPoint1.Y) ? selectPoint2.Y : selectPoint1.Y;
if (GetContext().EndsWith("PASTE"))
{ {
if (placeSaveThumb && y <= WINDOWH-BARSIZE) if (placeSaveThumb && y <= WINDOWH-BARSIZE)
{ {
@ -1286,22 +1529,21 @@ void GameView::OnMouseUp(int x, int y, unsigned button)
c->PlaceSave(ui::Point(thumbX, thumbY)); c->PlaceSave(ui::Point(thumbX, thumbY));
} }
} }
else else if (GetContext().EndsWith("COPY"))
{ {
int x2 = (selectPoint1.X>selectPoint2.X) ? selectPoint1.X : selectPoint2.X;
int y2 = (selectPoint1.Y>selectPoint2.Y) ? selectPoint1.Y : selectPoint2.Y;
int x1 = (selectPoint2.X<selectPoint1.X) ? selectPoint2.X : selectPoint1.X;
int y1 = (selectPoint2.Y<selectPoint1.Y) ? selectPoint2.Y : selectPoint1.Y;
if (selectMode ==SelectCopy)
c->CopyRegion(ui::Point(x1, y1), ui::Point(x2, y2)); c->CopyRegion(ui::Point(x1, y1), ui::Point(x2, y2));
else if (selectMode == SelectCut) }
else if (GetContext().EndsWith("CUT"))
{
c->CutRegion(ui::Point(x1, y1), ui::Point(x2, y2)); c->CutRegion(ui::Point(x1, y1), ui::Point(x2, y2));
else if (selectMode == SelectStamp) }
else if (GetContext().EndsWith("STAMP"))
{
c->StampRegion(ui::Point(x1, y1), ui::Point(x2, y2)); c->StampRegion(ui::Point(x1, y1), ui::Point(x2, y2));
} }
} }
selectMode = SelectNone;
return; PopContext();
} }
ui::Point finalDrawPoint2 = c->PointTranslate(currentMouse); ui::Point finalDrawPoint2 = c->PointTranslate(currentMouse);
@ -1338,9 +1580,11 @@ void GameView::OnMouseUp(int x, int y, unsigned button)
c->DrawFill(toolIndex, finalDrawPoint2); c->DrawFill(toolIndex, finalDrawPoint2);
} }
} }
else if (button != SDL_BUTTON_LEFT && GetContext().BeginsWith("DEFAULT_CTX_EDIT_"))
{
// this shouldn't happen, but do this just in case // this shouldn't happen, but do this just in case
else if (selectMode != SelectNone && button != SDL_BUTTON_LEFT) PopContext();
selectMode = SelectNone; }
// update the drawing mode for the next line // update the drawing mode for the next line
// since ctrl/shift state may have changed since we started drawing // since ctrl/shift state may have changed since we started drawing
@ -1352,7 +1596,7 @@ void GameView::ToolTip(ui::Point senderPosition, String toolTip)
// buttom button tooltips // buttom button tooltips
if (senderPosition.Y > Size.Y-17) if (senderPosition.Y > Size.Y-17)
{ {
if (selectMode == PlaceSave || selectMode == SelectNone) if (GetContext() == "DEFAULT_CTX_IDLE" || GetContext() == "DEFAULT_CTX_EDIT_PASTE")
{ {
buttonTip = toolTip; buttonTip = toolTip;
isButtonTipFadingIn = true; isButtonTipFadingIn = true;
@ -1380,7 +1624,7 @@ void GameView::OnMouseWheel(int x, int y, int d)
{ {
if (!d) if (!d)
return; return;
if (selectMode != SelectNone) if (GetContext() != "DEFAULT_CTX_IDLE")
{ {
return; return;
} }
@ -1396,7 +1640,7 @@ void GameView::OnMouseWheel(int x, int y, int d)
void GameView::BeginStampSelection() void GameView::BeginStampSelection()
{ {
selectMode = SelectStamp; PushContext("DEFAULT_CTX_EDIT_STAMP");
selectPoint1 = selectPoint2 = ui::Point(-1, -1); selectPoint1 = selectPoint2 = ui::Point(-1, -1);
isMouseDown = false; isMouseDown = false;
buttonTip = "\x0F\xEF\xEF\020Click-and-drag to specify an area to create a stamp (right click = cancel)"; buttonTip = "\x0F\xEF\xEF\020Click-and-drag to specify an area to create a stamp (right click = cancel)";
@ -1438,8 +1682,10 @@ void GameView::OnFileDrop(ByteString filename)
void GameView::OnTick(float dt) void GameView::OnTick(float dt)
{ {
if (selectMode == PlaceSave && !placeSaveThumb) if (GetContext() == "DEFAULT_CTX_EDIT_PASTE" && !placeSaveThumb)
selectMode = SelectNone; {
PopContext();
}
if (zoomEnabled && !zoomCursorFixed) if (zoomEnabled && !zoomCursorFixed)
c->SetZoomPosition(currentMouse); c->SetZoomPosition(currentMouse);
@ -1447,7 +1693,7 @@ void GameView::OnTick(float dt)
{ {
skipDraw = false; skipDraw = false;
} }
else if (selectMode == SelectNone && isMouseDown) else if (GetContext() == "DEFAULT_CTX_IDLE" && isMouseDown)
{ {
if (drawMode == DrawPoints) if (drawMode == DrawPoints)
{ {
@ -1506,7 +1752,9 @@ void GameView::OnTick(float dt)
if(infoTipPresence<0) if(infoTipPresence<0)
infoTipPresence = 0; infoTipPresence = 0;
} }
if (isButtonTipFadingIn || (selectMode != PlaceSave && selectMode != SelectNone)) if (isButtonTipFadingIn)
{
if (GetContext().BeginsWith("DEFAULT_CTX_EDIT_") && GetContext() != "DEFAULT_CTX_EDIT_PASTE")
{ {
isButtonTipFadingIn = false; isButtonTipFadingIn = false;
if(buttonTipShow < 120) if(buttonTipShow < 120)
@ -1516,6 +1764,7 @@ void GameView::OnTick(float dt)
buttonTipShow = 120; buttonTipShow = 120;
} }
} }
}
else if(buttonTipShow>0) else if(buttonTipShow>0)
{ {
buttonTipShow -= int(dt)>0?int(dt):1; buttonTipShow -= int(dt)>0?int(dt):1;
@ -1612,14 +1861,17 @@ void GameView::DoDraw()
void GameView::OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt) void GameView::OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt)
{ {
if (repeat)
{
return;
}
if (introText > 50) if (introText > 50)
{ {
introText = 50; introText = 50;
} }
if (selectMode != SelectNone) if (GetContext() == "DEFAULT_CTX_EDIT_PASTE")
{
if (selectMode == PlaceSave)
{ {
switch (key) switch (key)
{ {
@ -1656,242 +1908,39 @@ void GameView::OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl,
return; return;
} }
} }
}
int32_t functionId = keyboardBindingModel.GetFunctionForBinding(scan, shift, ctrl, alt); // linear search for now, will figure out something smarter if we ever need to
auto current_context = GetContext();
if (repeat) auto shortcut = std::find_if(keyconfig.begin(), keyconfig.end(), [=](KeyconfigItem const &item) {
return; return std::get<0>(item) == current_context
bool didKeyShortcut = true; && std::get<1>(item) == ctrl
&& std::get<2>(item) == shift
// please see KeyconfigMap.h for mappings && std::get<3>(item) == alt
switch(functionId) && std::get<4>(item) == scan;
});
if (shortcut != keyconfig.end())
{ {
case KeyconfigFunction::TOGGLE_CONSOLE: auto func = std::get<5>(*shortcut);
{ active_view_functions.push_back({ func, scan });
SDL_StopTextInput(); view_functions[func].on();
SDL_StartTextInput();
c->ShowConsole();
break;
}
case KeyconfigFunction::PAUSE_SIMULATION: //Space
c->SetPaused();
break;
case KeyconfigFunction::UNDO:
if (selectMode != SelectNone && isMouseDown)
break;
if (!isMouseDown)
{
c->HistoryRestore();
}
break;
case KeyconfigFunction::REDO:
if (selectMode != SelectNone && isMouseDown)
break;
if (!isMouseDown)
{
c->HistoryForward();
}
break;
case KeyconfigFunction::ENABLE_ZOOM:
{
isMouseDown = false;
zoomCursorFixed = false;
c->SetZoomEnabled(true);
break;
}
case KeyconfigFunction::PROPERTY_TOOL:
c->SetActiveTool(1, "DEFAULT_UI_PROPERTY");
break;
case KeyconfigFunction::TOGGLE_DEBUG_HUD:
SetDebugHUD(!GetDebugHUD());
break;
case KeyconfigFunction::RELOAD_SIMULATION:
c->ReloadSim();
break;
case KeyconfigFunction::SAVE_AUTHORSHIP_INFO:
if ((Client::Ref().GetAuthUser().UserElevation == User::ElevationModerator
|| Client::Ref().GetAuthUser().UserElevation == User::ElevationAdmin) && ctrl)
{
ByteString authorString = Client::Ref().GetAuthorInfo().toStyledString();
new InformationMessage("Save authorship info", authorString.FromUtf8(), true);
}
break;
case KeyconfigFunction::OPEN_ELEMENT_SEARCH:
c->OpenElementSearch();
break;
case KeyconfigFunction::FIND_MODE:
{
Tool *active = c->GetActiveTool(0);
if (!active->GetIdentifier().Contains("_PT_") || (ren->findingElement == active->GetToolID()))
ren->findingElement = 0;
else
ren->findingElement = active->GetToolID();
break;
}
case KeyconfigFunction::FRAME_STEP:
c->FrameStep();
break;
case KeyconfigFunction::SHOW_GRAVITY_GRID:
c->ShowGravityGrid();
break;
case KeyconfigFunction::DECREASE_GRAVITY_GRID_SIZE:
c->AdjustGridSize(-1);
break;
case KeyconfigFunction::INCREASE_GRAVITY_GRID_SIZE:
c->AdjustGridSize(1);
break;
case KeyconfigFunction::TOGGLE_INTRO_TEXT:
if(!introText)
introText = 8047;
else
introText = 0;
break;
case KeyconfigFunction::TOGGLE_HUD:
showHud = !showHud;
break;
case KeyconfigFunction::TOGGLE_DECORATIONS_LAYER:
c->SetDecoration();
break;
case KeyconfigFunction::TOGGLE_DECORATION_TOOL:
if (colourPicker->GetParentWindow())
c->SetActiveMenu(lastMenu);
else
{
c->SetDecoration(true);
c->SetPaused(true);
c->SetActiveMenu(SC_DECO);
}
break;
case KeyconfigFunction::TOGGLE_AIR_MODE:
c->SwitchAir();
break;
case KeyconfigFunction::QUIT:
ui::Engine::Ref().ConfirmExit();
break;
case KeyconfigFunction::TOGGLE_HEAT:
c->ToggleAHeat();
break;
case KeyconfigFunction::TOGGLE_NEWTONIAN_GRAVITY:
c->ToggleNewtonianGravity();
break;
case KeyconfigFunction::RESET_SPARK:
c->ResetSpark();
break;
case KeyconfigFunction::RESET_AIR:
c->ResetAir();
break;
case KeyconfigFunction::COPY:
{
selectMode = SelectCopy;
selectPoint1 = selectPoint2 = ui::Point(-1, -1);
isMouseDown = false;
buttonTip = "\x0F\xEF\xEF\020Click-and-drag to specify an area to copy (right click = cancel)";
buttonTipShow = 120;
break;
}
case KeyconfigFunction::CUT:
{
selectMode = SelectCut;
selectPoint1 = selectPoint2 = ui::Point(-1, -1);
isMouseDown = false;
buttonTip = "\x0F\xEF\xEF\020Click-and-drag to specify an area to copy then cut (right click = cancel)";
buttonTipShow = 120;
break;
}
case KeyconfigFunction::PASTE:
if (c->LoadClipboard())
{
selectPoint1 = selectPoint2 = mousePosition;
isMouseDown = false;
}
break;
case KeyconfigFunction::STAMP_TOOL:
{
std::vector<ByteString> stampList = Client::Ref().GetStamps(0, 1);
if (stampList.size())
{
SaveFile *saveFile = Client::Ref().GetStamp(stampList[0]);
if (!saveFile || !saveFile->GetGameSave())
break;
c->LoadStamp(saveFile->GetGameSave());
delete saveFile;
selectPoint1 = selectPoint2 = mousePosition;
isMouseDown = false;
break;
}
}
case KeyconfigFunction::OPEN_STAMPS:
{
selectMode = SelectNone;
selectPoint1 = selectPoint2 = ui::Point(-1, -1);
c->OpenStamps();
break;
}
case KeyconfigFunction::INCREASE_BRUSH_SIZE:
if(zoomEnabled && !zoomCursorFixed)
c->AdjustZoomSize(1, !alt);
else
c->AdjustBrushSize(1, !alt, shiftBehaviour, ctrlBehaviour);
break;
case KeyconfigFunction::DECREASE_BRUSH_SIZE:
if(zoomEnabled && !zoomCursorFixed)
c->AdjustZoomSize(-1, !alt);
else
c->AdjustBrushSize(-1, !alt, shiftBehaviour, ctrlBehaviour);
break;
case KeyconfigFunction::INSTALL_GAME:
c->Install();
break;
case KeyconfigFunction::INVERT_AIR_SIMULATION:
c->InvertAirSim();
break;
case KeyconfigFunction::TOGGLE_REPLACE_MODE:
c->SetReplaceModeFlags(c->GetReplaceModeFlags()^SPECIFIC_DELETE);
break;
case KeyconfigFunction::TOGGLE_SPECIFIC_DELETE_MODE:
c->SetReplaceModeFlags(c->GetReplaceModeFlags()^REPLACE_MODE);
break;
default:
didKeyShortcut = false;
}
if (!didKeyShortcut)
{
switch (key)
{
case SDLK_TAB: //Tab
c->ChangeBrush();
break;
case SDLK_INSERT:
if (ctrl)
c->SetReplaceModeFlags(c->GetReplaceModeFlags()^SPECIFIC_DELETE);
else
c->SetReplaceModeFlags(c->GetReplaceModeFlags()^REPLACE_MODE);
break;
case SDLK_DELETE:
c->SetReplaceModeFlags(c->GetReplaceModeFlags()^SPECIFIC_DELETE);
break;
}
}
if (shift && showDebug && key == '1')
c->LoadRenderPreset(10);
else if (key >= '0' && key <= '9')
{
c->LoadRenderPreset(key-'0');
} }
} }
void GameView::OnKeyRelease(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt) void GameView::OnKeyRelease(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt)
{ {
if (repeat) if (repeat)
return;
if (scan == SDL_SCANCODE_Z)
{ {
if (!zoomCursorFixed && !alt)
c->SetZoomEnabled(false);
return; return;
} }
auto active = std::find_if(active_view_functions.begin(), active_view_functions.end(), [=](ActiveViewFunction const &func) {
return func.scan != scan;
});
if (active != active_view_functions.end())
{
view_functions[active->func].off();
active_view_functions.erase(active);
}
} }
void GameView::NotifyNotificationsChanged(GameModel * sender) void GameView::NotifyNotificationsChanged(GameModel * sender)
@ -1975,19 +2024,28 @@ void GameView::NotifyLogChanged(GameModel * sender, String entry)
void GameView::NotifyPlaceSaveChanged(GameModel * sender) void GameView::NotifyPlaceSaveChanged(GameModel * sender)
{ {
if (placeSaveThumb)
{
delete placeSaveThumb; delete placeSaveThumb;
}
placeSaveOffset = ui::Point(0, 0); placeSaveOffset = ui::Point(0, 0);
if(sender->GetPlaceSave()) if(sender->GetPlaceSave())
{ {
SaveRenderer::Ref().CopyModes(sender->GetRenderer()); SaveRenderer::Ref().CopyModes(sender->GetRenderer());
if (!placeSaveThumb) // we weren't in DEFAULT_CTX_EDIT_PASTE
{
PushContext("DEFAULT_CTX_EDIT_PASTE");
}
placeSaveThumb = SaveRenderer::Ref().Render(sender->GetPlaceSave()); placeSaveThumb = SaveRenderer::Ref().Render(sender->GetPlaceSave());
selectMode = PlaceSave;
selectPoint2 = mousePosition; selectPoint2 = mousePosition;
} }
else else
{ {
if (placeSaveThumb)
{
PopContext(); // we were in DEFAULT_CTX_EDIT_PASTE
}
placeSaveThumb = NULL; placeSaveThumb = NULL;
selectMode = SelectNone;
} }
} }
@ -1996,7 +2054,7 @@ void GameView::enableShiftBehaviour()
if (!shiftBehaviour) if (!shiftBehaviour)
{ {
shiftBehaviour = true; shiftBehaviour = true;
if (!isMouseDown || selectMode != SelectNone) if (!isMouseDown || GetContext() != "DEFAULT_CTX_IDLE")
UpdateDrawMode(); UpdateDrawMode();
UpdateToolStrength(); UpdateToolStrength();
} }
@ -2007,7 +2065,7 @@ void GameView::disableShiftBehaviour()
if (shiftBehaviour) if (shiftBehaviour)
{ {
shiftBehaviour = false; shiftBehaviour = false;
if (!isMouseDown || selectMode != SelectNone) if (!isMouseDown || GetContext() != "DEFAULT_CTX_IDLE")
UpdateDrawMode(); UpdateDrawMode();
UpdateToolStrength(); UpdateToolStrength();
} }
@ -2036,7 +2094,7 @@ void GameView::enableCtrlBehaviour()
if (!ctrlBehaviour) if (!ctrlBehaviour)
{ {
ctrlBehaviour = true; ctrlBehaviour = true;
if (!isMouseDown || selectMode != SelectNone) if (!isMouseDown || GetContext() != "DEFAULT_CTX_IDLE")
UpdateDrawMode(); UpdateDrawMode();
UpdateToolStrength(); UpdateToolStrength();
@ -2061,7 +2119,7 @@ void GameView::disableCtrlBehaviour()
if (ctrlBehaviour) if (ctrlBehaviour)
{ {
ctrlBehaviour = false; ctrlBehaviour = false;
if (!isMouseDown || selectMode != SelectNone) if (!isMouseDown || GetContext() != "DEFAULT_CTX_IDLE")
UpdateDrawMode(); UpdateDrawMode();
UpdateToolStrength(); UpdateToolStrength();
@ -2127,7 +2185,7 @@ void GameView::OnDraw()
ren->clearScreen(1.0f); ren->clearScreen(1.0f);
ren->RenderBegin(); ren->RenderBegin();
ren->SetSample(c->PointTranslate(currentMouse).X, c->PointTranslate(currentMouse).Y); ren->SetSample(c->PointTranslate(currentMouse).X, c->PointTranslate(currentMouse).Y);
if (selectMode == SelectNone && (!zoomEnabled || zoomCursorFixed) && activeBrush && (isMouseDown || (currentMouse.X >= 0 && currentMouse.X < XRES && currentMouse.Y >= 0 && currentMouse.Y < YRES))) if (GetContext() == "DEFAULT_CTX_IDLE" && (!zoomEnabled || zoomCursorFixed) && activeBrush && (isMouseDown || (currentMouse.X >= 0 && currentMouse.X < XRES && currentMouse.Y >= 0 && currentMouse.Y < YRES)))
{ {
ui::Point finalCurrentMouse = c->PointTranslate(currentMouse); ui::Point finalCurrentMouse = c->PointTranslate(currentMouse);
ui::Point initialDrawPoint = drawPoint1; ui::Point initialDrawPoint = drawPoint1;
@ -2189,9 +2247,9 @@ void GameView::OnDraw()
} }
} }
if(selectMode!=SelectNone) if (GetContext().BeginsWith("DEFAULT_CTX_EDIT_"))
{ {
if(selectMode==PlaceSave) if (GetContext().EndsWith("PASTE"))
{ {
if(placeSaveThumb && selectPoint2.X!=-1) if(placeSaveThumb && selectPoint2.X!=-1)
{ {
@ -2548,3 +2606,45 @@ ui::Point GameView::rectSnapCoords(ui::Point point1, ui::Point point2)
// SW-NE // SW-NE
return point1 + ui::Point((diff.X - diff.Y)/2, (diff.Y - diff.X)/2); return point1 + ui::Point((diff.X - diff.Y)/2, (diff.Y - diff.X)/2);
} }
void GameView::PushContext(ByteString new_context)
{
context.push(new_context);
}
void GameView::PopContext()
{
context.pop();
assert(context.size());
}
ByteString GameView::GetContext() const
{
return context.top();
}
bool GameView::IsIdle() const
{
return GetContext() == "DEFAULT_CTX_IDLE";
}
void GameView::AddFunction(ByteString name, ByteString description, ViewFunctionOn on, ViewFunctionOff off)
{
view_functions.insert(std::make_pair(name, ViewFunction{ on, off, description }));
}
void GameView::RemoveFunction(ByteString name)
{
view_functions.erase(name);
}
void GameView::AddContext(ByteString name, ByteString description)
{
view_contexts.insert(std::make_pair(name, ViewContext{ description }));
}
void GameView::RemoveContext(ByteString name)
{
view_contexts.erase(name);
}

View File

@ -3,21 +3,19 @@
#include <vector> #include <vector>
#include <deque> #include <deque>
#include <map>
#include <stack>
#include <functional>
#include "common/String.h" #include "common/String.h"
#include "gui/interface/Window.h" #include "gui/interface/Window.h"
#include "simulation/Sample.h" #include "simulation/Sample.h"
#include "gui/keyconfig/KeyconfigModel.h" #include "Keyconfig.h"
enum DrawMode enum DrawMode
{ {
DrawPoints, DrawLine, DrawRect, DrawFill DrawPoints, DrawLine, DrawRect, DrawFill
}; };
enum SelectMode
{
SelectNone, SelectStamp, SelectCopy, SelectCut, PlaceSave
};
namespace ui namespace ui
{ {
class Button; class Button;
@ -33,6 +31,10 @@ class Brush;
class GameModel; class GameModel;
class GameView: public ui::Window class GameView: public ui::Window
{ {
public:
using ViewFunctionOn = std::function<void ()>;
using ViewFunctionOff = std::function<void ()>;
private: private:
bool isMouseDown; bool isMouseDown;
bool skipDraw; bool skipDraw;
@ -103,7 +105,7 @@ private:
ui::Point drawPoint1; ui::Point drawPoint1;
ui::Point drawPoint2; ui::Point drawPoint2;
SelectMode selectMode; std::stack<ByteString> context;
ui::Point selectPoint1; ui::Point selectPoint1;
ui::Point selectPoint2; ui::Point selectPoint2;
@ -115,8 +117,6 @@ private:
SimulationSample sample; SimulationSample sample;
KeyconfigModel keyboardBindingModel;
void updateToolButtonScroll(); void updateToolButtonScroll();
void SetSaveButtonTooltips(); void SetSaveButtonTooltips();
@ -131,6 +131,30 @@ private:
void disableAltBehaviour(); void disableAltBehaviour();
void UpdateDrawMode(); void UpdateDrawMode();
void UpdateToolStrength(); void UpdateToolStrength();
Keyconfig keyconfig;
struct ViewContext
{
ByteString description;
};
std::map<ByteString, ViewContext> view_contexts;
struct ViewFunction
{
ViewFunctionOn on;
ViewFunctionOff off;
ByteString description;
};
std::map<ByteString, ViewFunction> view_functions;
struct ActiveViewFunction
{
ByteString func;
int scan;
};
std::vector<ActiveViewFunction> active_view_functions;
public: public:
GameView(); GameView();
virtual ~GameView(); virtual ~GameView();
@ -142,17 +166,15 @@ public:
bool GetHudEnable(); bool GetHudEnable();
void SetDebugHUD(bool mode); void SetDebugHUD(bool mode);
bool GetDebugHUD(); bool GetDebugHUD();
bool GetPlacingSave();
bool GetPlacingZoom();
void SetActiveMenuDelayed(int activeMenu) { delayedActiveMenu = activeMenu; } void SetActiveMenuDelayed(int activeMenu) { delayedActiveMenu = activeMenu; }
bool CtrlBehaviour(){ return ctrlBehaviour; } bool CtrlBehaviour(){ return ctrlBehaviour; }
bool ShiftBehaviour(){ return shiftBehaviour; } bool ShiftBehaviour(){ return shiftBehaviour; }
bool AltBehaviour(){ return altBehaviour; } bool AltBehaviour(){ return altBehaviour; }
SelectMode GetSelectMode() { return selectMode; }
void BeginStampSelection(); void BeginStampSelection();
ui::Point GetPlaceSaveOffset() { return placeSaveOffset; } ui::Point GetPlaceSaveOffset() { return placeSaveOffset; }
void SetPlaceSaveOffset(ui::Point offset) { placeSaveOffset = offset; } void SetPlaceSaveOffset(ui::Point offset) { placeSaveOffset = offset; }
int Record(bool record); int Record(bool record);
bool IsIdle() const;
//all of these are only here for one debug lines //all of these are only here for one debug lines
bool GetMouseDown() { return isMouseDown; } bool GetMouseDown() { return isMouseDown; }
@ -185,7 +207,7 @@ public:
void NotifyInfoTipChanged(GameModel * sender); void NotifyInfoTipChanged(GameModel * sender);
void NotifyQuickOptionsChanged(GameModel * sender); void NotifyQuickOptionsChanged(GameModel * sender);
void NotifyLastToolChanged(GameModel * sender); void NotifyLastToolChanged(GameModel * sender);
void NotifyKeyBindingsChanged(GameModel * sender); void NotifyKeyconfigChanged(GameModel * sender);
void ToolTip(ui::Point senderPosition, String toolTip) override; void ToolTip(ui::Point senderPosition, String toolTip) override;
@ -216,6 +238,15 @@ public:
class ToolAction; class ToolAction;
class OptionAction; class OptionAction;
class OptionListener; class OptionListener;
void PushContext(ByteString new_context);
void PopContext();
ByteString GetContext() const;
void AddFunction(ByteString name, ByteString description, ViewFunctionOn on = nullptr, ViewFunctionOff off = nullptr);
void RemoveFunction(ByteString name);
void AddContext(ByteString name, ByteString description);
void RemoveContext(ByteString name);
}; };
#endif // GAMEVIEW_H #endif // GAMEVIEW_H

18
src/gui/game/Keyconfig.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef KEYCONFIG_H_
#define KEYCONFIG_H_
#include <vector>
#include <tuple>
#include <string>
using KeyconfigItem = std::tuple<
ByteString, // context
bool, // ctrl
bool, // shift
bool, // alt
int, // scancode
ByteString // function
>;
using Keyconfig = std::vector<KeyconfigItem>;
#endif // KEYCONFIG_H_

View File

@ -24,7 +24,6 @@ namespace ui
int GetScrollLimit(); int GetScrollLimit();
void SetScrollPosition(int position); void SetScrollPosition(int position);
inline float GetScrollPositionY() const { return offsetY; }
void Draw(const Point& screenPos) override; void Draw(const Point& screenPos) override;
void XTick(float dt) override; void XTick(float dt) override;

View File

@ -1,3 +1,5 @@
static int Aa;
#if 0 // temporarily disabled so it doesn't interfere with what I'm doing -- LBPHacker
#include "KeyconfigController.h" #include "KeyconfigController.h"
#include "KeyconfigView.h" #include "KeyconfigView.h"
@ -94,4 +96,4 @@ KeyconfigController::~KeyconfigController()
delete callback; delete callback;
delete model; delete model;
} }
#endif

View File

@ -1,241 +1,244 @@
static int Aa;
#if 0 // temporarily disabled so it doesn't interfere with what I'm doing -- LBPHacker
#include "KeyconfigModel.h" #include "KeyconfigModel.h"
#include "client/Client.h"
#include "SDLCompat.h"
#include "KeyconfigMap.h"
#include <algorithm>
#include "KeyconfigView.h"
void KeyconfigModel::WriteDefaultFuncArray(bool force) // #include "client/Client.h"
{ // #include "SDLCompat.h"
if (force) // #include "KeyconfigMap.h"
Client::Ref().ClearPref(ByteString(KEYCONFIG_FUNCS_PREF)); // #include <algorithm>
// #include "KeyconfigView.h"
for (auto defaultBinding : defaultKeyconfigMapArray) // void KeyconfigModel::WriteDefaultFuncArray(bool force)
{ // {
int functionId; // if (force)
String description; // Client::Ref().ClearPref(ByteString(KEYCONFIG_FUNCS_PREF));
for (auto functions : keyboardBindingFunctionMap)
{
if (functions.id == defaultBinding.bindingId)
{
functionId = functions.functionId;
description = functions.description;
}
}
ByteString pref = ByteString(KEYCONFIG_FUNCS_PREF) + ByteString(".") + ByteString(functionId); // for (auto defaultBinding : defaultKeyconfigMapArray)
bool functionExists = Client::Ref().GetPrefJson(pref, Json::nullValue) != Json::nullValue; // {
// int functionId;
// String description;
// for (auto functions : keyboardBindingFunctionMap)
// {
// if (functions.id == defaultBinding.bindingId)
// {
// functionId = functions.functionId;
// description = functions.description;
// }
// }
if (!force && functionExists) // ByteString pref = ByteString(KEYCONFIG_FUNCS_PREF) + ByteString(".") + ByteString(functionId);
continue; // bool functionExists = Client::Ref().GetPrefJson(pref, Json::nullValue) != Json::nullValue;
Json::Value prefValue; // if (!force && functionExists)
// continue;
prefValue["hasShortcut"] = true; // Json::Value prefValue;
prefValue["functionId"] = functionId;
Client::Ref().SetPref(pref, prefValue);
}
} // prefValue["hasShortcut"] = true;
// prefValue["functionId"] = functionId;
// Client::Ref().SetPref(pref, prefValue);
// }
void KeyconfigModel::WriteDefaultPrefs(bool force) // }
{
// Load temporary bindings into memory
// this is so we can add in any new axctions
// from the KeyconfigMap into our prefs
LoadBindingPrefs();
if (force) // void KeyconfigModel::WriteDefaultPrefs(bool force)
Client::Ref().ClearPref(ByteString(KEYCONFIG_PREF)); // {
// // Load temporary bindings into memory
// // this is so we can add in any new axctions
// // from the KeyconfigMap into our prefs
// LoadBindingPrefs();
WriteDefaultFuncArray(force); // if (force)
// Client::Ref().ClearPref(ByteString(KEYCONFIG_PREF));
for (auto defaultBinding : defaultKeyconfigMapArray) // WriteDefaultFuncArray(force);
{
int functionId;
String description;
for (auto functions : keyboardBindingFunctionMap)
{
if (functions.id == defaultBinding.bindingId)
{
functionId = functions.functionId;
description = functions.description;
}
}
ByteString pref = ByteString(KEYCONFIG_PREF) + ByteString(".") + defaultBinding.keyCombo; // for (auto defaultBinding : defaultKeyconfigMapArray)
Json::Value prefValue; // {
// int functionId;
// String description;
// for (auto functions : keyboardBindingFunctionMap)
// {
// if (functions.id == defaultBinding.bindingId)
// {
// functionId = functions.functionId;
// description = functions.description;
// }
// }
// if we not forcing then check if the function is already set up as a pref // ByteString pref = ByteString(KEYCONFIG_PREF) + ByteString(".") + defaultBinding.keyCombo;
// if it is then bail the current iteration // Json::Value prefValue;
if (!force)
{
if (bindingPrefs.size() > 0)
{
for (auto prefBinding : bindingPrefs)
{
if (prefBinding.functionId == functionId)
goto end; // evil but necessary
}
}
}
prefValue["description"] = description.ToUtf8(); // // if we not forcing then check if the function is already set up as a pref
prefValue["functionId"] = functionId; // // if it is then bail the current iteration
Client::Ref().SetPref(pref, prefValue); // if (!force)
// {
// if (bindingPrefs.size() > 0)
// {
// for (auto prefBinding : bindingPrefs)
// {
// if (prefBinding.functionId == functionId)
// goto end; // evil but necessary
// }
// }
// }
end:; // prefValue["description"] = description.ToUtf8();
} // prefValue["functionId"] = functionId;
// Client::Ref().SetPref(pref, prefValue);
// force is from a user action so don't write into store // end:;
// until user hits OK // }
if (!force)
Client::Ref().WritePrefs();
LoadBindingPrefs(); // // force is from a user action so don't write into store
} // // until user hits OK
// if (!force)
// Client::Ref().WritePrefs();
void KeyconfigModel::LoadBindingPrefs() // LoadBindingPrefs();
{ // }
Json::Value bindings = Client::Ref().GetPrefJson(KEYCONFIG_PREF);
bindingPrefs.clear();
if (bindings != Json::nullValue) // void KeyconfigModel::LoadBindingPrefs()
{ // {
Json::Value::Members keyComboJson = bindings.getMemberNames(); // Json::Value bindings = Client::Ref().GetPrefJson(KEYCONFIG_PREF);
int index = 0; // bindingPrefs.clear();
for (auto& member : keyComboJson) // if (bindings != Json::nullValue)
{ // {
ByteString keyCombo(member); // Json::Value::Members keyComboJson = bindings.getMemberNames();
ByteString pref = ByteString(KEYCONFIG_PREF) + "." + keyCombo; // int index = 0;
Json::Value result = Client::Ref().GetPrefJson(pref);
if (result != Json::nullValue) // for (auto& member : keyComboJson)
{ // {
BindingModel model; // ByteString keyCombo(member);
std::pair<int, int> p = GetModifierAndScanFromString(keyCombo); // ByteString pref = ByteString(KEYCONFIG_PREF) + "." + keyCombo;
model.modifier = p.first; // Json::Value result = Client::Ref().GetPrefJson(pref);
model.scan = p.second;
model.functionId = result["functionId"].asInt();
model.description = ByteString(result["description"].asString()).FromUtf8();
model.index = index;
bindingPrefs.push_back(model);
}
index++; // if (result != Json::nullValue)
} // {
} // BindingModel model;
} // std::pair<int, int> p = GetModifierAndScanFromString(keyCombo);
// model.modifier = p.first;
// model.scan = p.second;
// model.functionId = result["functionId"].asInt();
// model.description = ByteString(result["description"].asString()).FromUtf8();
// model.index = index;
// bindingPrefs.push_back(model);
// }
std::pair<int, int> // index++;
KeyconfigModel::GetModifierAndScanFromString(ByteString str) // }
{ // }
int modifier = 0; // }
int scan = 0;
if (str == "NULL") // std::pair<int, int>
{ // KeyconfigModel::GetModifierAndScanFromString(ByteString str)
scan = -1; // {
} // int modifier = 0;
else // int scan = 0;
{
ByteString::Split split = str.SplitBy("+");
// not the last int so its a modifier // if (str == "NULL")
ByteString modString = split.Before(); // {
// scan = -1;
// }
// else
// {
// ByteString::Split split = str.SplitBy("+");
modifier |= (std::stoi(modString) & BINDING_MASK); // // not the last int so its a modifier
scan = std::stoi(split.After()); // ByteString modString = split.Before();
}
return std::make_pair(modifier, scan); // modifier |= (std::stoi(modString) & BINDING_MASK);
} // scan = std::stoi(split.After());
// }
void KeyconfigModel::TurnOffFunctionShortcut(int functionId) // return std::make_pair(modifier, scan);
{ // }
ByteString pref = ByteString(KEYCONFIG_FUNCS_PREF) + ByteString(".") + ByteString(functionId)
+ ByteString(".hasShortcut");
Client::Ref().SetPref(pref, false); // void KeyconfigModel::TurnOffFunctionShortcut(int functionId)
} // {
// ByteString pref = ByteString(KEYCONFIG_FUNCS_PREF) + ByteString(".") + ByteString(functionId)
// + ByteString(".hasShortcut");
void KeyconfigModel::TurnOnFunctionShortcut(int functionId) // Client::Ref().SetPref(pref, false);
{ // }
ByteString pref = ByteString(KEYCONFIG_FUNCS_PREF) + ByteString(".") + ByteString(functionId)
+ ByteString(".hasShortcut");
Client::Ref().SetPref(pref, true); // void KeyconfigModel::TurnOnFunctionShortcut(int functionId)
} // {
// ByteString pref = ByteString(KEYCONFIG_FUNCS_PREF) + ByteString(".") + ByteString(functionId)
// + ByteString(".hasShortcut");
void KeyconfigModel::RemoveModelByIndex(int index) // Client::Ref().SetPref(pref, true);
{ // }
std::vector<BindingModel>::iterator it = bindingPrefs.begin();
while(it != bindingPrefs.end()) // void KeyconfigModel::RemoveModelByIndex(int index)
{ // {
auto& pref = *it; // std::vector<BindingModel>::iterator it = bindingPrefs.begin();
if (pref.index == index)
{
bindingPrefs.erase(it);
return;
}
it++; // while(it != bindingPrefs.end())
} // {
} // auto& pref = *it;
// if (pref.index == index)
// {
// bindingPrefs.erase(it);
// return;
// }
void KeyconfigModel::CreateModel(BindingModel model) // it++;
{ // }
// if the function has no shortcut then just turn it on // }
if (!FunctionHasShortcut(model.functionId))
{
TurnOnFunctionShortcut(model.functionId);
return;
}
// index is just an session based id that we use // void KeyconfigModel::CreateModel(BindingModel model)
// to identify removals/changes // {
// so whenever a new model is created we just set it to the // // if the function has no shortcut then just turn it on
// size of the container // if (!FunctionHasShortcut(model.functionId))
model.index = bindingPrefs.size(); // {
bindingPrefs.push_back(model); // TurnOnFunctionShortcut(model.functionId);
} // return;
// }
void KeyconfigModel::AddModel(BindingModel model) // // index is just an session based id that we use
{ // // to identify removals/changes
bindingPrefs.push_back(model); // // so whenever a new model is created we just set it to the
TurnOnFunctionShortcut(model.functionId); // // size of the container
bool hasConflict = HasConflictingCombo(); // model.index = bindingPrefs.size();
NotifyBindingsChanged(hasConflict); // bindingPrefs.push_back(model);
} // }
bool KeyconfigModel::FunctionHasShortcut(int functionId) // void KeyconfigModel::AddModel(BindingModel model)
{ // {
ByteString pref = ByteString(KEYCONFIG_FUNCS_PREF) + ByteString(".") + ByteString(functionId) // bindingPrefs.push_back(model);
+ ByteString(".hasShortcut"); // TurnOnFunctionShortcut(model.functionId);
// bool hasConflict = HasConflictingCombo();
// NotifyBindingsChanged(hasConflict);
// }
return Client::Ref().GetPrefBool(pref, false); // bool KeyconfigModel::FunctionHasShortcut(int functionId)
} // {
// ByteString pref = ByteString(KEYCONFIG_FUNCS_PREF) + ByteString(".") + ByteString(functionId)
// + ByteString(".hasShortcut");
void KeyconfigModel::Save() // return Client::Ref().GetPrefBool(pref, false);
{ // }
Client::Ref().ClearPref(KEYCONFIG_PREF);
for (auto& binding : bindingPrefs) // void KeyconfigModel::Save()
{ // {
ByteString mod(std::to_string(binding.modifier)); // Client::Ref().ClearPref(KEYCONFIG_PREF);
ByteString scan(std::to_string(binding.scan));
ByteString pref = ByteString(KEYCONFIG_PREF) + ByteString(".") + mod + ByteString("+") + scan;
Json::Value val; // for (auto& binding : bindingPrefs)
val["functionId"] = binding.functionId; // {
val["description"] = binding.description.ToUtf8(); // ByteString mod(std::to_string(binding.modifier));
Client::Ref().SetPref(pref, val); // ByteString scan(std::to_string(binding.scan));
} // ByteString pref = ByteString(KEYCONFIG_PREF) + ByteString(".") + mod + ByteString("+") + scan;
Client::Ref().WritePrefs(); // Json::Value val;
} // val["functionId"] = binding.functionId;
// val["description"] = binding.description.ToUtf8();
// Client::Ref().SetPref(pref, val);
// }
// Client::Ref().WritePrefs();
// }
int KeyconfigModel::GetFunctionForBinding(int scan, bool shift, bool ctrl, bool alt) int KeyconfigModel::GetFunctionForBinding(int scan, bool shift, bool ctrl, bool alt)
{ {
@ -272,88 +275,90 @@ int KeyconfigModel::GetFunctionForBinding(int scan, bool shift, bool ctrl, bool
* then we turn off hasShortcut for the associated function * then we turn off hasShortcut for the associated function
* so it renders as *No Shortcut* on the view * so it renders as *No Shortcut* on the view
*/ */
void KeyconfigModel::PopBindingByFunctionId(int functionId) // void KeyconfigModel::PopBindingByFunctionId(int functionId)
// {
// std::sort(bindingPrefs.begin(), bindingPrefs.end(), [](BindingModel a, BindingModel b)
// {
// return a.index > b.index;
// });
// std::vector<BindingModel> v;
// for (auto b : bindingPrefs)
// {
// if (b.functionId == functionId)
// v.push_back(b);
// }
// if (v.size() == 1)
// {
// auto it = std::find(bindingPrefs.begin(), bindingPrefs.end(), v[0]);
// TurnOffFunctionShortcut((*it).functionId);
// }
// else
// {
// auto it = bindingPrefs.begin();
// while (it != bindingPrefs.end())
// {
// if ((*it).functionId == functionId)
// {
// bindingPrefs.erase(it);
// break;
// }
// it++;
// }
// }
// }
// String KeyconfigModel::GetDisplayForModel(BindingModel model)
// {
// return model.description;
// }
// bool KeyconfigModel::HasConflictingCombo()
// {
// for (auto& binding : bindingPrefs)
// {
// // if we have any new bindings then we
// // need to return a conflict until
// // the user types out a binding
// if (binding.isNew)
// return true;
// // if the current binding has no shortcut then skip
// if (!FunctionHasShortcut(binding.functionId))
// continue;
// // if key combo appears twice then there is a conflicting combo
// auto iter = std::find(bindingPrefs.begin(), bindingPrefs.end(), binding);
// if (iter != bindingPrefs.end())
// {
// // if this time round we don't have a shortcut either
// // then we can safely continue because this means
// // we don't have a conflict for the current binding
// if (!FunctionHasShortcut((*iter).functionId))
// continue;
// iter++;
// iter = std::find(iter, bindingPrefs.end(), binding);
// if (iter != bindingPrefs.end())
// return true;
// }
// }
// return false;
// }
void KeyconfigModel::AddObserver(KeyconfigView* view)
{ {
std::sort(bindingPrefs.begin(), bindingPrefs.end(), [](BindingModel a, BindingModel b) observers.push_back(view);
{ view->NotifyKeyconfigChanged(this);
return a.index > b.index;
});
std::vector<BindingModel> v;
for (auto b : bindingPrefs)
{
if (b.functionId == functionId)
v.push_back(b);
}
if (v.size() == 1)
{
auto it = std::find(bindingPrefs.begin(), bindingPrefs.end(), v[0]);
TurnOffFunctionShortcut((*it).functionId);
}
else
{
auto it = bindingPrefs.begin();
while (it != bindingPrefs.end())
{
if ((*it).functionId == functionId)
{
bindingPrefs.erase(it);
break;
}
it++;
}
}
} }
String KeyconfigModel::GetDisplayForModel(BindingModel model) void KeyconfigModel::notifyKeyconfigChanged(bool hasConflict)
{
return model.description;
}
bool KeyconfigModel::HasConflictingCombo()
{
for (auto& binding : bindingPrefs)
{
// if we have any new bindings then we
// need to return a conflict until
// the user types out a binding
if (binding.isNew)
return true;
// if the current binding has no shortcut then skip
if (!FunctionHasShortcut(binding.functionId))
continue;
// if key combo appears twice then there is a conflicting combo
auto iter = std::find(bindingPrefs.begin(), bindingPrefs.end(), binding);
if (iter != bindingPrefs.end())
{
// if this time round we don't have a shortcut either
// then we can safely continue because this means
// we don't have a conflict for the current binding
if (!FunctionHasShortcut((*iter).functionId))
continue;
iter++;
iter = std::find(iter, bindingPrefs.end(), binding);
if (iter != bindingPrefs.end())
return true;
}
}
return false;
}
void KeyconfigModel::AddObserver(KeyconfigView* observer)
{
observers.push_back(observer);
}
void KeyconfigModel::NotifyBindingsChanged(bool hasConflict)
{ {
for (auto& observer : observers) for (auto& observer : observers)
{ {
observer->OnKeyCombinationChanged(hasConflict); observer->NotifyKeyconfigChanged(hasConflict);
} }
} }
#endif

View File

@ -1,74 +1,81 @@
#ifndef KEYCONFIGSMODEL_H #ifndef KEYCONFIGSMODEL_H
#define KEYCONFIGSMODEL_H #define KEYCONFIGSMODEL_H
#include <vector> // #include <vector>
#include <utility> // #include <utility>
#include "common/String.h" // #include "common/String.h"
#define KEYCONFIG_PREF "Keyconfig" // #define KEYCONFIG_PREF "Keyconfig"
#define KEYCONFIG_FUNCS_PREF "KeyconfigFunctions" // #define KEYCONFIG_FUNCS_PREF "KeyconfigFunctions"
#define BINDING_MASK 0x07 // #define BINDING_MASK 0x07
#define BINDING_CTRL 0x01 // #define BINDING_CTRL 0x01
#define BINDING_ALT 0x02 // #define BINDING_ALT 0x02
#define BINDING_SHIFT 0x04 // #define BINDING_SHIFT 0x04
struct BindingModel // struct BindingModel
{ // {
int modifier; // int modifier;
int scan; // int scan;
int functionId; // int functionId;
String description; // String description;
int index; // int index;
bool noShortcut; // bool noShortcut;
bool isNew; // bool isNew;
BindingModel() : noShortcut(false), isNew(false){}; // BindingModel() : noShortcut(false), isNew(false){};
bool operator==(const BindingModel& other) const // bool operator==(const BindingModel& other) const
{ // {
return modifier == other.modifier && scan == other.scan; // return modifier == other.modifier && scan == other.scan;
} // }
bool operator< (const BindingModel &other) const // bool operator< (const BindingModel &other) const
{ // {
if (description == other.description) // if (description == other.description)
return index < other.index; // return index < other.index;
return description < other.description; // return description < other.description;
} // }
}; // };
class KeyconfigView; class KeyconfigView;
class KeyconfigModel class KeyconfigModel
{ {
GameModel *gModel;
std::vector<KeyconfigView *> observers;
void notifyKeyconfigChanged();
public: public:
KeyconfigModel(){} KeyconfigModel(GameModel *gModel);
void WriteDefaultPrefs(bool force = false); // true if user clicks reset to defaults
inline std::vector<BindingModel> GetBindingPrefs() const { return bindingPrefs; }
void LoadBindingPrefs();
void Save();
void RemoveModelByIndex(int index);
void AddModel(BindingModel model);
void CreateModel(BindingModel model);
String GetDisplayForModel(BindingModel model);
void AddObserver(KeyconfigView* observer); void AddObserver(KeyconfigView* observer);
void NotifyBindingsChanged(bool hasConflict); std::vector<BindingModel> GetBindingPrefs();
bool HasConflictingCombo(); virtual ~KeyconfigModel();
void PopBindingByFunctionId(int functionId);
void WriteDefaultFuncArray(bool force = false);
bool FunctionHasShortcut(int functionId);
int GetFunctionForBinding(int scan, bool shift, bool ctrl, bool alt);
protected: // void RemoveModelByIndex(int index);
void TurnOffFunctionShortcut(int functionId); // void AddModel(BindingModel model);
void TurnOnFunctionShortcut(int functionId); // void CreateModel(BindingModel model);
// String GetDisplayForModel(BindingModel model);
// void NotifyBindingsChanged(bool hasConflict);
// bool HasConflictingCombo();
// void PopBindingByFunctionId(int functionId);
// void WriteDefaultFuncArray(bool force = false);
// bool FunctionHasShortcut(int functionId);
// int GetFunctionForBinding(int scan, bool shift, bool ctrl, bool alt);
std::vector<KeyconfigView*> observers;
std::vector<BindingModel> bindingPrefs; // void Save();
std::pair<int, int> GetModifierAndScanFromString(ByteString str); // void WriteDefaultPrefs(bool force = false); // true if user clicks reset to defaults
// inline std::vector<BindingModel> GetBindingPrefs() const { return bindingPrefs; }
// void LoadBindingPrefs();
// protected:
// void TurnOffFunctionShortcut(int functionId);
// void TurnOnFunctionShortcut(int functionId);
// std::vector<BindingModel> bindingPrefs;
// std::pair<int, int> GetModifierAndScanFromString(ByteString str);
}; };
#endif // KEYCONFIGSMODEL_H #endif // KEYCONFIGSMODEL_H

View File

@ -1,5 +1,6 @@
static int Aa;
#if 0 // temporarily disabled so it doesn't interfere with what I'm doing -- LBPHacker
#include "KeyconfigTextbox.h" #include "KeyconfigTextbox.h"
#include "SDLCompat.h" #include "SDLCompat.h"
#include "gui/interface/Window.h" #include "gui/interface/Window.h"
#include "client/Client.h" #include "client/Client.h"
@ -118,3 +119,4 @@ void KeyconfigTextbox::OnKeyRelease(int key, int scan, bool repeat, bool shift,
// should the user carelessly click about // should the user carelessly click about
c->NotifyKeyReleased(); c->NotifyKeyReleased();
} }
#endif

View File

@ -1,5 +1,6 @@
static int Aa;
#if 0 // temporarily disabled so it doesn't interfere with what I'm doing -- LBPHacker
#include "KeyconfigView.h" #include "KeyconfigView.h"
#include "gui/interface/Button.h" #include "gui/interface/Button.h"
#include "gui/interface/Label.h" #include "gui/interface/Label.h"
#include "gui/interface/DropDown.h" #include "gui/interface/DropDown.h"
@ -289,3 +290,4 @@ KeyconfigView::~KeyconfigView()
{ {
} }
#endif

View File

@ -2,7 +2,6 @@
#include "OptionsView.h" #include "OptionsView.h"
#include "OptionsModel.h" #include "OptionsModel.h"
#include "gui/game/GameModel.h"
#include "Controller.h" #include "Controller.h"
@ -112,12 +111,6 @@ void OptionsController::Exit()
HasExited = true; HasExited = true;
} }
void OptionsController::NotifyKeyBindingsChanged()
{
gModel->NotifyKeyBindingsChanged();
}
OptionsController::~OptionsController() OptionsController::~OptionsController()
{ {
view->CloseActiveWindow(); view->CloseActiveWindow();

View File

@ -30,7 +30,6 @@ public:
void SetShowAvatars(bool showAvatars); void SetShowAvatars(bool showAvatars);
void SetMouseClickrequired(bool mouseClickRequired); void SetMouseClickrequired(bool mouseClickRequired);
void SetIncludePressure(bool includePressure); void SetIncludePressure(bool includePressure);
void NotifyKeyBindingsChanged();
void Exit(); void Exit();
OptionsView * GetView(); OptionsView * GetView();

View File

@ -18,8 +18,6 @@
#include "gui/interface/DropDown.h" #include "gui/interface/DropDown.h"
#include "gui/interface/Engine.h" #include "gui/interface/Engine.h"
#include "gui/interface/Checkbox.h" #include "gui/interface/Checkbox.h"
#include "gui/keyconfig/KeyconfigView.h"
#include "gui/keyconfig/KeyconfigController.h"
#include "graphics/Graphics.h" #include "graphics/Graphics.h"
@ -458,9 +456,9 @@ OptionsView::OptionsView():
KeyconfigAction() { } KeyconfigAction() { }
void ActionCallback(ui::Button * sender) override void ActionCallback(ui::Button * sender) override
{ {
OptionsView* v = (OptionsView*) sender->GetParentWindow(); // OptionsView* v = (OptionsView*) sender->GetParentWindow();
KeyconfigController* keyboardBindingsController = new KeyconfigController(v->c); // KeyconfigController* keyboardBindingsController = new KeyconfigController(v->c);
ui::Engine::Ref().ShowWindow(keyboardBindingsController->GetView()); // ui::Engine::Ref().ShowWindow(keyboardBindingsController->GetView());
} }
}; };