diff --git a/src/Controller.h b/src/Controller.h index 87680bd84..626e476cf 100644 --- a/src/Controller.h +++ b/src/Controller.h @@ -1,14 +1,6 @@ #ifndef CONTROLLER_H_ #define CONTROLLER_H_ -class ControllerCallback -{ -public: - ControllerCallback() {} - virtual void ControllerExit() {} - virtual ~ControllerCallback() {} -}; - class Controller { private: diff --git a/src/gui/colourpicker/ColourPickerActivity.cpp b/src/gui/colourpicker/ColourPickerActivity.cpp index 49c8f2599..9c92aebe3 100644 --- a/src/gui/colourpicker/ColourPickerActivity.cpp +++ b/src/gui/colourpicker/ColourPickerActivity.cpp @@ -10,64 +10,55 @@ #include "Misc.h" -ColourPickerActivity::ColourPickerActivity(ui::Colour initialColour, ColourPickedCallback * callback) : +ColourPickerActivity::ColourPickerActivity(ui::Colour initialColour, OnPicked onPicked_) : WindowActivity(ui::Point(-1, -1), ui::Point(266, 175)), currentHue(0), currentSaturation(0), currentValue(0), mouseDown(false), valueMouseDown(false), - callback(callback) + onPicked(onPicked_) { + auto colourChange = [this] { + int r, g, b, alpha; + r = rValue->GetText().ToNumber(true); + g = gValue->GetText().ToNumber(true); + b = bValue->GetText().ToNumber(true); + alpha = aValue->GetText().ToNumber(true); + if (r > 255) + r = 255; + if (g > 255) + g = 255; + if (b > 255) + b = 255; + if (alpha > 255) + alpha = 255; - class ColourChange : public ui::TextboxAction - { - ColourPickerActivity * a; - public: - ColourChange(ColourPickerActivity * a) : a(a) {} - - void TextChangedCallback(ui::Textbox * sender) override - { - int r, g, b, alpha; - r = a->rValue->GetText().ToNumber(true); - g = a->gValue->GetText().ToNumber(true); - b = a->bValue->GetText().ToNumber(true); - alpha = a->aValue->GetText().ToNumber(true); - if (r > 255) - r = 255; - if (g > 255) - g = 255; - if (b > 255) - b = 255; - if (alpha > 255) - alpha = 255; - - RGB_to_HSV(r, g, b, &a->currentHue, &a->currentSaturation, &a->currentValue); - a->currentAlpha = alpha; - a->UpdateTextboxes(r, g, b, alpha); - } + RGB_to_HSV(r, g, b, ¤tHue, ¤tSaturation, ¤tValue); + currentAlpha = alpha; + UpdateTextboxes(r, g, b, alpha); }; rValue = new ui::Textbox(ui::Point(5, Size.Y-23), ui::Point(30, 17), "255"); - rValue->SetActionCallback(new ColourChange(this)); + rValue->SetActionCallback({ colourChange }); rValue->SetLimit(3); rValue->SetInputType(ui::Textbox::Number); AddComponent(rValue); gValue = new ui::Textbox(ui::Point(40, Size.Y-23), ui::Point(30, 17), "255"); - gValue->SetActionCallback(new ColourChange(this)); + gValue->SetActionCallback({ colourChange }); gValue->SetLimit(3); gValue->SetInputType(ui::Textbox::Number); AddComponent(gValue); bValue = new ui::Textbox(ui::Point(75, Size.Y-23), ui::Point(30, 17), "255"); - bValue->SetActionCallback(new ColourChange(this)); + bValue->SetActionCallback({ colourChange }); bValue->SetLimit(3); bValue->SetInputType(ui::Textbox::Number); AddComponent(bValue); aValue = new ui::Textbox(ui::Point(110, Size.Y-23), ui::Point(30, 17), "255"); - aValue->SetActionCallback(new ColourChange(this)); + aValue->SetActionCallback({ colourChange }); aValue->SetLimit(3); aValue->SetInputType(ui::Textbox::Number); AddComponent(aValue); @@ -75,26 +66,17 @@ ColourPickerActivity::ColourPickerActivity(ui::Colour initialColour, ColourPicke hexValue = new::ui::Label(ui::Point(150, Size.Y-23), ui::Point(53, 17), "0xFFFFFFFF"); AddComponent(hexValue); - class OkayAction: public ui::ButtonAction - { - ColourPickerActivity * a; - public: - OkayAction(ColourPickerActivity * a) : a(a) { } - void ActionCallback(ui::Button * sender) override - { - int Red, Green, Blue; - Red = a->rValue->GetText().ToNumber(true); - Green = a->gValue->GetText().ToNumber(true); - Blue = a->bValue->GetText().ToNumber(true); - ui::Colour col(Red, Green, Blue, a->currentAlpha); - if(a->callback) - a->callback->ColourPicked(col); - a->Exit(); - } - }; - ui::Button * doneButton = new ui::Button(ui::Point(Size.X-45, Size.Y-23), ui::Point(40, 17), "Done"); - doneButton->SetActionCallback(new OkayAction(this)); + doneButton->SetActionCallback({ [this] { + int Red, Green, Blue; + Red = rValue->GetText().ToNumber(true); + Green = gValue->GetText().ToNumber(true); + Blue = bValue->GetText().ToNumber(true); + ui::Colour col(Red, Green, Blue, currentAlpha); + if (onPicked) + onPicked(col); + Exit(); + } }); AddComponent(doneButton); SetOkayButton(doneButton); @@ -316,8 +298,3 @@ void ColourPickerActivity::OnDraw() g->xor_line(offsetX+currentValueX, offsetY+4+128, offsetX+currentValueX, offsetY+13+128); g->xor_line(offsetX+currentValueX+1, offsetY+4+128, offsetX+currentValueX+1, offsetY+13+128); } - -ColourPickerActivity::~ColourPickerActivity() { - delete callback; -} - diff --git a/src/gui/colourpicker/ColourPickerActivity.h b/src/gui/colourpicker/ColourPickerActivity.h index 7efffc39d..6110250e6 100644 --- a/src/gui/colourpicker/ColourPickerActivity.h +++ b/src/gui/colourpicker/ColourPickerActivity.h @@ -4,21 +4,18 @@ #include "Activity.h" #include "gui/interface/Colour.h" +#include + namespace ui { class Textbox; class Label; } -class ColourPickedCallback +class ColourPickerActivity : public WindowActivity { -public: - ColourPickedCallback() {} - virtual ~ColourPickedCallback() {} - virtual void ColourPicked(ui::Colour colour) {} -}; + using OnPicked = std::function; -class ColourPickerActivity: public WindowActivity { int currentHue; int currentSaturation; int currentValue; @@ -33,16 +30,17 @@ class ColourPickerActivity: public WindowActivity { ui::Textbox * aValue; ui::Label * hexValue; - ColourPickedCallback * callback; + OnPicked onPicked; void UpdateTextboxes(int r, int g, int b, int a); public: + ColourPickerActivity(ui::Colour initialColour, OnPicked onPicked = nullptr); + virtual ~ColourPickerActivity() = default; + void OnMouseMove(int x, int y, int dx, int dy) override; void OnMouseDown(int x, int y, unsigned button) override; void OnMouseUp(int x, int y, unsigned button) override; void OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt) override; void OnTryExit(ExitMethod method) override; - ColourPickerActivity(ui::Colour initialColour, ColourPickedCallback * callback = NULL); - virtual ~ColourPickerActivity(); void OnDraw() override; }; diff --git a/src/gui/console/ConsoleController.cpp b/src/gui/console/ConsoleController.cpp index 2503e12c5..4f8bd2233 100644 --- a/src/gui/console/ConsoleController.cpp +++ b/src/gui/console/ConsoleController.cpp @@ -7,7 +7,7 @@ #include "lua/CommandInterface.h" -ConsoleController::ConsoleController(ControllerCallback * callback, CommandInterface * commandInterface): +ConsoleController::ConsoleController(std::function onDone, CommandInterface * commandInterface): HasDone(false) { consoleModel = new ConsoleModel(); @@ -15,7 +15,7 @@ ConsoleController::ConsoleController(ControllerCallback * callback, CommandInter consoleView->AttachController(this); consoleModel->AddObserver(consoleView); - this->callback = callback; + this->onDone = onDone; this->commandInterface = commandInterface; } @@ -59,8 +59,8 @@ void ConsoleController::PreviousCommand() void ConsoleController::Exit() { consoleView->CloseActiveWindow(); - if (callback) - callback->ControllerExit(); + if (onDone) + onDone(); HasDone = true; } @@ -72,7 +72,6 @@ ConsoleView * ConsoleController::GetView() ConsoleController::~ConsoleController() { consoleView->CloseActiveWindow(); - delete callback; delete consoleModel; delete consoleView; } diff --git a/src/gui/console/ConsoleController.h b/src/gui/console/ConsoleController.h index aea6ab98d..e6b08303e 100644 --- a/src/gui/console/ConsoleController.h +++ b/src/gui/console/ConsoleController.h @@ -3,19 +3,20 @@ #include "common/String.h" +#include + class CommandInterface; class ConsoleModel; class ConsoleView; -class ControllerCallback; class ConsoleController { - ControllerCallback * callback; ConsoleView * consoleView; ConsoleModel * consoleModel; CommandInterface * commandInterface; + std::function onDone; public: bool HasDone; - ConsoleController(ControllerCallback * callback, CommandInterface * commandInterface); + ConsoleController(std::function onDone, CommandInterface * commandInterface); String FormatCommand(String command); void EvaluateCommand(String command); void NextCommand(); diff --git a/src/gui/console/ConsoleView.cpp b/src/gui/console/ConsoleView.cpp index 7551f46cb..9c2848199 100644 --- a/src/gui/console/ConsoleView.cpp +++ b/src/gui/console/ConsoleView.cpp @@ -19,20 +19,10 @@ ConsoleView::ConsoleView(): ui::Window(ui::Point(0, 0), ui::Point(WINDOWW, 150)), commandField(NULL) { - class CommandHighlighter: public ui::TextboxAction - { - ConsoleView * v; - public: - CommandHighlighter(ConsoleView * v_) { v = v_; } - void TextChangedCallback(ui::Textbox * sender) override - { - sender->SetDisplayText(v->c->FormatCommand(sender->GetText())); - } - }; commandField = new ui::Textbox(ui::Point(0, Size.Y-16), ui::Point(Size.X, 16), ""); commandField->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; commandField->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; - commandField->SetActionCallback(new CommandHighlighter(this)); + commandField->SetActionCallback({ [this] { commandField->SetDisplayText(c->FormatCommand(commandField->GetText())); } }); AddComponent(commandField); FocusComponent(commandField); commandField->SetBorder(false); diff --git a/src/gui/dialogues/ConfirmPrompt.cpp b/src/gui/dialogues/ConfirmPrompt.cpp index 738e3f597..5c5b804cc 100644 --- a/src/gui/dialogues/ConfirmPrompt.cpp +++ b/src/gui/dialogues/ConfirmPrompt.cpp @@ -11,69 +11,7 @@ #include "graphics/Graphics.h" -ConfirmPrompt::ConfirmPrompt(String title, String message, ConfirmDialogueCallback * callback_): - ui::Window(ui::Point(-1, -1), ui::Point(250, 35)), - callback(callback_) -{ - ui::Label * titleLabel = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 15), title); - titleLabel->SetTextColour(style::Colour::WarningTitle); - titleLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; - titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; - AddComponent(titleLabel); - - - ui::ScrollPanel *messagePanel = new ui::ScrollPanel(ui::Point(4, 24), ui::Point(Size.X-8, 206)); - AddComponent(messagePanel); - - ui::Label * messageLabel = new ui::Label(ui::Point(4, 0), ui::Point(Size.X-28, -1), message); - messageLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; - messageLabel->Appearance.VerticalAlign = ui::Appearance::AlignTop; - messageLabel->SetMultiline(true); - messagePanel->AddChild(messageLabel); - - messagePanel->InnerSize = ui::Point(messagePanel->Size.X, messageLabel->Size.Y+4); - - if (messageLabel->Size.Y < messagePanel->Size.Y) - messagePanel->Size.Y = messageLabel->Size.Y+4; - Size.Y += messagePanel->Size.Y+12; - Position.Y = (ui::Engine::Ref().GetHeight()-Size.Y)/2; - - class CloseAction: public ui::ButtonAction - { - public: - ConfirmPrompt * prompt; - DialogueResult result; - CloseAction(ConfirmPrompt * prompt_, DialogueResult result_) { prompt = prompt_; result = result_; } - void ActionCallback(ui::Button * sender) override - { - prompt->CloseActiveWindow(); - if(prompt->callback) - prompt->callback->ConfirmCallback(result); - prompt->SelfDestruct(); - } - }; - - - ui::Button * cancelButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X-75, 16), "Cancel"); - cancelButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; - cancelButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; - cancelButton->Appearance.BorderInactive = ui::Colour(200, 200, 200); - cancelButton->SetActionCallback(new CloseAction(this, ResultCancel)); - AddComponent(cancelButton); - SetCancelButton(cancelButton); - - ui::Button * okayButton = new ui::Button(ui::Point(Size.X-76, Size.Y-16), ui::Point(76, 16), "Continue"); - okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; - okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; - okayButton->Appearance.TextInactive = style::Colour::WarningTitle; - okayButton->SetActionCallback(new CloseAction(this, ResultOkay)); - AddComponent(okayButton); - SetOkayButton(okayButton); - - MakeActiveWindow(); -} - -ConfirmPrompt::ConfirmPrompt(String title, String message, String buttonText, ConfirmDialogueCallback * callback_): +ConfirmPrompt::ConfirmPrompt(String title, String message, ResultCallback callback_, String buttonText): ui::Window(ui::Point(-1, -1), ui::Point(250, 50)), callback(callback_) { @@ -100,27 +38,16 @@ ConfirmPrompt::ConfirmPrompt(String title, String message, String buttonText, Co Size.Y += messagePanel->Size.Y+12; Position.Y = (ui::Engine::Ref().GetHeight()-Size.Y)/2; - class CloseAction: public ui::ButtonAction - { - public: - ConfirmPrompt * prompt; - DialogueResult result; - CloseAction(ConfirmPrompt * prompt_, DialogueResult result_) { prompt = prompt_; result = result_; } - void ActionCallback(ui::Button * sender) override - { - prompt->CloseActiveWindow(); - if(prompt->callback) - prompt->callback->ConfirmCallback(result); - prompt->SelfDestruct(); - } - }; - - ui::Button * cancelButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X-75, 16), "Cancel"); cancelButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; cancelButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; cancelButton->Appearance.BorderInactive = ui::Colour(200, 200, 200); - cancelButton->SetActionCallback(new CloseAction(this, ResultCancel)); + cancelButton->SetActionCallback({ [this] { + CloseActiveWindow(); + if (callback.cancel) + callback.cancel(); + SelfDestruct(); + } }); AddComponent(cancelButton); SetCancelButton(cancelButton); @@ -128,7 +55,12 @@ ConfirmPrompt::ConfirmPrompt(String title, String message, String buttonText, Co okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; okayButton->Appearance.TextInactive = style::Colour::WarningTitle; - okayButton->SetActionCallback(new CloseAction(this, ResultOkay)); + okayButton->SetActionCallback({ [this] { + CloseActiveWindow(); + if (callback.okay) + callback.okay(); + SelfDestruct(); + } }); AddComponent(okayButton); SetOkayButton(okayButton); @@ -137,23 +69,13 @@ ConfirmPrompt::ConfirmPrompt(String title, String message, String buttonText, Co bool ConfirmPrompt::Blocking(String title, String message, String buttonText) { - class BlockingPromptCallback: public ConfirmDialogueCallback { - public: - bool & outputResult; - BlockingPromptCallback(bool & output): outputResult(output) {} - void ConfirmCallback(ConfirmPrompt::DialogueResult result) override { - if (result == ConfirmPrompt::ResultOkay) - outputResult = true; - else - outputResult = false; - ui::Engine::Ref().Break(); - } - virtual ~BlockingPromptCallback() { } - }; - bool result; - new ConfirmPrompt(title, message, buttonText, new BlockingPromptCallback(result)); + bool outputResult; + new ConfirmPrompt(title, message, { + [&outputResult] { outputResult = true; ui::Engine::Ref().Break(); }, + [&outputResult] { outputResult = false; ui::Engine::Ref().Break(); }, + }, buttonText); EngineProcess(); - return result; + return outputResult; } void ConfirmPrompt::OnDraw() @@ -163,8 +85,3 @@ void ConfirmPrompt::OnDraw() g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3); g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255); } - -ConfirmPrompt::~ConfirmPrompt() { - delete callback; -} - diff --git a/src/gui/dialogues/ConfirmPrompt.h b/src/gui/dialogues/ConfirmPrompt.h index 42f571f15..ef84c0c49 100644 --- a/src/gui/dialogues/ConfirmPrompt.h +++ b/src/gui/dialogues/ConfirmPrompt.h @@ -3,23 +3,23 @@ #include "gui/interface/Window.h" -class ConfirmDialogueCallback; -class ConfirmPrompt: public ui::Window { +#include + +class ConfirmPrompt : public ui::Window +{ + struct ResultCallback + { + std::function okay, cancel; + }; + + ResultCallback callback; + public: - enum DialogueResult { ResultCancel, ResultOkay }; - ConfirmPrompt(String title, String message, ConfirmDialogueCallback * callback_ = NULL); - ConfirmPrompt(String title, String message, String buttonText, ConfirmDialogueCallback * callback_ = NULL); + ConfirmPrompt(String title, String message, ResultCallback callback_ = {}, String buttonText = String("Confirm")); + virtual ~ConfirmPrompt() = default; + static bool Blocking(String title, String message, String buttonText = String("Confirm")); void OnDraw() override; - virtual ~ConfirmPrompt(); - ConfirmDialogueCallback * callback; -}; - -class ConfirmDialogueCallback -{ - public: - virtual void ConfirmCallback(ConfirmPrompt::DialogueResult result) {} - virtual ~ConfirmDialogueCallback() {} }; #endif /* CONFIRMPROMPT_H_ */ diff --git a/src/gui/dialogues/ErrorMessage.cpp b/src/gui/dialogues/ErrorMessage.cpp index c643b7335..557e2301f 100644 --- a/src/gui/dialogues/ErrorMessage.cpp +++ b/src/gui/dialogues/ErrorMessage.cpp @@ -10,7 +10,7 @@ #include "graphics/Graphics.h" -ErrorMessage::ErrorMessage(String title, String message, ErrorMessageCallback * callback_): +ErrorMessage::ErrorMessage(String title, String message, DismissCallback callback_): ui::Window(ui::Point(-1, -1), ui::Point(200, 35)), callback(callback_) { @@ -29,25 +29,16 @@ ErrorMessage::ErrorMessage(String title, String message, ErrorMessageCallback * Size.Y += messageLabel->Size.Y+12; Position.Y = (ui::Engine::Ref().GetHeight()-Size.Y)/2; - class DismissAction: public ui::ButtonAction - { - ErrorMessage * message; - public: - DismissAction(ErrorMessage * message_) { message = message_; } - void ActionCallback(ui::Button * sender) override - { - message->CloseActiveWindow(); - if(message->callback) - message->callback->DismissCallback(); - message->SelfDestruct(); - } - }; - ui::Button * okayButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X, 16), "Dismiss"); okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; okayButton->Appearance.BorderInactive = ui::Colour(200, 200, 200); - okayButton->SetActionCallback(new DismissAction(this)); + okayButton->SetActionCallback({ [this] { + CloseActiveWindow(); + if (callback.dismiss) + callback.dismiss(); + SelfDestruct(); + } }); AddComponent(okayButton); SetOkayButton(okayButton); SetCancelButton(okayButton); @@ -57,15 +48,9 @@ ErrorMessage::ErrorMessage(String title, String message, ErrorMessageCallback * void ErrorMessage::Blocking(String title, String message) { - class BlockingDismissCallback: public ErrorMessageCallback { - public: - BlockingDismissCallback() {} - void DismissCallback() override { - ui::Engine::Ref().Break(); - } - virtual ~BlockingDismissCallback() { } - }; - new ErrorMessage(title, message, new BlockingDismissCallback()); + new ErrorMessage(title, message, { [] { + ui::Engine::Ref().Break(); + } }); EngineProcess(); } @@ -76,8 +61,3 @@ void ErrorMessage::OnDraw() g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3); g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255); } - -ErrorMessage::~ErrorMessage() { - delete callback; -} - diff --git a/src/gui/dialogues/ErrorMessage.h b/src/gui/dialogues/ErrorMessage.h index 6f38a81e7..003258554 100644 --- a/src/gui/dialogues/ErrorMessage.h +++ b/src/gui/dialogues/ErrorMessage.h @@ -3,21 +3,23 @@ #include "gui/interface/Window.h" -class ErrorMessageCallback; -class ErrorMessage: public ui::Window { - ErrorMessageCallback * callback; +#include + +class ErrorMessage : public ui::Window +{ + struct DismissCallback + { + std::function dismiss; + }; + + DismissCallback callback; + public: - ErrorMessage(String title, String message, ErrorMessageCallback * callback_ = NULL); + ErrorMessage(String title, String message, DismissCallback callback_ = {}); + virtual ~ErrorMessage() = default; + static void Blocking(String title, String message); void OnDraw() override; - virtual ~ErrorMessage(); -}; - -class ErrorMessageCallback -{ - public: - virtual void DismissCallback() {} - virtual ~ErrorMessageCallback() {} }; #endif /* ERRORMESSAGE_H_ */ diff --git a/src/gui/dialogues/InformationMessage.cpp b/src/gui/dialogues/InformationMessage.cpp index 38056fdb7..3257a610d 100644 --- a/src/gui/dialogues/InformationMessage.cpp +++ b/src/gui/dialogues/InformationMessage.cpp @@ -55,23 +55,14 @@ InformationMessage::InformationMessage(String title, String message, bool large) titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; AddComponent(titleLabel); - class DismissAction: public ui::ButtonAction - { - InformationMessage * message; - public: - DismissAction(InformationMessage * message_) { message = message_; } - void ActionCallback(ui::Button * sender) override - { - message->CloseActiveWindow(); - message->SelfDestruct(); //TODO: Fix component disposal - } - }; - ui::Button * okayButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X, 16), "Dismiss"); okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; okayButton->Appearance.BorderInactive = ui::Colour(200, 200, 200); - okayButton->SetActionCallback(new DismissAction(this)); + okayButton->SetActionCallback({ [this] { + CloseActiveWindow(); + SelfDestruct(); //TODO: Fix component disposal + } }); AddComponent(okayButton); SetOkayButton(okayButton); SetCancelButton(okayButton); @@ -86,7 +77,3 @@ void InformationMessage::OnDraw() g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3); g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255); } - -InformationMessage::~InformationMessage() { -} - diff --git a/src/gui/dialogues/InformationMessage.h b/src/gui/dialogues/InformationMessage.h index 020c70272..1570d6f1d 100644 --- a/src/gui/dialogues/InformationMessage.h +++ b/src/gui/dialogues/InformationMessage.h @@ -3,11 +3,13 @@ #include "gui/interface/Window.h" -class InformationMessage: public ui::Window { +class InformationMessage : public ui::Window +{ public: InformationMessage(String title, String message, bool large); + virtual ~InformationMessage() = default; + void OnDraw() override; - virtual ~InformationMessage(); }; #endif /* INFORMATIONMESSAGE_H_ */ diff --git a/src/gui/dialogues/SaveIDMessage.cpp b/src/gui/dialogues/SaveIDMessage.cpp index 8c81689f8..95b9a1c1c 100644 --- a/src/gui/dialogues/SaveIDMessage.cpp +++ b/src/gui/dialogues/SaveIDMessage.cpp @@ -36,22 +36,13 @@ SaveIDMessage::SaveIDMessage(int id): ui::CopyTextButton * copyTextButton = new ui::CopyTextButton(ui::Point((Size.X-textWidth-10)/2, 50), ui::Point(textWidth+10, 18), String::Build(id), copyTextLabel); AddComponent(copyTextButton); - class DismissAction: public ui::ButtonAction - { - SaveIDMessage * message; - public: - DismissAction(SaveIDMessage * message_) { message = message_; } - void ActionCallback(ui::Button * sender) override - { - message->CloseActiveWindow(); - message->SelfDestruct(); - } - }; - ui::Button * okayButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X, 16), "OK"); okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; - okayButton->SetActionCallback(new DismissAction(this)); + okayButton->SetActionCallback({ [this] { + CloseActiveWindow(); + SelfDestruct(); + } }); AddComponent(okayButton); // This button has multiple personalities SetOkayButton(okayButton); @@ -73,9 +64,3 @@ void SaveIDMessage::OnTryExit(ExitMethod method) CloseActiveWindow(); SelfDestruct(); } - -SaveIDMessage::~SaveIDMessage() -{ - -} - diff --git a/src/gui/dialogues/SaveIDMessage.h b/src/gui/dialogues/SaveIDMessage.h index ff3243930..bf4c7b24e 100644 --- a/src/gui/dialogues/SaveIDMessage.h +++ b/src/gui/dialogues/SaveIDMessage.h @@ -3,12 +3,14 @@ #include "gui/interface/Window.h" -class SaveIDMessage: public ui::Window { +class SaveIDMessage : public ui::Window +{ public: SaveIDMessage(int id); + virtual ~SaveIDMessage() = default; + void OnDraw() override; void OnTryExit(ExitMethod method) override; - virtual ~SaveIDMessage(); }; #endif /* SAVEIDMESSAGE_H */ diff --git a/src/gui/dialogues/TextPrompt.cpp b/src/gui/dialogues/TextPrompt.cpp index 439917ca9..bd4db5c50 100644 --- a/src/gui/dialogues/TextPrompt.cpp +++ b/src/gui/dialogues/TextPrompt.cpp @@ -10,22 +10,7 @@ #include "graphics/Graphics.h" -class CloseAction: public ui::ButtonAction -{ -public: - TextPrompt * prompt; - TextPrompt::DialogueResult result; - CloseAction(TextPrompt * prompt_, TextPrompt::DialogueResult result_) { prompt = prompt_; result = result_; } - void ActionCallback(ui::Button * sender) override - { - prompt->CloseActiveWindow(); - if(prompt->callback) - prompt->callback->TextCallback(result, prompt->textField->GetText()); - prompt->SelfDestruct(); //TODO: Fix component disposal - } -}; - -TextPrompt::TextPrompt(String title, String message, String text, String placeholder, bool multiline, TextDialogueCallback * callback_): +TextPrompt::TextPrompt(String title, String message, String text, String placeholder, bool multiline, TextDialogueCallback callback_): ui::Window(ui::Point(-1, -1), ui::Point(200, 65)), callback(callback_) { @@ -66,7 +51,12 @@ TextPrompt::TextPrompt(String title, String message, String text, String placeho cancelButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; cancelButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; cancelButton->Appearance.BorderInactive = ui::Colour(200, 200, 200); - cancelButton->SetActionCallback(new CloseAction(this, ResultCancel)); + cancelButton->SetActionCallback({ [this] { + CloseActiveWindow(); + if (callback.cancel) + callback.cancel(); + SelfDestruct(); + } }); AddComponent(cancelButton); SetCancelButton(cancelButton); @@ -74,7 +64,12 @@ TextPrompt::TextPrompt(String title, String message, String text, String placeho okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignRight; okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; okayButton->Appearance.TextInactive = style::Colour::WarningTitle; - okayButton->SetActionCallback(new CloseAction(this, ResultOkay)); + okayButton->SetActionCallback({ [this] { + CloseActiveWindow(); + if (callback.text) + callback.text(textField->GetText()); + SelfDestruct(); + } }); AddComponent(okayButton); SetOkayButton(okayButton); @@ -83,25 +78,12 @@ TextPrompt::TextPrompt(String title, String message, String text, String placeho String TextPrompt::Blocking(String title, String message, String text, String placeholder, bool multiline) { - String returnString = ""; - - class BlockingTextCallback: public TextDialogueCallback { - String & outputString; - public: - BlockingTextCallback(String & output) : outputString(output) {} - void TextCallback(TextPrompt::DialogueResult result, String resultText) override { - if(result == ResultOkay) - outputString = resultText; - else - outputString = ""; - ui::Engine::Ref().Break(); - } - virtual ~BlockingTextCallback() { } - }; - new TextPrompt(title, message, text, placeholder, multiline, new BlockingTextCallback(returnString)); + String outputString; + new TextPrompt(title, message, text, placeholder, multiline, { [&outputString](String const &resultText) { + outputString = resultText; + } }); EngineProcess(); - - return returnString; + return outputString; } void TextPrompt::OnDraw() @@ -111,8 +93,3 @@ void TextPrompt::OnDraw() g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3); g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255); } - -TextPrompt::~TextPrompt() { - delete callback; -} - diff --git a/src/gui/dialogues/TextPrompt.h b/src/gui/dialogues/TextPrompt.h index c59f683c1..c86699d29 100644 --- a/src/gui/dialogues/TextPrompt.h +++ b/src/gui/dialogues/TextPrompt.h @@ -3,31 +3,32 @@ #include "gui/interface/Window.h" +#include + namespace ui { class Textbox; } -class TextDialogueCallback; -class TextPrompt: public ui::Window +class TextPrompt : public ui::Window { + struct TextDialogueCallback + { + std::function text; + std::function cancel; + }; + + TextDialogueCallback callback; + protected: ui::Textbox * textField; + public: - friend class CloseAction; - enum DialogueResult { ResultCancel, ResultOkay }; - TextPrompt(String title, String message, String text, String placeholder, bool multiline, TextDialogueCallback * callback_); + TextPrompt(String title, String message, String text, String placeholder, bool multiline, TextDialogueCallback callback_ = {}); + virtual ~TextPrompt() = default; + static String Blocking(String title, String message, String text, String placeholder, bool multiline); void OnDraw() override; - virtual ~TextPrompt(); - TextDialogueCallback * callback; -}; - -class TextDialogueCallback -{ - public: - virtual void TextCallback(TextPrompt::DialogueResult result, String resultText) {} - virtual ~TextDialogueCallback() {} }; #endif /* TEXTPROMPT_H_ */ diff --git a/src/gui/elementsearch/ElementSearchActivity.cpp b/src/gui/elementsearch/ElementSearchActivity.cpp index 2d65dbfcb..0f9ccc021 100644 --- a/src/gui/elementsearch/ElementSearchActivity.cpp +++ b/src/gui/elementsearch/ElementSearchActivity.cpp @@ -15,20 +15,6 @@ #include "graphics/Graphics.h" -class ElementSearchActivity::ToolAction: public ui::ButtonAction -{ - ElementSearchActivity * a; -public: - Tool * tool; - ToolAction(ElementSearchActivity * a, Tool * tool) : a(a), tool(tool) { } - void ActionCallback(ui::Button * sender_) override - { - ToolButton *sender = (ToolButton*)sender_; - if(sender->GetSelectionState() >= 0 && sender->GetSelectionState() <= 2) - a->SetActiveTool(sender->GetSelectionState(), tool); - } -}; - ElementSearchActivity::ElementSearchActivity(GameController * gameController, std::vector tools) : WindowActivity(ui::Point(-1, -1), ui::Point(236, 302)), firstResult(NULL), @@ -47,50 +33,19 @@ ElementSearchActivity::ElementSearchActivity(GameController * gameController, st title->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; AddComponent(title); - class SearchAction : public ui::TextboxAction - { - private: - ElementSearchActivity * a; - public: - SearchAction(ElementSearchActivity * a) : a(a) {} - void TextChangedCallback(ui::Textbox * sender) override { - a->searchTools(sender->GetText()); - } - }; - searchField = new ui::Textbox(ui::Point(8, 23), ui::Point(Size.X-16, 17), ""); - searchField->SetActionCallback(new SearchAction(this)); + searchField->SetActionCallback({ [this] { searchTools(searchField->GetText()); } }); searchField->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; AddComponent(searchField); FocusComponent(searchField); - class CloseAction: public ui::ButtonAction - { - ElementSearchActivity * a; - public: - CloseAction(ElementSearchActivity * a) : a(a) { } - void ActionCallback(ui::Button * sender_) override - { - a->exit = true; - } - }; - - class OKAction: public ui::ButtonAction - { - ElementSearchActivity * a; - public: - OKAction(ElementSearchActivity * a) : a(a) { } - void ActionCallback(ui::Button * sender_) override - { - if(a->GetFirstResult()) - a->SetActiveTool(0, a->GetFirstResult()); - } - }; - ui::Button * closeButton = new ui::Button(ui::Point(0, Size.Y-15), ui::Point((Size.X/2)+1, 15), "Close"); - closeButton->SetActionCallback(new CloseAction(this)); + closeButton->SetActionCallback({ [this] { exit = true; } }); ui::Button * okButton = new ui::Button(ui::Point(Size.X/2, Size.Y-15), ui::Point(Size.X/2, 15), "OK"); - okButton->SetActionCallback(new OKAction(this)); + okButton->SetActionCallback({ [this] { + if (GetFirstResult()) + SetActiveTool(0, GetFirstResult()); + } }); AddComponent(okButton); AddComponent(closeButton); @@ -194,7 +149,10 @@ void ElementSearchActivity::searchTools(String query) tempButton->Appearance.SetTexture(tempTexture); tempButton->Appearance.BackgroundInactive = ui::Colour(tool->colRed, tool->colGreen, tool->colBlue); - tempButton->SetActionCallback(new ToolAction(this, tool)); + tempButton->SetActionCallback({ [this, tempButton, tool] { + if (tempButton->GetSelectionState() >= 0 && tempButton->GetSelectionState() <= 2) + SetActiveTool(tempButton->GetSelectionState(), tool); + } }); if(gameController->GetActiveTool(0) == tool) { diff --git a/src/gui/elementsearch/ElementSearchActivity.h b/src/gui/elementsearch/ElementSearchActivity.h index e3a17e197..09444b143 100644 --- a/src/gui/elementsearch/ElementSearchActivity.h +++ b/src/gui/elementsearch/ElementSearchActivity.h @@ -31,7 +31,6 @@ class ElementSearchActivity: public WindowActivity void searchTools(String query); public: - class ToolAction; bool exit; Tool * GetFirstResult() { return firstResult; } ElementSearchActivity(GameController * gameController, std::vector tools); diff --git a/src/gui/filebrowser/FileBrowserActivity.cpp b/src/gui/filebrowser/FileBrowserActivity.cpp index 05fc4661d..fc8537edf 100644 --- a/src/gui/filebrowser/FileBrowserActivity.cpp +++ b/src/gui/filebrowser/FileBrowserActivity.cpp @@ -21,25 +21,6 @@ #include "graphics/Graphics.h" -class SaveSelectedAction: public ui::SaveButtonAction -{ - FileBrowserActivity * a; -public: - SaveSelectedAction(FileBrowserActivity * _a) { a = _a; } - void ActionCallback(ui::SaveButton * sender) override - { - a->SelectSave(sender->GetSaveFile()); - } - void AltActionCallback(ui::SaveButton * sender) override - { - a->RenameSave(sender->GetSaveFile()); - } - void AltActionCallback2(ui::SaveButton * sender) override - { - a->DeleteSave(sender->GetSaveFile()); - } -}; - //Currently, reading is done on another thread, we can't render outside the main thread due to some bullshit with OpenGL class LoadFilesTask: public Task { @@ -99,19 +80,9 @@ public: } }; -class FileBrowserActivity::SearchAction: public ui::TextboxAction -{ -public: - FileBrowserActivity * a; - SearchAction(FileBrowserActivity * a) : a(a) {} - void TextChangedCallback(ui::Textbox * sender) override { - a->DoSearch(sender->GetText().ToUtf8()); - } -}; - -FileBrowserActivity::FileBrowserActivity(ByteString directory, FileSelectedCallback * callback): +FileBrowserActivity::FileBrowserActivity(ByteString directory, OnSelected onSelected_): WindowActivity(ui::Point(-1, -1), ui::Point(500, 350)), - callback(callback), + onSelected(onSelected_), directory(directory), totalFiles(0) { @@ -125,7 +96,7 @@ FileBrowserActivity::FileBrowserActivity(ByteString directory, FileSelectedCallb ui::Textbox * textField = new ui::Textbox(ui::Point(8, 25), ui::Point(Size.X-16, 16), "", "[search]"); textField->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; textField->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; - textField->SetActionCallback(new SearchAction(this)); + textField->SetActionCallback({ [this, textField] { DoSearch(textField->GetText().ToUtf8()); } }); AddComponent(textField); FocusComponent(textField); @@ -165,8 +136,8 @@ void FileBrowserActivity::DoSearch(ByteString search) void FileBrowserActivity::SelectSave(SaveFile * file) { - if(callback) - callback->FileSelected(new SaveFile(*file)); + if (onSelected) + onSelected(std::unique_ptr(new SaveFile(*file))); Exit(); } @@ -303,7 +274,12 @@ void FileBrowserActivity::OnTick(float dt) saveFile); saveButton->AddContextMenu(1); saveButton->Tick(dt); - saveButton->SetActionCallback(new SaveSelectedAction(this)); + saveButton->SetActionCallback({ + [this, saveButton] { SelectSave(saveButton->GetSaveFile()); }, + [this, saveButton] { RenameSave(saveButton->GetSaveFile()); }, + [this, saveButton] { DeleteSave(saveButton->GetSaveFile()); } + }); + progressBar->SetStatus("Rendering thumbnails"); progressBar->SetProgress((float(totalFiles-files.size())/float(totalFiles))*100.0f); componentsQueue.push_back(saveButton); @@ -334,6 +310,5 @@ void FileBrowserActivity::OnDraw() FileBrowserActivity::~FileBrowserActivity() { - delete callback; cleanup(); } diff --git a/src/gui/filebrowser/FileBrowserActivity.h b/src/gui/filebrowser/FileBrowserActivity.h index 78172b1a4..f75619112 100644 --- a/src/gui/filebrowser/FileBrowserActivity.h +++ b/src/gui/filebrowser/FileBrowserActivity.h @@ -1,18 +1,14 @@ #pragma once -#include #include "common/String.h" #include "Activity.h" #include "tasks/TaskListener.h" +#include +#include +#include + class SaveFile; -class FileSelectedCallback -{ -public: - FileSelectedCallback() {} - virtual ~FileSelectedCallback() {} - virtual void FileSelected(SaveFile* file) {} -}; namespace ui { @@ -24,8 +20,10 @@ namespace ui class LoadFilesTask; class FileBrowserActivity: public TaskListener, public WindowActivity { + using OnSelected = std::function)>; + LoadFilesTask * loadFiles; - FileSelectedCallback * callback; + OnSelected onSelected; ui::ScrollPanel * itemList; ui::Label * infoText; std::vector files; @@ -40,12 +38,12 @@ class FileBrowserActivity: public TaskListener, public WindowActivity int fileX, fileY; int buttonWidth, buttonHeight, buttonAreaWidth, buttonAreaHeight, buttonXOffset, buttonYOffset; - - class SearchAction; void populateList(); void cleanup(); public: - FileBrowserActivity(ByteString directory, FileSelectedCallback * callback); + FileBrowserActivity(ByteString directory, OnSelected onSelected = nullptr); + virtual ~FileBrowserActivity(); + void OnDraw() override; void OnTick(float dt) override; void OnTryExit(ExitMethod method) override; @@ -55,7 +53,6 @@ public: void DeleteSave(SaveFile * file); void RenameSave(SaveFile * file); void DoSearch(ByteString search); - virtual ~FileBrowserActivity(); void NotifyDone(Task * task) override; void NotifyError(Task * task) override; diff --git a/src/gui/font/FontEditor.cpp b/src/gui/font/FontEditor.cpp index 980a75dbf..c5ecfd478 100644 --- a/src/gui/font/FontEditor.cpp +++ b/src/gui/font/FontEditor.cpp @@ -272,204 +272,105 @@ FontEditor::FontEditor(ByteString _header): int baseline = 8 + FONT_H * FONT_SCALE + 4 + FONT_H + 4 + 1; int currentX = 1; - class PrevCharAction : public ui::ButtonAction - { - FontEditor *v; - public: - PrevCharAction(FontEditor *_v): v(_v) {} - void ActionCallback(ui::Button *) - { - v->PrevChar(); - } - }; ui::Button *prev = new ui::Button(ui::Point(currentX, baseline), ui::Point(17, 17), 0xE016); currentX += 18; - prev->SetActionCallback(new PrevCharAction(this)); + prev->SetActionCallback({ [this] { PrevChar(); } }); AddComponent(prev); - class CharNumberAction : public ui::TextboxAction - { - FontEditor *v; - public: - CharNumberAction(FontEditor *_v): v(_v) {} - void TextChangedCallback(ui::Textbox *) - { - unsigned int number = v->currentCharTextbox->GetText().ToNumber(Format::Hex(), true); - if(number <= 0x10FFFF) - v->currentChar = number; - } - }; currentCharTextbox = new ui::Textbox(ui::Point(currentX, baseline), ui::Point(31, 17)); currentX += 32; - currentCharTextbox->SetActionCallback(new CharNumberAction(this)); + currentCharTextbox->SetActionCallback({ [this] { + unsigned int number = currentCharTextbox->GetText().ToNumber(Format::Hex(), true); + if(number <= 0x10FFFF) + currentChar = number; + } }); UpdateCharNumber(); AddComponent(currentCharTextbox); - class NextCharAction : public ui::ButtonAction - { - FontEditor *v; - public: - NextCharAction(FontEditor *_v): v(_v) {} - void ActionCallback(ui::Button *) - { - v->NextChar(); - } - }; ui::Button *next = new ui::Button(ui::Point(currentX, baseline), ui::Point(17, 17), 0xE015); currentX += 18; - next->SetActionCallback(new NextCharAction(this)); + next->SetActionCallback({ [this] { NextChar(); } }); AddComponent(next); - class ShrinkCharAction : public ui::ButtonAction - { - FontEditor *v; - public: - ShrinkCharAction(FontEditor *_v): v(_v) {} - void ActionCallback(ui::Button *) - { - v->ShrinkChar(); - } - }; ui::Button *shrink = new ui::Button(ui::Point(currentX, baseline), ui::Point(17, 17), "><"); currentX += 18; - shrink->SetActionCallback(new ShrinkCharAction(this)); + shrink->SetActionCallback({ [this] { ShrinkChar(); } }); AddComponent(shrink); - class GrowCharAction : public ui::ButtonAction - { - FontEditor *v; - public: - GrowCharAction(FontEditor *_v): v(_v) {} - void ActionCallback(ui::Button *) - { - v->GrowChar(); - } - }; ui::Button *grow = new ui::Button(ui::Point(currentX, baseline), ui::Point(17, 17), "<>"); currentX += 18; - grow->SetActionCallback(new GrowCharAction(this)); + grow->SetActionCallback({ [this] { GrowChar(); } }); AddComponent(grow); - class AddCharAction : public ui::ButtonAction - { - FontEditor *v; - public: - AddCharAction(FontEditor *_v): v(_v) {} - void ActionCallback(ui::Button *) - { - if(v->fontWidths.find(v->currentChar) == v->fontWidths.end()) - { - v->savedButton->SetToggleState(false); - v->fontWidths[v->currentChar] = 5; - v->fontPixels[v->currentChar]; - } - } - }; ui::Button *add = new ui::Button(ui::Point(currentX, baseline), ui::Point(36, 17), "Add"); currentX += 37; - add->SetActionCallback(new AddCharAction(this)); + add->SetActionCallback({ [this] { + if (fontWidths.find(currentChar) == fontWidths.end()) + { + savedButton->SetToggleState(false); + fontWidths[currentChar] = 5; + fontPixels[currentChar]; + } + } }); AddComponent(add); - class RemoveCharAction : public ui::ButtonAction - { - FontEditor *v; - public: - RemoveCharAction(FontEditor *_v): v(_v) {} - void ActionCallback(ui::Button *) - { - if(v->fontWidths.find(v->currentChar) != v->fontWidths.end()) - { - v->savedButton->SetToggleState(false); - v->fontWidths.erase(v->currentChar); - v->fontPixels.erase(v->currentChar); - } - } - }; ui::Button *remove = new ui::Button(ui::Point(currentX, baseline), ui::Point(36, 17), "Remove"); currentX += 37; - remove->SetActionCallback(new RemoveCharAction(this)); + remove->SetActionCallback({ [this] { + if (fontWidths.find(currentChar) != fontWidths.end()) + { + savedButton->SetToggleState(false); + fontWidths.erase(currentChar); + fontPixels.erase(currentChar); + } + } }); AddComponent(remove); - class ToggleAction : public ui::ButtonAction - { - int &toggle; - public: - ToggleAction(int &_toggle): toggle(_toggle) {} - void ActionCallback(ui::Button *button) - { - toggle = button->GetToggleState(); - } - }; - ui::Button *showGrid = new ui::Button(ui::Point(currentX, baseline), ui::Point(32, 17), "Grid"); currentX += 33; showGrid->SetTogglable(true); showGrid->SetToggleState(grid); - showGrid->SetActionCallback(new ToggleAction(grid)); + showGrid->SetActionCallback({ [this, showGrid] { + grid = showGrid->GetToggleState(); + } }); AddComponent(showGrid); ui::Button *showRulers = new ui::Button(ui::Point(currentX, baseline), ui::Point(32, 17), "Rulers"); currentX += 33; showRulers->SetTogglable(true); - showRulers->SetToggleState(grid); - showRulers->SetActionCallback(new ToggleAction(rulers)); + showRulers->SetToggleState(rulers); + showRulers->SetActionCallback({ [this, showGrid] { + rulers = showGrid->GetToggleState(); + } }); AddComponent(showRulers); baseline += 18; currentX = 1; - class ColorComponentAction : public ui::TextboxAction - { - int &color; - public: - ColorComponentAction(int &_color): color(_color) {} - void TextChangedCallback(ui::Textbox *box) - { - color = box->GetText().ToNumber(true); - } - }; int *refs[6] = {&fgR, &fgG, &fgB, &bgR, &bgG, &bgB}; for(int i = 0; i < 6; i++) { ui::Textbox *colorComponent = new ui::Textbox(ui::Point(currentX, baseline), ui::Point(27, 17), String::Build(*refs[i])); currentX += 28; - colorComponent->SetActionCallback(new ColorComponentAction(*refs[i])); + colorComponent->SetActionCallback({ [colorComponent, refs, i] { + *refs[i] = colorComponent->GetText().ToNumber(true); + } }); AddComponent(colorComponent); } baseline += 18; currentX = 1; - class RenderAction : public ui::ButtonAction - { - FontEditor *v; - public: - RenderAction(FontEditor *_v): v(_v) {} - void ActionCallback(ui::Button *) - { - v->Render(); - } - }; ui::Button *render = new ui::Button(ui::Point(currentX, baseline), ui::Point(50, 17), "Render"); currentX += 51; - render->SetActionCallback(new RenderAction(this)); + render->SetActionCallback({ [this] { Render(); } }); AddComponent(render); - class SaveAction : public ui::ButtonAction - { - FontEditor *v; - public: - SaveAction(FontEditor *_v): v(_v) {} - void ActionCallback(ui::Button *) - { - v->Save(); - } - }; savedButton = new ui::Button(ui::Point(currentX, baseline), ui::Point(50, 17), "Save"); currentX += 51; savedButton->SetTogglable(true); savedButton->SetToggleState(true); - savedButton->SetActionCallback(new SaveAction(this)); + savedButton->SetActionCallback({ [this] { Save(); } }); AddComponent(savedButton); baseline += 18; @@ -480,41 +381,34 @@ FontEditor::FontEditor(ByteString _header): outputPreview->Appearance.VerticalAlign = ui::Appearance::AlignTop; AddComponent(outputPreview); - class PreviewAction : public ui::TextboxAction - { - FontEditor *v; - public: - PreviewAction(FontEditor *_v): v(_v) {} - void TextChangedCallback(ui::Textbox *box) - { - String str = box->GetText(); - size_t at = 0; - StringBuilder text; - while(at < str.size()) - { - unsigned int ch; - if(str[at] != ' ') - if(String::Split split = str.SplitNumber(ch, Format::Hex(), at)) - { - text << String::value_type(ch); - at = split.PositionAfter(); - } - else - { - text << str[at++]; - } - else - at++; - } - v->outputPreview->SetText(text.Build()); - } - }; ui::Textbox *inputPreview = new ui::Textbox(ui::Point(0, baseline), ui::Point(Size.X, (Size.Y - baseline) * 3 / 5)); inputPreview->SetMultiline(true); inputPreview->SetInputType(ui::Textbox::Multiline); inputPreview->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; inputPreview->Appearance.VerticalAlign = ui::Appearance::AlignTop; - inputPreview->SetActionCallback(new PreviewAction(this)); + auto textChangedCallback = [this, inputPreview] { + String str = inputPreview->GetText(); + size_t at = 0; + StringBuilder text; + while(at < str.size()) + { + unsigned int ch; + if(str[at] != ' ') + if(String::Split split = str.SplitNumber(ch, Format::Hex(), at)) + { + text << String::value_type(ch); + at = split.PositionAfter(); + } + else + { + text << str[at++]; + } + else + at++; + } + outputPreview->SetText(text.Build()); + }; + inputPreview->SetActionCallback({ textChangedCallback }); StringBuilder input; input << Format::Hex() << Format::Width(2); @@ -525,7 +419,7 @@ FontEditor::FontEditor(ByteString _header): input << ch << " "; } inputPreview->SetText(input.Build()); - PreviewAction(this).TextChangedCallback(inputPreview); + textChangedCallback(); AddComponent(inputPreview); } diff --git a/src/gui/game/GameController.cpp b/src/gui/game/GameController.cpp index f13c7e95a..a9aec0e51 100644 --- a/src/gui/game/GameController.cpp +++ b/src/gui/game/GameController.cpp @@ -78,94 +78,6 @@ # undef GetUserName // dammit windows #endif -class GameController::SearchCallback: public ControllerCallback -{ - GameController * cc; -public: - SearchCallback(GameController * cc_) { cc = cc_; } - - void ControllerExit() override - { - if(cc->search->GetLoadedSave()) - { - try - { - cc->HistorySnapshot(); - cc->gameModel->SetSave(cc->search->GetLoadedSave(), cc->gameView->ShiftBehaviour()); - cc->search->ReleaseLoadedSave(); - } - catch(GameModelException & ex) - { - new ErrorMessage("Cannot open save", ByteString(ex.what()).FromUtf8()); - } - } - } -}; - -class GameController::SaveOpenCallback: public ControllerCallback -{ - GameController * cc; -public: - SaveOpenCallback(GameController * cc_) { cc = cc_; } - void ControllerExit() override - { - if(cc->activePreview->GetDoOpen() && cc->activePreview->GetSaveInfo()) - { - try - { - cc->HistorySnapshot(); - cc->LoadSave(cc->activePreview->GetSaveInfo()); - } - catch(GameModelException & ex) - { - new ErrorMessage("Cannot open save", ByteString(ex.what()).FromUtf8()); - } - } - } -}; - -class GameController::OptionsCallback: public ControllerCallback -{ - GameController * cc; -public: - OptionsCallback(GameController * cc_) { cc = cc_; } - void ControllerExit() override - { - cc->gameModel->UpdateQuickOptions(); - Client::Ref().WritePrefs(); - } -}; - -class GameController::TagsCallback: public ControllerCallback -{ - GameController * cc; -public: - TagsCallback(GameController * cc_) { cc = cc_; } - void ControllerExit() override - { - cc->gameView->NotifySaveChanged(cc->gameModel); - } -}; - -class GameController::StampsCallback: public ControllerCallback -{ - GameController * cc; -public: - StampsCallback(GameController * cc_) { cc = cc_; } - void ControllerExit() override - { - SaveFile *file = cc->localBrowser->GetSave(); - if (file) - { - if (file->GetError().length()) - new ErrorMessage("Error loading stamp", file->GetError()); - else if (cc->localBrowser->GetMoveToFront()) - Client::Ref().MoveStampToFront(file->GetDisplayName().ToUtf8()); - cc->LoadStamp(file->GetGameSave()); - } - } -}; - GameController::GameController(): firstTick(true), foundSignID(-1), @@ -385,26 +297,16 @@ void GameController::Install() #if defined(MACOSX) new InformationMessage("No installation necessary", "You don't need to install The Powder Toy on OS X", false); #elif defined(WIN) || defined(LIN) - class InstallConfirmation: public ConfirmDialogueCallback { - public: - GameController * c; - InstallConfirmation(GameController * c_) { c = c_; } - void ConfirmCallback(ConfirmPrompt::DialogueResult result) override { - if (result == ConfirmPrompt::ResultOkay) - { - if(Client::Ref().DoInstallation()) - { - new InformationMessage("Success", "Installation completed", false); - } - else - { - new ErrorMessage("Could not install", "The installation did not complete due to an error"); - } - } + new ConfirmPrompt("Install The Powder Toy", "Do you wish to install The Powder Toy on this computer?\nThis allows you to open save files and saves directly from the website.", { [this] { + if (Client::Ref().DoInstallation()) + { + new InformationMessage("Success", "Installation completed", false); } - virtual ~InstallConfirmation() { } - }; - new ConfirmPrompt("Install The Powder Toy", "Do you wish to install The Powder Toy on this computer?\nThis allows you to open save files and saves directly from the website.", new InstallConfirmation(this)); + else + { + new ErrorMessage("Could not install", "The installation did not complete due to an error"); + } + } }); #else new ErrorMessage("Cannot install", "You cannot install The Powder Toy on this platform"); #endif @@ -1250,7 +1152,21 @@ void GameController::SetReplaceModeFlags(int flags) void GameController::OpenSearch(String searchText) { if(!search) - search = new SearchController(new SearchCallback(this)); + search = new SearchController([this] { + if (search->GetLoadedSave()) + { + try + { + HistorySnapshot(); + gameModel->SetSave(search->GetLoadedSave(), gameView->ShiftBehaviour()); + search->ReleaseLoadedSave(); + } + catch(GameModelException & ex) + { + new ErrorMessage("Cannot open save", ByteString(ex.what()).FromUtf8()); + } + } + }); if (searchText.length()) search->DoSearch2(searchText); ui::Engine::Ref().ShowWindow(search->GetView()); @@ -1278,19 +1194,9 @@ void GameController::OpenLocalSaveWindow(bool asCurrent) if (!asCurrent || !gameModel->GetSaveFile()) { - class LocalSaveCallback: public FileSavedCallback - { - GameController * c; - public: - LocalSaveCallback(GameController * _c): c(_c) {} - virtual ~LocalSaveCallback() {} - void FileSaved(SaveFile* file) override - { - c->gameModel->SetSaveFile(file, c->gameView->ShiftBehaviour()); - } - }; - - new LocalSaveActivity(tempSave, new LocalSaveCallback(this)); + new LocalSaveActivity(tempSave, [this](SaveFile *file) { + gameModel->SetSaveFile(file, gameView->ShiftBehaviour()); + }); } else if (gameModel->GetSaveFile()) { @@ -1326,9 +1232,25 @@ void GameController::LoadSave(SaveInfo * save) gameModel->SetSave(save, gameView->ShiftBehaviour()); } +void GameController::OpenSaveDone() +{ + if (activePreview->GetDoOpen() && activePreview->GetSaveInfo()) + { + try + { + HistorySnapshot(); + LoadSave(activePreview->GetSaveInfo()); + } + catch(GameModelException & ex) + { + new ErrorMessage("Cannot open save", ByteString(ex.what()).FromUtf8()); + } + } +} + void GameController::OpenSavePreview(int saveID, int saveDate, bool instant) { - activePreview = new PreviewController(saveID, saveDate, instant, new SaveOpenCallback(this)); + activePreview = new PreviewController(saveID, saveDate, instant, [this] { OpenSaveDone(); }); ui::Engine::Ref().ShowWindow(activePreview->GetView()); } @@ -1336,27 +1258,17 @@ void GameController::OpenSavePreview() { if(gameModel->GetSave()) { - activePreview = new PreviewController(gameModel->GetSave()->GetID(), false, new SaveOpenCallback(this)); + activePreview = new PreviewController(gameModel->GetSave()->GetID(), 0, false, [this] { OpenSaveDone(); }); ui::Engine::Ref().ShowWindow(activePreview->GetView()); } } void GameController::OpenLocalBrowse() { - class LocalSaveOpenCallback: public FileSelectedCallback - { - GameController * c; - public: - LocalSaveOpenCallback(GameController * _c): c(_c) {} - virtual ~LocalSaveOpenCallback() {}; - void FileSelected(SaveFile* file) override - { - c->HistorySnapshot(); - c->LoadSaveFile(file); - delete file; - } - }; - new FileBrowserActivity(LOCAL_SAVE_DIR PATH_SEP, new LocalSaveOpenCallback(this)); + new FileBrowserActivity(LOCAL_SAVE_DIR PATH_SEP, [this](std::unique_ptr file) { + HistorySnapshot(); + LoadSaveFile(file.get()); + }); } void GameController::OpenLogin() @@ -1398,18 +1310,9 @@ void GameController::OpenElementSearch() void GameController::OpenColourPicker() { - class ColourPickerCallback: public ColourPickedCallback - { - GameController * c; - public: - ColourPickerCallback(GameController * _c): c(_c) {} - virtual ~ColourPickerCallback() {} - void ColourPicked(ui::Colour colour) override - { - c->SetColour(colour); - } - }; - new ColourPickerActivity(gameModel->GetColourSelectorColour(), new ColourPickerCallback(this)); + new ColourPickerActivity(gameModel->GetColourSelectorColour(), [this](ui::Colour colour) { + SetColour(colour); + }); } void GameController::OpenTags() @@ -1417,7 +1320,7 @@ void GameController::OpenTags() if(gameModel->GetSave() && gameModel->GetSave()->GetID()) { delete tagsWindow; - tagsWindow = new TagsController(new TagsCallback(this), gameModel->GetSave()); + tagsWindow = new TagsController([this] { gameView->NotifySaveChanged(gameModel); }, gameModel->GetSave()); ui::Engine::Ref().ShowWindow(tagsWindow->GetView()); } else @@ -1428,13 +1331,26 @@ void GameController::OpenTags() void GameController::OpenStamps() { - localBrowser = new LocalBrowserController(new StampsCallback(this)); + localBrowser = new LocalBrowserController([this] { + SaveFile *file = localBrowser->GetSave(); + if (file) + { + if (file->GetError().length()) + new ErrorMessage("Error loading stamp", file->GetError()); + else if (localBrowser->GetMoveToFront()) + Client::Ref().MoveStampToFront(file->GetDisplayName().ToUtf8()); + LoadStamp(file->GetGameSave()); + } + }); ui::Engine::Ref().ShowWindow(localBrowser->GetView()); } void GameController::OpenOptions() { - options = new OptionsController(gameModel, new OptionsCallback(this)); + options = new OptionsController(gameModel, [this] { + gameModel->UpdateQuickOptions(); + Client::Ref().WritePrefs(); + }); ui::Engine::Ref().ShowWindow(options->GetView()); } @@ -1462,19 +1378,6 @@ void GameController::OpenRenderOptions() void GameController::OpenSaveWindow() { - class SaveUploadedCallback: public ServerSaveActivity::SaveUploadedCallback - { - GameController * c; - public: - SaveUploadedCallback(GameController * _c): c(_c) {} - virtual ~SaveUploadedCallback() {} - void SaveUploaded(SaveInfo save) override - { - save.SetVote(1); - save.SetVotesUp(1); - c->LoadSave(&save); - } - }; if(gameModel->GetUser().UserID) { Simulation * sim = gameModel->GetSimulation(); @@ -1491,13 +1394,21 @@ void GameController::OpenSaveWindow() { SaveInfo tempSave(*gameModel->GetSave()); tempSave.SetGameSave(gameSave); - new ServerSaveActivity(tempSave, new SaveUploadedCallback(this)); + new ServerSaveActivity(tempSave, [this](SaveInfo &save) { + save.SetVote(1); + save.SetVotesUp(1); + LoadSave(&save); + }); } else { SaveInfo tempSave(0, 0, 0, 0, 0, gameModel->GetUser().Username, ""); tempSave.SetGameSave(gameSave); - new ServerSaveActivity(tempSave, new SaveUploadedCallback(this)); + new ServerSaveActivity(tempSave, [this](SaveInfo &save) { + save.SetVote(1); + save.SetVotesUp(1); + LoadSave(&save); + }); } } } @@ -1509,19 +1420,6 @@ void GameController::OpenSaveWindow() void GameController::SaveAsCurrent() { - - class SaveUploadedCallback: public ServerSaveActivity::SaveUploadedCallback - { - GameController * c; - public: - SaveUploadedCallback(GameController * _c): c(_c) {} - virtual ~SaveUploadedCallback() {} - void SaveUploaded(SaveInfo save) override - { - c->LoadSave(&save); - } - }; - if(gameModel->GetSave() && gameModel->GetUser().UserID && gameModel->GetUser().Username == gameModel->GetSave()->GetUserName()) { Simulation * sim = gameModel->GetSimulation(); @@ -1538,13 +1436,13 @@ void GameController::SaveAsCurrent() { SaveInfo tempSave(*gameModel->GetSave()); tempSave.SetGameSave(gameSave); - new ServerSaveActivity(tempSave, true, new SaveUploadedCallback(this)); + new ServerSaveActivity(tempSave, true, [this](SaveInfo &save) { LoadSave(&save); }); } else { SaveInfo tempSave(0, 0, 0, 0, 0, gameModel->GetUser().Username, ""); tempSave.SetGameSave(gameSave); - new ServerSaveActivity(tempSave, true, new SaveUploadedCallback(this)); + new ServerSaveActivity(tempSave, true, [this](SaveInfo &save) { LoadSave(&save); }); } } } @@ -1673,19 +1571,6 @@ void GameController::NotifyNewNotification(Client * sender, std::pairRunUpdater(); - } - } - virtual ~UpdateConfirmation() { } - }; - class UpdateNotification : public Notification { GameController * c; @@ -1728,7 +1613,7 @@ void GameController::NotifyUpdateAvailable(Client * sender) if (info.Changelog.length()) updateMessage << "\n\nChangelog:\n" << info.Changelog; - new ConfirmPrompt("Run Updater", updateMessage.Build(), new UpdateConfirmation(c)); + new ConfirmPrompt("Run Updater", updateMessage.Build(), { [this] { c->RunUpdater(); } }); } }; diff --git a/src/gui/game/GameController.h b/src/gui/game/GameController.h index 28ebb6d35..3b62106ab 100644 --- a/src/gui/game/GameController.h +++ b/src/gui/game/GameController.h @@ -51,15 +51,10 @@ private: CommandInterface * commandInterface; std::vector debugInfo; unsigned int debugFlags; + + void OpenSaveDone(); public: bool HasDone; - class SearchCallback; - class SSaveCallback; - class TagsCallback; - class StampsCallback; - class OptionsCallback; - class SaveOpenCallback; - friend class SaveOpenCallback; GameController(); ~GameController(); GameView * GetView(); diff --git a/src/gui/game/GameView.cpp b/src/gui/game/GameView.cpp index 64e986f43..28422d004 100644 --- a/src/gui/game/GameView.cpp +++ b/src/gui/game/GameView.cpp @@ -14,6 +14,7 @@ #include "QuickOptions.h" #include "DecorationTool.h" #include "ToolButton.h" +#include "MenuButton.h" #include "Menu.h" #include "client/SaveInfo.h" @@ -41,38 +42,36 @@ # undef GetUserName // dammit windows #endif -class SplitButton; -class SplitButtonAction -{ -public: - virtual void ActionCallbackLeft(ui::Button * sender) {} - virtual void ActionCallbackRight(ui::Button * sender) {} - virtual ~SplitButtonAction() {} -}; class SplitButton : public ui::Button { -private: bool rightDown; bool leftDown; bool showSplit; int splitPosition; String toolTip2; - SplitButtonAction * splitActionCallback; + + struct SplitButtonAction + { + std::function left, right; + }; + SplitButtonAction actionCallback; + public: SplitButton(ui::Point position, ui::Point size, String buttonText, String toolTip, String toolTip2, int split) : Button(position, size, buttonText, toolTip), showSplit(true), splitPosition(split), - toolTip2(toolTip2), - splitActionCallback(NULL) + toolTip2(toolTip2) { } + virtual ~SplitButton() = default; + void SetRightToolTip(String tooltip) { toolTip2 = tooltip; } bool GetShowSplit() { return showSplit; } void SetShowSplit(bool split) { showSplit = split; } - SplitButtonAction * GetSplitActionCallback() { return splitActionCallback; } - void SetSplitActionCallback(SplitButtonAction * newAction) { splitActionCallback = newAction; } + inline SplitButtonAction const &GetSplitActionCallback() { return actionCallback; } + inline void SetSplitActionCallback(SplitButtonAction const &action) { actionCallback = action; } void SetToolTip(int x, int y) { if(x >= splitPosition || !showSplit) @@ -137,15 +136,15 @@ public: { if(!Enabled) return; - if(splitActionCallback) - splitActionCallback->ActionCallbackRight(this); + if (actionCallback.right) + actionCallback.right(); } void DoLeftAction() { if(!Enabled) return; - if(splitActionCallback) - splitActionCallback->ActionCallbackLeft(this); + if (actionCallback.left) + actionCallback.left(); } void Draw(const ui::Point& screenPos) override { @@ -156,10 +155,6 @@ public: if(showSplit) g->draw_line(splitPosition+screenPos.X, screenPos.Y+1, splitPosition+screenPos.X, screenPos.Y+Size.Y-2, 180, 180, 180, 255); } - virtual ~SplitButton() - { - delete splitActionCallback; - } }; @@ -221,19 +216,6 @@ GameView::GameView(): int currentX = 1; //Set up UI - class SearchAction : public ui::ButtonAction - { - GameView * v; - public: - SearchAction(GameView * _v) { v = _v; } - void ActionCallback(ui::Button * sender) override - { - if(v->CtrlBehaviour()) - v->c->OpenLocalBrowse(); - else - v->c->OpenSearch(""); - } - }; scrollBar = new ui::Button(ui::Point(0,YRES+21), ui::Point(XRES, 2), ""); scrollBar->Appearance.BorderHover = ui::Colour(200, 200, 200); @@ -246,222 +228,105 @@ GameView::GameView(): searchButton->SetIcon(IconOpen); currentX+=18; searchButton->SetTogglable(false); - searchButton->SetActionCallback(new SearchAction(this)); + searchButton->SetActionCallback({ [this] { + if (CtrlBehaviour()) + c->OpenLocalBrowse(); + else + c->OpenSearch(""); + } }); AddComponent(searchButton); - class ReloadAction : public ui::ButtonAction - { - GameView * v; - public: - ReloadAction(GameView * _v) { v = _v; } - void ActionCallback(ui::Button * sender) override - { - v->c->ReloadSim(); - } - void AltActionCallback(ui::Button * sender) override - { - v->c->OpenSavePreview(); - } - }; reloadButton = new ui::Button(ui::Point(currentX, Size.Y-16), ui::Point(17, 15), "", "Reload the simulation"); reloadButton->SetIcon(IconReload); reloadButton->Appearance.Margin.Left+=2; currentX+=18; - reloadButton->SetActionCallback(new ReloadAction(this)); + reloadButton->SetActionCallback({ [this] { c->ReloadSim(); }, [this] { c->OpenSavePreview(); } }); AddComponent(reloadButton); - class SaveSimulationAction : public SplitButtonAction - { - GameView * v; - public: - SaveSimulationAction(GameView * _v) { v = _v; } - void ActionCallbackRight(ui::Button * sender) override - { - if(v->CtrlBehaviour() || !Client::Ref().GetAuthUser().UserID) - v->c->OpenLocalSaveWindow(false); - else - v->c->OpenSaveWindow(); - } - void ActionCallbackLeft(ui::Button * sender) override - { - if(v->CtrlBehaviour() || !Client::Ref().GetAuthUser().UserID) - v->c->OpenLocalSaveWindow(true); - else - v->c->SaveAsCurrent(); - } - }; saveSimulationButton = new SplitButton(ui::Point(currentX, Size.Y-16), ui::Point(150, 15), "[untitled simulation]", "", "", 19); saveSimulationButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; saveSimulationButton->SetIcon(IconSave); currentX+=151; - ((SplitButton*)saveSimulationButton)->SetSplitActionCallback(new SaveSimulationAction(this)); + saveSimulationButton->SetSplitActionCallback({ + [this] { + if (CtrlBehaviour() || !Client::Ref().GetAuthUser().UserID) + c->OpenLocalSaveWindow(true); + else + c->SaveAsCurrent(); + }, + [this] { + if (CtrlBehaviour() || !Client::Ref().GetAuthUser().UserID) + c->OpenLocalSaveWindow(false); + else + c->OpenSaveWindow(); + } + }); SetSaveButtonTooltips(); AddComponent(saveSimulationButton); - class UpVoteAction : public ui::ButtonAction - { - GameView * v; - public: - UpVoteAction(GameView * _v) { v = _v; } - void ActionCallback(ui::Button * sender) override - { - v->c->Vote(1); - } - }; upVoteButton = new ui::Button(ui::Point(currentX, Size.Y-16), ui::Point(39, 15), "", "Like this save"); upVoteButton->SetIcon(IconVoteUp); upVoteButton->Appearance.Margin.Top+=2; upVoteButton->Appearance.Margin.Left+=2; currentX+=38; - upVoteButton->SetActionCallback(new UpVoteAction(this)); + upVoteButton->SetActionCallback({ [this] { c->Vote(1); } }); AddComponent(upVoteButton); - class DownVoteAction : public ui::ButtonAction - { - GameView * v; - public: - DownVoteAction(GameView * _v) { v = _v; } - void ActionCallback(ui::Button * sender) override - { - v->c->Vote(-1); - } - }; downVoteButton = new ui::Button(ui::Point(currentX, Size.Y-16), ui::Point(15, 15), "", "Dislike this save"); downVoteButton->SetIcon(IconVoteDown); downVoteButton->Appearance.Margin.Bottom+=2; downVoteButton->Appearance.Margin.Left+=2; currentX+=16; - downVoteButton->SetActionCallback(new DownVoteAction(this)); + downVoteButton->SetActionCallback({ [this] { c->Vote(-1); } }); AddComponent(downVoteButton); - class TagSimulationAction : public ui::ButtonAction - { - GameView * v; - public: - TagSimulationAction(GameView * _v) { v = _v; } - void ActionCallback(ui::Button * sender) override - { - v->c->OpenTags(); - } - }; tagSimulationButton = new ui::Button(ui::Point(currentX, Size.Y-16), ui::Point(227, 15), "[no tags set]", "Add simulation tags"); tagSimulationButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; tagSimulationButton->SetIcon(IconTag); //currentX+=252; - tagSimulationButton->SetActionCallback(new TagSimulationAction(this)); + tagSimulationButton->SetActionCallback({ [this] { c->OpenTags(); } }); AddComponent(tagSimulationButton); - class ClearSimAction : public ui::ButtonAction - { - GameView * v; - public: - ClearSimAction(GameView * _v) { v = _v; } - void ActionCallback(ui::Button * sender) override - { - v->c->ClearSim(); - } - }; clearSimButton = new ui::Button(ui::Point(Size.X-159, Size.Y-16), ui::Point(17, 15), "", "Erase everything"); clearSimButton->SetIcon(IconNew); clearSimButton->Appearance.Margin.Left+=2; - clearSimButton->SetActionCallback(new ClearSimAction(this)); + clearSimButton->SetActionCallback({ [this] { c->ClearSim(); } }); AddComponent(clearSimButton); - class LoginAction : public SplitButtonAction - { - GameView * v; - public: - LoginAction(GameView * _v) { v = _v; } - void ActionCallbackLeft(ui::Button * sender) override - { - v->c->OpenLogin(); - } - void ActionCallbackRight(ui::Button * sender) override - { - v->c->OpenProfile(); - } - }; loginButton = new SplitButton(ui::Point(Size.X-141, Size.Y-16), ui::Point(92, 15), "[sign in]", "Sign into simulation server", "Edit Profile", 19); loginButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; loginButton->SetIcon(IconLogin); - ((SplitButton*)loginButton)->SetSplitActionCallback(new LoginAction(this)); + loginButton->SetSplitActionCallback({ + [this] { c->OpenLogin(); }, + [this] { c->OpenProfile(); } + }); AddComponent(loginButton); - class SimulationOptionAction : public ui::ButtonAction - { - GameView * v; - public: - SimulationOptionAction(GameView * _v) { v = _v; } - void ActionCallback(ui::Button * sender) override - { - v->c->OpenOptions(); - } - }; simulationOptionButton = new ui::Button(ui::Point(Size.X-48, Size.Y-16), ui::Point(15, 15), "", "Simulation options"); simulationOptionButton->SetIcon(IconSimulationSettings); simulationOptionButton->Appearance.Margin.Left+=2; - simulationOptionButton->SetActionCallback(new SimulationOptionAction(this)); + simulationOptionButton->SetActionCallback({ [this] { c->OpenOptions(); } }); AddComponent(simulationOptionButton); - class DisplayModeAction : public ui::ButtonAction - { - GameView * v; - public: - DisplayModeAction(GameView * _v) { v = _v; } - void ActionCallback(ui::Button * sender) override - { - v->c->OpenRenderOptions(); - } - }; displayModeButton = new ui::Button(ui::Point(Size.X-32, Size.Y-16), ui::Point(15, 15), "", "Renderer options"); displayModeButton->SetIcon(IconRenderSettings); displayModeButton->Appearance.Margin.Left+=2; - displayModeButton->SetActionCallback(new DisplayModeAction(this)); + displayModeButton->SetActionCallback({ [this] { c->OpenRenderOptions(); } }); AddComponent(displayModeButton); - class PauseAction : public ui::ButtonAction - { - GameView * v; - public: - PauseAction(GameView * _v) { v = _v; } - void ActionCallback(ui::Button * sender) override - { - v->c->SetPaused(sender->GetToggleState()); - } - }; pauseButton = new ui::Button(ui::Point(Size.X-16, Size.Y-16), ui::Point(15, 15), "", "Pause/Resume the simulation"); //Pause pauseButton->SetIcon(IconPause); pauseButton->SetTogglable(true); - pauseButton->SetActionCallback(new PauseAction(this)); + pauseButton->SetActionCallback({ [this] { c->SetPaused(pauseButton->GetToggleState()); } }); AddComponent(pauseButton); - class ElementSearchAction : public ui::ButtonAction - { - GameView * v; - public: - ElementSearchAction(GameView * _v) { v = _v; } - void ActionCallback(ui::Button * sender) override - { - v->c->OpenElementSearch(); - } - }; ui::Button * tempButton = new ui::Button(ui::Point(WINDOWW-16, WINDOWH-32), ui::Point(15, 15), 0xE065, "Search for elements"); tempButton->Appearance.Margin = ui::Border(0, 2, 3, 2); - tempButton->SetActionCallback(new ElementSearchAction(this)); + tempButton->SetActionCallback({ [this] { c->OpenElementSearch(); } }); AddComponent(tempButton); - class ColourPickerAction : public ui::ButtonAction - { - GameView * v; - public: - ColourPickerAction(GameView * _v) { v = _v; } - void ActionCallback(ui::Button * sender) override - { - v->c->OpenColourPicker(); - } - }; colourPicker = new ui::Button(ui::Point((XRES/2)-8, YRES+1), ui::Point(16, 16), "", "Pick Colour"); - colourPicker->SetActionCallback(new ColourPickerAction(this)); + colourPicker->SetActionCallback({ [this] { c->OpenColourPicker(); } }); } GameView::~GameView() @@ -482,49 +347,6 @@ GameView::~GameView() delete placeSaveThumb; } -class GameView::MenuAction: public ui::ButtonAction -{ - GameView * v; -public: - int menuID; - bool needsClick; - MenuAction(GameView * _v, int menuID_) - { - v = _v; - menuID = menuID_; - if (menuID == SC_DECO) - needsClick = true; - else - needsClick = false; - } - void MouseEnterCallback(ui::Button * sender) override - { - // don't immediately change the active menu, the actual set is done inside GameView::OnMouseMove - // if we change it here it causes components to be removed, which causes the window to stop sending events - // and then the previous menusection button never gets sent the OnMouseLeave event and is never unhighlighted - if(!(needsClick || v->c->GetMouseClickRequired()) && !v->GetMouseDown()) - v->SetActiveMenuDelayed(menuID); - } - void ActionCallback(ui::Button * sender) override - { - if (needsClick || v->c->GetMouseClickRequired()) - v->c->SetActiveMenu(menuID); - else - MouseEnterCallback(sender); - } -}; - -class GameView::OptionAction: public ui::ButtonAction -{ - QuickOption * option; -public: - OptionAction(QuickOption * _option) { option = _option; } - void ActionCallback(ui::Button * sender) override - { - option->Perform(); - } -}; - class GameView::OptionListener: public QuickOptionListener { ui::Button * button; @@ -544,51 +366,6 @@ public: } }; -class GameView::ToolAction: public ui::ButtonAction -{ - GameView * v; -public: - Tool * tool; - ToolAction(GameView * _v, Tool * tool_) { v = _v; tool = tool_; } - void ActionCallback(ui::Button * sender_) override - { - ToolButton *sender = (ToolButton*)sender_; - if (v->ShiftBehaviour() && v->CtrlBehaviour() && !v->AltBehaviour()) - { - if (sender->GetSelectionState() == 0) - { - if (Favorite::Ref().IsFavorite(tool->GetIdentifier())) - { - Favorite::Ref().RemoveFavorite(tool->GetIdentifier()); - } - else - { - Favorite::Ref().AddFavorite(tool->GetIdentifier()); - } - v->c->RebuildFavoritesMenu(); - } - else if (sender->GetSelectionState() == 1) - { - Favorite::Ref().RemoveFavorite(tool->GetIdentifier()); - v->c->RebuildFavoritesMenu(); - } - } - else - { - if (v->CtrlBehaviour() && v->AltBehaviour() && !v->ShiftBehaviour()) - { - if (tool->GetIdentifier().Contains("_PT_")) - { - sender->SetSelectionState(3); - } - } - - if (sender->GetSelectionState() >= 0 && sender->GetSelectionState() <= 3) - v->c->SetActiveTool(sender->GetSelectionState(), tool); - } - } -}; - void GameView::NotifyQuickOptionsChanged(GameModel * sender) { for (size_t i = 0; i < quickOptionButtons.size(); i++) @@ -604,7 +381,9 @@ void GameView::NotifyQuickOptionsChanged(GameModel * sender) ui::Button * tempButton = new ui::Button(ui::Point(WINDOWW-16, currentY), ui::Point(15, 15), option->GetIcon(), option->GetDescription()); //tempButton->Appearance.Margin = ui::Border(0, 2, 3, 2); tempButton->SetTogglable(true); - tempButton->SetActionCallback(new OptionAction(option)); + tempButton->SetActionCallback({ [option] { + option->Perform(); + } }); option->AddListener(new OptionListener(tempButton)); AddComponent(tempButton); @@ -638,10 +417,25 @@ void GameView::NotifyMenuListChanged(GameModel * sender) String description = menuList[i]->GetDescription(); if (i == SC_FAVORITES && !Favorite::Ref().AnyFavorites()) description += " (Use ctrl+shift+click to toggle the favorite status of an element)"; - ui::Button * tempButton = new ui::Button(ui::Point(WINDOWW-16, currentY), ui::Point(15, 15), tempString, description); + auto *tempButton = new MenuButton(ui::Point(WINDOWW-16, currentY), ui::Point(15, 15), tempString, description); tempButton->Appearance.Margin = ui::Border(0, 2, 3, 2); + tempButton->menuID = i; + tempButton->needsClick = i == SC_DECO; tempButton->SetTogglable(true); - tempButton->SetActionCallback(new MenuAction(this, i)); + auto mouseEnterCallback = [this, tempButton] { + // don't immediately change the active menu, the actual set is done inside GameView::OnMouseMove + // if we change it here it causes components to be removed, which causes the window to stop sending events + // and then the previous menusection button never gets sent the OnMouseLeave event and is never unhighlighted + if(!(tempButton->needsClick || c->GetMouseClickRequired()) && !GetMouseDown()) + SetActiveMenuDelayed(tempButton->menuID); + }; + auto actionCallback = [this, tempButton, mouseEnterCallback] { + if (tempButton->needsClick || c->GetMouseClickRequired()) + c->SetActiveMenu(tempButton->menuID); + else + mouseEnterCallback(); + }; + tempButton->SetActionCallback({ actionCallback, nullptr, mouseEnterCallback }); currentY-=16; AddComponent(tempButton); menuButtons.push_back(tempButton); @@ -696,7 +490,7 @@ void GameView::NotifyActiveToolsChanged(GameModel * sender) decoBrush = false; for (size_t i = 0; i < toolButtons.size(); i++) { - Tool * tool = ((ToolAction*)toolButtons[i]->GetActionCallback())->tool; + auto *tool = toolButtons[i]->tool; if(sender->GetActiveTool(0) == tool) { toolButtons[i]->SetSelectionState(0); //Primary @@ -748,7 +542,7 @@ void GameView::NotifyToolListChanged(GameModel * sender) { for (size_t i = 0; i < menuButtons.size(); i++) { - if (((MenuAction*)menuButtons[i]->GetActionCallback())->menuID==sender->GetActiveMenu()) + if (menuButtons[i]->menuID==sender->GetActiveMenu()) { menuButtons[i]->SetToggleState(true); } @@ -767,21 +561,58 @@ void GameView::NotifyToolListChanged(GameModel * sender) int currentX = 0; for (size_t i = 0; i < toolList.size(); i++) { - VideoBuffer * tempTexture = toolList[i]->GetTexture(26, 14); + auto *tool = toolList[i]; + VideoBuffer * tempTexture = tool->GetTexture(26, 14); ToolButton * tempButton; //get decotool texture manually, since it changes depending on it's own color if (sender->GetActiveMenu() == SC_DECO) - tempTexture = ((DecorationTool*)toolList[i])->GetIcon(toolList[i]->GetToolID(), 26, 14); + tempTexture = ((DecorationTool*)tool)->GetIcon(tool->GetToolID(), 26, 14); if(tempTexture) - tempButton = new ToolButton(ui::Point(currentX, YRES+1), ui::Point(30, 18), "", toolList[i]->GetIdentifier(), toolList[i]->GetDescription()); + tempButton = new ToolButton(ui::Point(currentX, YRES+1), ui::Point(30, 18), "", tool->GetIdentifier(), tool->GetDescription()); else - tempButton = new ToolButton(ui::Point(currentX, YRES+1), ui::Point(30, 18), toolList[i]->GetName(), toolList[i]->GetIdentifier(), toolList[i]->GetDescription()); + tempButton = new ToolButton(ui::Point(currentX, YRES+1), ui::Point(30, 18), tool->GetName(), tool->GetIdentifier(), tool->GetDescription()); //currentY -= 17; currentX -= 31; - tempButton->SetActionCallback(new ToolAction(this, toolList[i])); + tempButton->tool = tool; + tempButton->SetActionCallback({ [this, tempButton] { + auto *tool = tempButton->tool; + if (ShiftBehaviour() && CtrlBehaviour() && !AltBehaviour()) + { + if (tempButton->GetSelectionState() == 0) + { + if (Favorite::Ref().IsFavorite(tool->GetIdentifier())) + { + Favorite::Ref().RemoveFavorite(tool->GetIdentifier()); + } + else + { + Favorite::Ref().AddFavorite(tool->GetIdentifier()); + } + c->RebuildFavoritesMenu(); + } + else if (tempButton->GetSelectionState() == 1) + { + Favorite::Ref().RemoveFavorite(tool->GetIdentifier()); + c->RebuildFavoritesMenu(); + } + } + else + { + if (CtrlBehaviour() && AltBehaviour() && !ShiftBehaviour()) + { + if (tool->GetIdentifier().Contains("_PT_")) + { + tempButton->SetSelectionState(3); + } + } + + if (tempButton->GetSelectionState() >= 0 && tempButton->GetSelectionState() <= 3) + c->SetActiveTool(tempButton->GetSelectionState(), tool); + } + } }); tempButton->Appearance.SetTexture(tempTexture); delete tempTexture; @@ -842,23 +673,8 @@ void GameView::NotifyColourSelectorVisibilityChanged(GameModel * sender) void GameView::NotifyColourPresetsChanged(GameModel * sender) { - class ColourPresetAction: public ui::ButtonAction + for (auto *button : colourPresets) { - GameView * v; - public: - int preset; - ColourPresetAction(GameView * _v, int preset) : preset(preset) { v = _v; } - void ActionCallback(ui::Button * sender_) override - { - v->c->SetActiveColourPreset(preset); - v->c->SetColour(sender_->Appearance.BackgroundInactive); - } - }; - - - for(std::vector::iterator iter = colourPresets.begin(), end = colourPresets.end(); iter != end; ++iter) - { - ToolButton * button = *iter; RemoveComponent(button); delete button; } @@ -871,7 +687,10 @@ void GameView::NotifyColourPresetsChanged(GameModel * sender) { ToolButton * tempButton = new ToolButton(ui::Point(currentX, YRES+1), ui::Point(30, 18), "", "", "Decoration Presets."); tempButton->Appearance.BackgroundInactive = *iter; - tempButton->SetActionCallback(new ColourPresetAction(this, i)); + tempButton->SetActionCallback({ [this, i, tempButton] { + c->SetActiveColourPreset(i); + c->SetColour(tempButton->Appearance.BackgroundInactive); + } }); currentX += 31; @@ -920,14 +739,14 @@ void GameView::NotifyUserChanged(GameModel * sender) if(!sender->GetUser().UserID) { loginButton->SetText("[sign in]"); - ((SplitButton*)loginButton)->SetShowSplit(false); - ((SplitButton*)loginButton)->SetRightToolTip("Sign in to simulation server"); + loginButton->SetShowSplit(false); + loginButton->SetRightToolTip("Sign in to simulation server"); } else { loginButton->SetText(sender->GetUser().Username.FromUtf8()); - ((SplitButton*)loginButton)->SetShowSplit(true); - ((SplitButton*)loginButton)->SetRightToolTip("Edit profile"); + loginButton->SetShowSplit(true); + loginButton->SetRightToolTip("Edit profile"); } // saveSimulationButtonEnabled = sender->GetUser().ID; saveSimulationButtonEnabled = true; @@ -961,9 +780,9 @@ void GameView::NotifySaveChanged(GameModel * sender) saveSimulationButton->SetText(sender->GetSave()->GetName()); if (sender->GetSave()->GetUserName() == sender->GetUser().Username) - ((SplitButton*)saveSimulationButton)->SetShowSplit(true); + saveSimulationButton->SetShowSplit(true); else - ((SplitButton*)saveSimulationButton)->SetShowSplit(false); + saveSimulationButton->SetShowSplit(false); reloadButton->Enabled = true; upVoteButton->Enabled = (sender->GetSave()->GetID() && sender->GetUser().UserID && sender->GetSave()->GetVote()==0); if(sender->GetSave()->GetID() && sender->GetUser().UserID && sender->GetSave()->GetVote()==1) @@ -1020,9 +839,9 @@ void GameView::NotifySaveChanged(GameModel * sender) else if (sender->GetSaveFile()) { if (ctrlBehaviour) - ((SplitButton*)saveSimulationButton)->SetShowSplit(true); + saveSimulationButton->SetShowSplit(true); else - ((SplitButton*)saveSimulationButton)->SetShowSplit(false); + saveSimulationButton->SetShowSplit(false); saveSimulationButton->SetText(sender->GetSaveFile()->GetDisplayName()); reloadButton->Enabled = true; upVoteButton->Enabled = false; @@ -1037,7 +856,7 @@ void GameView::NotifySaveChanged(GameModel * sender) } else { - ((SplitButton*)saveSimulationButton)->SetShowSplit(false); + saveSimulationButton->SetShowSplit(false); saveSimulationButton->SetText("[untitled simulation]"); reloadButton->Enabled = false; upVoteButton->Enabled = false; @@ -1904,48 +1723,23 @@ void GameView::DoDraw() void GameView::NotifyNotificationsChanged(GameModel * sender) { - class NotificationButtonAction : public ui::ButtonAction + for (auto *notificationComponent : notificationComponents) { - Notification * notification; - public: - NotificationButtonAction(Notification * notification) : notification(notification) { } - void ActionCallback(ui::Button * sender) override - { - notification->Action(); - //v->c->RemoveNotification(notification); - } - }; - class CloseNotificationButtonAction : public ui::ButtonAction - { - GameView * v; - Notification * notification; - public: - CloseNotificationButtonAction(GameView * v, Notification * notification) : v(v), notification(notification) { } - void ActionCallback(ui::Button * sender) override - { - v->c->RemoveNotification(notification); - } - void AltActionCallback(ui::Button * sender) override - { - v->c->RemoveNotification(notification); - } - }; - - for(std::vector::const_iterator iter = notificationComponents.begin(), end = notificationComponents.end(); iter != end; ++iter) { - ui::Component * cNotification = *iter; - RemoveComponent(cNotification); - delete cNotification; + RemoveComponent(notificationComponent); + delete notificationComponent; } notificationComponents.clear(); std::vector notifications = sender->GetNotifications(); int currentY = YRES-23; - for(std::vector::iterator iter = notifications.begin(), end = notifications.end(); iter != end; ++iter) + for (auto *notification : notifications) { - int width = (Graphics::textwidth((*iter)->Message))+8; - ui::Button * tempButton = new ui::Button(ui::Point(XRES-width-22, currentY), ui::Point(width, 15), (*iter)->Message); - tempButton->SetActionCallback(new NotificationButtonAction(*iter)); + int width = (Graphics::textwidth(notification->Message))+8; + ui::Button * tempButton = new ui::Button(ui::Point(XRES-width-22, currentY), ui::Point(width, 15), notification->Message); + tempButton->SetActionCallback({ [notification] { + notification->Action(); + } }); tempButton->Appearance.BorderInactive = style::Colour::WarningTitle; tempButton->Appearance.TextInactive = style::Colour::WarningTitle; tempButton->Appearance.BorderHover = ui::Colour(255, 175, 0); @@ -1955,7 +1749,10 @@ void GameView::NotifyNotificationsChanged(GameModel * sender) tempButton = new ui::Button(ui::Point(XRES-20, currentY), ui::Point(15, 15), 0xE02A); //tempButton->SetIcon(IconClose); - tempButton->SetActionCallback(new CloseNotificationButtonAction(this, *iter)); + auto closeNotification = [this, notification] { + c->RemoveNotification(notification); + }; + tempButton->SetActionCallback({ closeNotification, closeNotification }); tempButton->Appearance.Margin.Left -= 1; tempButton->Appearance.Margin.Top -= 1; tempButton->Appearance.BorderInactive = style::Colour::WarningTitle; @@ -2060,7 +1857,7 @@ void GameView::enableCtrlBehaviour() searchButton->SetToolTip("Open a simulation from your hard drive."); if (currentSaveType == 2) - ((SplitButton*)saveSimulationButton)->SetShowSplit(true); + saveSimulationButton->SetShowSplit(true); } } @@ -2084,7 +1881,7 @@ void GameView::disableCtrlBehaviour() searchButton->Appearance.TextInactive = searchButton->Appearance.TextHover = ui::Colour(255, 255, 255); searchButton->SetToolTip("Find & open a simulation. Hold Ctrl to load offline saves."); if (currentSaveType == 2) - ((SplitButton*)saveSimulationButton)->SetShowSplit(false); + saveSimulationButton->SetShowSplit(false); } } @@ -2118,13 +1915,13 @@ void GameView::UpdateToolStrength() void GameView::SetSaveButtonTooltips() { if (!Client::Ref().GetAuthUser().UserID) - ((SplitButton*)saveSimulationButton)->SetToolTips("Overwrite the open simulation on your hard drive.", "Save the simulation to your hard drive. Login to save online."); + saveSimulationButton->SetToolTips("Overwrite the open simulation on your hard drive.", "Save the simulation to your hard drive. Login to save online."); else if (ctrlBehaviour) - ((SplitButton*)saveSimulationButton)->SetToolTips("Overwrite the open simulation on your hard drive.", "Save the simulation to your hard drive."); - else if (((SplitButton*)saveSimulationButton)->GetShowSplit()) - ((SplitButton*)saveSimulationButton)->SetToolTips("Re-upload the current simulation", "Modify simulation properties"); + saveSimulationButton->SetToolTips("Overwrite the open simulation on your hard drive.", "Save the simulation to your hard drive."); + else if (saveSimulationButton->GetShowSplit()) + saveSimulationButton->SetToolTips("Re-upload the current simulation", "Modify simulation properties"); else - ((SplitButton*)saveSimulationButton)->SetToolTips("Re-upload the current simulation", "Upload a new simulation. Hold Ctrl to save offline."); + saveSimulationButton->SetToolTips("Re-upload the current simulation", "Upload a new simulation. Hold Ctrl to save offline."); } void GameView::OnDraw() diff --git a/src/gui/game/GameView.h b/src/gui/game/GameView.h index 080448b77..417996bd3 100644 --- a/src/gui/game/GameView.h +++ b/src/gui/game/GameView.h @@ -24,6 +24,9 @@ namespace ui class Textbox; } +class SplitButton; + +class MenuButton; class Renderer; class VideoBuffer; class ToolButton; @@ -76,21 +79,23 @@ private: Brush * activeBrush; //UI Elements std::vector quickOptionButtons; - std::vector menuButtons; + + std::vector menuButtons; + std::vector toolButtons; std::vector notificationComponents; std::deque > logEntries; ui::Button * scrollBar; ui::Button * searchButton; ui::Button * reloadButton; - ui::Button * saveSimulationButton; + SplitButton * saveSimulationButton; bool saveSimulationButtonEnabled; bool saveReuploadAllowed; ui::Button * downVoteButton; ui::Button * upVoteButton; ui::Button * tagSimulationButton; ui::Button * clearSimButton; - ui::Button * loginButton; + SplitButton * loginButton; ui::Button * simulationOptionButton; ui::Button * displayModeButton; ui::Button * pauseButton; @@ -208,9 +213,6 @@ public: void DoKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt) override; void DoKeyRelease(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt) override; - class MenuAction; - class ToolAction; - class OptionAction; class OptionListener; }; diff --git a/src/gui/game/MenuButton.h b/src/gui/game/MenuButton.h new file mode 100644 index 000000000..1c0007d80 --- /dev/null +++ b/src/gui/game/MenuButton.h @@ -0,0 +1,14 @@ +#ifndef MENUBUTTON_H_ +#define MENUBUTTON_H_ + +#include "gui/interface/Button.h" + +class MenuButton : public ui::Button +{ +public: + using ui::Button::Button; + int menuID; + bool needsClick; +}; + +#endif /* MENUBUTTON_H_ */ diff --git a/src/gui/game/PropertyTool.cpp b/src/gui/game/PropertyTool.cpp index d3ffb96e9..bf533cd92 100644 --- a/src/gui/game/PropertyTool.cpp +++ b/src/gui/game/PropertyTool.cpp @@ -32,20 +32,6 @@ public: void OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt) override; void OnTryExit(ExitMethod method) override; virtual ~PropertyWindow() {} - class OkayAction: public ui::ButtonAction - { - public: - PropertyWindow * prompt; - OkayAction(PropertyWindow * prompt_) { prompt = prompt_; } - void ActionCallback(ui::Button * sender) override - { - prompt->CloseActiveWindow(); - if(prompt->textField->GetText().length()) - prompt->SetProperty(); - prompt->SelfDestruct(); - return; - } - }; }; PropertyWindow::PropertyWindow(PropertyTool * tool_, Simulation *sim_): @@ -65,22 +51,17 @@ sim(sim_) okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; okayButton->Appearance.BorderInactive = ui::Colour(200, 200, 200); - okayButton->SetActionCallback(new OkayAction(this)); + okayButton->SetActionCallback({ [this] { + CloseActiveWindow(); + if (textField->GetText().length()) + SetProperty(); + SelfDestruct(); + } }); AddComponent(okayButton); SetOkayButton(okayButton); - class PropertyChanged: public ui::DropDownAction - { - PropertyWindow * w; - public: - PropertyChanged(PropertyWindow * w): w(w) { } - void OptionChanged(ui::DropDown * sender, std::pair option) override - { - w->FocusComponent(w->textField); - } - }; property = new ui::DropDown(ui::Point(8, 25), ui::Point(Size.X-16, 16)); - property->SetActionCallback(new PropertyChanged(this)); + property->SetActionCallback({ [this] { FocusComponent(textField); } }); AddComponent(property); for (size_t i = 0; i < properties.size(); i++) { diff --git a/src/gui/game/SignTool.cpp b/src/gui/game/SignTool.cpp index cff2b19b1..4f5b2ac06 100644 --- a/src/gui/game/SignTool.cpp +++ b/src/gui/game/SignTool.cpp @@ -50,71 +50,6 @@ public: } virtual ~SignWindow() {} void OnTryExit(ui::Window::ExitMethod method) override; - class OkayAction: public ui::ButtonAction - { - public: - SignWindow * prompt; - OkayAction(SignWindow * prompt_) { prompt = prompt_; } - void ActionCallback(ui::Button * sender) override - { - prompt->CloseActiveWindow(); - if(prompt->signID==-1 && prompt->textField->GetText().length()) - { - prompt->sim->signs.push_back(sign(prompt->textField->GetText(), prompt->signPosition.X, prompt->signPosition.Y, (sign::Justification)prompt->justification->GetOption().second)); - } - else if(prompt->signID!=-1 && prompt->textField->GetText().length()) - { - prompt->sim->signs[prompt->signID] = sign(sign(prompt->textField->GetText(), prompt->signPosition.X, prompt->signPosition.Y, (sign::Justification)prompt->justification->GetOption().second)); - } - prompt->SelfDestruct(); - } - }; - class DeleteAction: public ui::ButtonAction - { - public: - SignWindow * prompt; - DeleteAction(SignWindow * prompt_) { prompt = prompt_; } - void ActionCallback(ui::Button * sender) override - { - prompt->CloseActiveWindow(); - if(prompt->signID!=-1) - { - prompt->sim->signs.erase(prompt->sim->signs.begin()+prompt->signID); - } - prompt->SelfDestruct(); - } - }; - - class SignTextAction: public ui::TextboxAction - { - public: - SignWindow * prompt; - SignTextAction(SignWindow * prompt_) { prompt = prompt_; } - void TextChangedCallback(ui::Textbox * sender) override - { - if(prompt->signID!=-1) - { - prompt->sim->signs[prompt->signID].text = sender->GetText(); - prompt->sim->signs[prompt->signID].ju = (sign::Justification)prompt->justification->GetOption().second; - } - } - }; - - class MoveAction: public ui::ButtonAction - { - public: - SignWindow * prompt; - MoveAction(SignWindow * prompt_) { prompt = prompt_; } - void ActionCallback(ui::Button * sender) override - { - if(prompt->signID!=-1) - { - prompt->movingSign = &prompt->sim->signs[prompt->signID]; - prompt->sim->signs[prompt->signID].ju = (sign::Justification)prompt->justification->GetOption().second; - prompt->signMoving = true; - } - } - }; }; SignWindow::SignWindow(SignTool * tool_, Simulation * sim_, int signID_, ui::Point position_): @@ -136,7 +71,18 @@ SignWindow::SignWindow(SignTool * tool_, Simulation * sim_, int signID_, ui::Poi okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; okayButton->Appearance.BorderInactive = (ui::Colour(200, 200, 200)); - okayButton->SetActionCallback(new OkayAction(this)); + okayButton->SetActionCallback({ [this] { + CloseActiveWindow(); + if(signID==-1 && textField->GetText().length()) + { + sim->signs.push_back(sign(textField->GetText(), signPosition.X, signPosition.Y, (sign::Justification)justification->GetOption().second)); + } + else if(signID!=-1 && textField->GetText().length()) + { + sim->signs[signID] = sign(sign(textField->GetText(), signPosition.X, signPosition.Y, (sign::Justification)justification->GetOption().second)); + } + SelfDestruct(); + } }); AddComponent(okayButton); SetOkayButton(okayButton); @@ -158,7 +104,13 @@ SignWindow::SignWindow(SignTool * tool_, Simulation * sim_, int signID_, ui::Poi textField->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; textField->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; textField->SetLimit(45); - textField->SetActionCallback(new SignTextAction(this)); + textField->SetActionCallback({ [this] { + if (signID!=-1) + { + sim->signs[signID].text = textField->GetText(); + sim->signs[signID].ju = (sign::Justification)justification->GetOption().second; + } + } }); AddComponent(textField); FocusComponent(textField); @@ -171,13 +123,27 @@ SignWindow::SignWindow(SignTool * tool_, Simulation * sim_, int signID_, ui::Poi ui::Point position = ui::Point(justification->Position.X+justification->Size.X+3, 48); ui::Button * moveButton = new ui::Button(position, ui::Point(((Size.X-position.X-8)/2)-2, 16), "Move"); - moveButton->SetActionCallback(new MoveAction(this)); + moveButton->SetActionCallback({ [this] { + if (signID!=-1) + { + movingSign = &sim->signs[signID]; + sim->signs[signID].ju = (sign::Justification)justification->GetOption().second; + signMoving = true; + } + } }); AddComponent(moveButton); position = ui::Point(justification->Position.X+justification->Size.X+3, 48)+ui::Point(moveButton->Size.X+3, 0); ui::Button * deleteButton = new ui::Button(position, ui::Point((Size.X-position.X-8)-1, 16), "Delete"); //deleteButton->SetIcon(IconDelete); - deleteButton->SetActionCallback(new DeleteAction(this)); + deleteButton->SetActionCallback({ [this] { + CloseActiveWindow(); + if (signID!=-1) + { + sim->signs.erase(sim->signs.begin() + signID); + } + SelfDestruct(); + } }); signPosition.X = sim->signs[signID].x; signPosition.Y = sim->signs[signID].y; diff --git a/src/gui/game/ToolButton.cpp b/src/gui/game/ToolButton.cpp index 1d1d7e042..1d3610d2f 100644 --- a/src/gui/game/ToolButton.cpp +++ b/src/gui/game/ToolButton.cpp @@ -110,7 +110,3 @@ int ToolButton::GetSelectionState() { return currentSelection; } - -ToolButton::~ToolButton() { -} - diff --git a/src/gui/game/ToolButton.h b/src/gui/game/ToolButton.h index 6fb720e7c..6421d2cfd 100644 --- a/src/gui/game/ToolButton.h +++ b/src/gui/game/ToolButton.h @@ -3,6 +3,8 @@ #include "gui/interface/Button.h" +class Tool; + class ToolButton: public ui::Button { int currentSelection; @@ -15,7 +17,7 @@ public: void Draw(const ui::Point& screenPos) override; void SetSelectionState(int state); int GetSelectionState(); - virtual ~ToolButton(); + Tool *tool; }; #endif /* TOOLBUTTON_H_ */ diff --git a/src/gui/interface/AvatarButton.cpp b/src/gui/interface/AvatarButton.cpp index bb98eb527..cba5f0fb8 100644 --- a/src/gui/interface/AvatarButton.cpp +++ b/src/gui/interface/AvatarButton.cpp @@ -15,17 +15,11 @@ namespace ui { AvatarButton::AvatarButton(Point position, Point size, ByteString username): Component(position, size), name(username), - tried(false), - actionCallback(NULL) + tried(false) { } -AvatarButton::~AvatarButton() -{ - delete actionCallback; -} - void AvatarButton::OnResponse(std::unique_ptr Avatar) { avatar = std::move(Avatar); @@ -97,13 +91,8 @@ void AvatarButton::OnMouseLeave(int x, int y) void AvatarButton::DoAction() { - if(actionCallback) - actionCallback->ActionCallback(this); -} - -void AvatarButton::SetActionCallback(AvatarButtonAction * action) -{ - actionCallback = action; + if( actionCallback.action) + actionCallback.action(); } } /* namespace ui */ diff --git a/src/gui/interface/AvatarButton.h b/src/gui/interface/AvatarButton.h index 3b33a0b0b..e9a278a1c 100644 --- a/src/gui/interface/AvatarButton.h +++ b/src/gui/interface/AvatarButton.h @@ -10,25 +10,25 @@ #include "client/http/RequestMonitor.h" #include +#include namespace ui { -class AvatarButton; -class AvatarButtonAction -{ -public: - virtual void ActionCallback(ui::AvatarButton * sender) {} - virtual ~AvatarButtonAction() {} -}; - class AvatarButton : public Component, public http::RequestMonitor { std::unique_ptr avatar; ByteString name; bool tried; + + struct AvatarButtonAction + { + std::function action; + }; + AvatarButtonAction actionCallback; + public: AvatarButton(Point position, Point size, ByteString username); - virtual ~AvatarButton(); + virtual ~AvatarButton() = default; void OnMouseClick(int x, int y, unsigned int button) override; void OnMouseUnclick(int x, int y, unsigned int button) override; @@ -47,10 +47,9 @@ public: void SetUsername(ByteString username) { name = username; } ByteString GetUsername() { return name; } - void SetActionCallback(AvatarButtonAction * action); + inline void SetActionCallback(AvatarButtonAction const &action) { actionCallback = action; }; protected: bool isMouseInside, isButtonDown; - AvatarButtonAction * actionCallback; }; } #endif /* AVATARBUTTON_H_ */ diff --git a/src/gui/interface/Button.cpp b/src/gui/interface/Button.cpp index e38005c10..e9e099b0d 100644 --- a/src/gui/interface/Button.cpp +++ b/src/gui/interface/Button.cpp @@ -15,8 +15,7 @@ Button::Button(Point position, Point size, String buttonText, String toolTip): isButtonDown(false), isMouseInside(false), isTogglable(false), - toggle(false), - actionCallback(NULL) + toggle(false) { TextPosition(ButtonText); } @@ -191,8 +190,8 @@ void Button::OnMouseEnter(int x, int y) isMouseInside = true; if(!Enabled) return; - if(actionCallback) - actionCallback->MouseEnterCallback(this); + if (actionCallback.mouseEnter) + actionCallback.mouseEnter(); } void Button::OnMouseHover(int x, int y) @@ -213,27 +212,16 @@ void Button::DoAction() { if(!Enabled) return; - if(actionCallback) - actionCallback->ActionCallback(this); + if (actionCallback.action) + actionCallback.action(); } void Button::DoAltAction() { if(!Enabled) return; - if(actionCallback) - actionCallback->AltActionCallback(this); -} - -void Button::SetActionCallback(ButtonAction * action) -{ - delete actionCallback; - actionCallback = action; -} - -Button::~Button() -{ - delete actionCallback; + if (actionCallback.altAction) + actionCallback.altAction(); } } /* namespace ui */ diff --git a/src/gui/interface/Button.h b/src/gui/interface/Button.h index 69a0b8996..cc7bc1f6f 100644 --- a/src/gui/interface/Button.h +++ b/src/gui/interface/Button.h @@ -4,23 +4,21 @@ #include "common/String.h" #include "Component.h" +#include + namespace ui { -class Button; -class ButtonAction -{ -public: - virtual void ActionCallback(ui::Button * sender) {} - virtual void AltActionCallback(ui::Button * sender) {} - virtual void MouseEnterCallback(ui::Button * sender) {} - virtual ~ButtonAction() {} -}; class Button : public Component { + struct ButtonAction + { + std::function action, altAction, mouseEnter; + }; + public: Button(Point position = Point(0, 0), Point size = Point(0, 0), String buttonText = String(), String toolTip = String()); - virtual ~Button(); + virtual ~Button() = default; void OnMouseClick(int x, int y, unsigned int button) override; void OnMouseUnclick(int x, int y, unsigned int button) override; @@ -40,21 +38,20 @@ public: bool GetTogglable(); bool GetToggleState(); void SetToggleState(bool state); - void SetActionCallback(ButtonAction * action); - ButtonAction * GetActionCallback() { return actionCallback; } + inline void SetActionCallback(ButtonAction const &action) { actionCallback = action; } + // inline ButtonAction const &GetActionCallback() const { return actionCallback; } void SetText(String buttonText); void SetIcon(Icon icon); inline String GetText() { return ButtonText; } void SetToolTip(String newToolTip) { toolTip = newToolTip; } -protected: +protected: String ButtonText; String toolTip; String buttonDisplayText; bool isButtonDown, isAltButtonDown, state, isMouseInside, isTogglable, toggle; - ButtonAction * actionCallback; - + ButtonAction actionCallback; }; } #endif /* BUTTON_H_ */ diff --git a/src/gui/interface/Checkbox.cpp b/src/gui/interface/Checkbox.cpp index efb52dc6b..42e23d14e 100644 --- a/src/gui/interface/Checkbox.cpp +++ b/src/gui/interface/Checkbox.cpp @@ -11,8 +11,7 @@ Checkbox::Checkbox(ui::Point position, ui::Point size, String text, String toolT text(text), toolTip(toolTip), checked(false), - isMouseOver(false), - actionCallback(NULL) + isMouseOver(false) { } @@ -44,8 +43,8 @@ void Checkbox::OnMouseClick(int x, int y, unsigned int button) { checked = true; } - if(actionCallback) - actionCallback->ActionCallback(this); + if (actionCallback.action) + actionCallback.action(); } void Checkbox::OnMouseUp(int x, int y, unsigned int button) @@ -97,14 +96,3 @@ void Checkbox::Draw(const Point& screenPos) g->draw_icon(screenPos.X+iconPosition.X, screenPos.Y+iconPosition.Y, Appearance.icon, 200); } } - -void Checkbox::SetActionCallback(CheckboxAction * action) -{ - delete actionCallback; - actionCallback = action; -} - -Checkbox::~Checkbox() { - delete actionCallback; -} - diff --git a/src/gui/interface/Checkbox.h b/src/gui/interface/Checkbox.h index 744f8a77b..2fba1a924 100644 --- a/src/gui/interface/Checkbox.h +++ b/src/gui/interface/Checkbox.h @@ -3,23 +3,26 @@ #include "common/String.h" #include "Component.h" + +#include + namespace ui { -class Checkbox; -class CheckboxAction -{ -public: - virtual void ActionCallback(ui::Checkbox * sender) {} - virtual ~CheckboxAction() {} -}; class Checkbox: public ui::Component { String text; String toolTip; bool checked; bool isMouseOver; - CheckboxAction * actionCallback; + struct CheckboxAction + { + std::function action; + }; + CheckboxAction actionCallback; + public: Checkbox(ui::Point position, ui::Point size, String text, String toolTip); + virtual ~Checkbox() = default; + void SetText(String text); String GetText(); void SetIcon(Icon icon); @@ -29,11 +32,10 @@ public: void OnMouseLeave(int x, int y) override; void OnMouseClick(int x, int y, unsigned int button) override; void OnMouseUp(int x, int y, unsigned int button) override; - void SetActionCallback(CheckboxAction * action); - CheckboxAction * GetActionCallback() { return actionCallback; } + inline void SetActionCallback(CheckboxAction const &action) { actionCallback = action; } + inline CheckboxAction const &GetActionCallback() const { return actionCallback; } bool GetChecked() { return checked; } void SetChecked(bool checked_) { checked = checked_; } - virtual ~Checkbox(); }; } diff --git a/src/gui/interface/ContextMenu.cpp b/src/gui/interface/ContextMenu.cpp index e592f8544..5222de132 100644 --- a/src/gui/interface/ContextMenu.cpp +++ b/src/gui/interface/ContextMenu.cpp @@ -6,18 +6,6 @@ using namespace ui; -class ContextMenu::ItemSelectedAction: public ButtonAction -{ - ContextMenu * window; - int item; -public: - ItemSelectedAction(ContextMenu * window, int itemID): window(window), item(itemID) { } - void ActionCallback(ui::Button *sender) override - { - window->ActionCallbackItem(sender, item); - } -}; - ContextMenu::ContextMenu(Component * source): Window(ui::Point(0, 0), ui::Point(0, 0)), source(source), @@ -49,7 +37,10 @@ void ContextMenu::Show(ui::Point position) Button * tempButton = new Button(Point(1, currentY), Point(Size.X-2, 16), items[i].Text); tempButton->Appearance = Appearance; tempButton->Enabled = items[i].Enabled; - tempButton->SetActionCallback(new ItemSelectedAction(this, items[i].ID)); + auto item = items[i].ID; + tempButton->SetActionCallback({ [this, item, tempButton] { + ActionCallbackItem(tempButton, item); + } }); buttons.push_back(tempButton); AddComponent(tempButton); currentY += 15; diff --git a/src/gui/interface/ContextMenu.h b/src/gui/interface/ContextMenu.h index 82d19dbac..b6dbd1384 100644 --- a/src/gui/interface/ContextMenu.h +++ b/src/gui/interface/ContextMenu.h @@ -18,14 +18,15 @@ public: ContextMenuItem(String text, int id, bool enabled) : ID(id), Text(text), Enabled(enabled) {} }; -class ContextMenu: public ui::Window, public ButtonAction { +class ContextMenu: public ui::Window { std::vector buttons; std::vector items; ui::Component * source; public: ui::Appearance Appearance; - class ItemSelectedAction; ContextMenu(Component * source); + virtual ~ContextMenu() = default; + void ActionCallbackItem(ui::Button *sender, int item); void AddItem(ContextMenuItem item); void RemoveItem(int id); @@ -33,7 +34,6 @@ public: void Show(ui::Point position); void OnDraw() override; void OnMouseDown(int x, int y, unsigned button) override; - virtual ~ContextMenu() {} }; } diff --git a/src/gui/interface/DropDown.cpp b/src/gui/interface/DropDown.cpp index a29883623..5a95eb173 100644 --- a/src/gui/interface/DropDown.cpp +++ b/src/gui/interface/DropDown.cpp @@ -7,27 +7,14 @@ namespace ui { -class ItemSelectedAction; -class DropDownWindow: public ui::Window { - friend class ItemSelectedAction; +class DropDownWindow : public ui::Window +{ DropDown * dropDown; Appearance appearance; std::vector