diff --git a/.github/workflows/windows-premake-msvc.yaml b/.github/workflows/windows-premake-msvc.yaml new file mode 100644 index 0000000..f0a57d4 --- /dev/null +++ b/.github/workflows/windows-premake-msvc.yaml @@ -0,0 +1,30 @@ +name: Windows-premake-msvc +on: [push, pull_request] +jobs: + Build-Guisan: + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: install premake5 + uses: Jarod42/install-premake5@v1 + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v2 + + - name: run premake5 + run: premake5.exe vs2022 --to=solution/vs2022 + + - name: build + run: | + cd solution/vs2022 + nuget install packages.config -OutputDirectory packages + msbuild.exe /property:Configuration=Release Guisan.sln + + - name: artifact + uses: actions/upload-artifact@v4 + with: + name: guisan-msvc + path: | + solution/vs2022/bin/Release/**.* diff --git a/CMakeLists.txt b/CMakeLists.txt index a7b9910..2e20ceb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,8 +18,8 @@ INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/include") ADD_COMPILE_DEFINITIONS(GUICHAN_BUILD GUICHAN_EXTENSION_BUILD) # The Guisan core library -FILE(GLOB GUISAN_HEADER include/guisan.hpp) -FILE(GLOB GUISAN_HEADERS +SET(GUISAN_HEADER include/guisan.hpp) +SET(GUISAN_HEADERS include/guisan/actionevent.hpp include/guisan/actionlistener.hpp include/guisan/cliprectangle.hpp @@ -53,7 +53,7 @@ FILE(GLOB GUISAN_HEADERS include/guisan/rectangle.hpp include/guisan/selectionevent.hpp include/guisan/selectionlistener.hpp - include/guisan.text.hpp + include/guisan/text.hpp include/guisan/widget.hpp include/guisan/widgetlistener.hpp ) @@ -76,11 +76,11 @@ ELSE(BUILD_GUISAN_SHARED) ENDIF(BUILD_GUISAN_SHARED) ADD_LIBRARY(${PROJECT_NAME} ${GUISAN_LIBRARY_TYPE} - ${GUISAN_HEADER} - ${GUISAN_HEADERS} - ${GUISAN_WIDGET_HEADERS} + ${GUISAN_HEADER} + ${GUISAN_HEADERS} + ${GUISAN_WIDGET_HEADERS} ${GUISAN_CONTRIB_WIDGET_HEADERS} - ${GUISAN_SRC} + ${GUISAN_SRC} ${GUISAN_WIDGET_SRC}) ADD_CUSTOM_TARGET(lib DEPENDS ${PROJECT_NAME}) # Create symlink diff --git a/Guisan.sln b/Guisan.sln deleted file mode 100644 index a20750f..0000000 --- a/Guisan.sln +++ /dev/null @@ -1,44 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27703.2000 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Guisan", "Guisan.vcxproj", "{3F89CFFD-556A-404C-8E6E-9F7BF5C5525C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Demo", "demo\ff\Demo.vcxproj", "{C38D3313-382B-41C3-8CCE-AC2EBC51DCA7}" - ProjectSection(ProjectDependencies) = postProject - {3F89CFFD-556A-404C-8E6E-9F7BF5C5525C} = {3F89CFFD-556A-404C-8E6E-9F7BF5C5525C} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3F89CFFD-556A-404C-8E6E-9F7BF5C5525C}.Debug|x64.ActiveCfg = Debug|x64 - {3F89CFFD-556A-404C-8E6E-9F7BF5C5525C}.Debug|x64.Build.0 = Debug|x64 - {3F89CFFD-556A-404C-8E6E-9F7BF5C5525C}.Debug|x86.ActiveCfg = Debug|Win32 - {3F89CFFD-556A-404C-8E6E-9F7BF5C5525C}.Debug|x86.Build.0 = Debug|Win32 - {3F89CFFD-556A-404C-8E6E-9F7BF5C5525C}.Release|x64.ActiveCfg = Release|x64 - {3F89CFFD-556A-404C-8E6E-9F7BF5C5525C}.Release|x64.Build.0 = Release|x64 - {3F89CFFD-556A-404C-8E6E-9F7BF5C5525C}.Release|x86.ActiveCfg = Release|Win32 - {3F89CFFD-556A-404C-8E6E-9F7BF5C5525C}.Release|x86.Build.0 = Release|Win32 - {C38D3313-382B-41C3-8CCE-AC2EBC51DCA7}.Debug|x64.ActiveCfg = Debug|x64 - {C38D3313-382B-41C3-8CCE-AC2EBC51DCA7}.Debug|x64.Build.0 = Debug|x64 - {C38D3313-382B-41C3-8CCE-AC2EBC51DCA7}.Debug|x86.ActiveCfg = Debug|Win32 - {C38D3313-382B-41C3-8CCE-AC2EBC51DCA7}.Debug|x86.Build.0 = Debug|Win32 - {C38D3313-382B-41C3-8CCE-AC2EBC51DCA7}.Release|x64.ActiveCfg = Release|x64 - {C38D3313-382B-41C3-8CCE-AC2EBC51DCA7}.Release|x64.Build.0 = Release|x64 - {C38D3313-382B-41C3-8CCE-AC2EBC51DCA7}.Release|x86.ActiveCfg = Release|Win32 - {C38D3313-382B-41C3-8CCE-AC2EBC51DCA7}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {731FE13E-F08A-4C7F-8C8E-B68F553CF59C} - EndGlobalSection -EndGlobal diff --git a/Guisan.vcxproj b/Guisan.vcxproj deleted file mode 100644 index 49635ca..0000000 --- a/Guisan.vcxproj +++ /dev/null @@ -1,268 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {3F89CFFD-556A-404C-8E6E-9F7BF5C5525C} - Win32Proj - 10.0 - - - - StaticLibrary - true - v143 - - - StaticLibrary - false - v143 - - - StaticLibrary - true - v143 - - - StaticLibrary - false - v143 - - - - - - - - - - - - - - - - - - - - - true - - - true - - - - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level3 - ProgramDatabase - Disabled - .\include;C:\Users\Gwilherm\SDL\SDL2_ttf-2.0.14\include;C:\Users\Gwilherm\SDL\SDL2_image-2.0.3\include;C:\Users\Gwilherm\SDL\SDL2-2.0.8\include;%(AdditionalIncludeDirectories) - - - MachineX86 - true - Windows - - - SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;%(AdditionalDependencies) - - - C:\Users\Gwilherm\SDL\SDL2_ttf-2.0.14\lib\x86;C:\Users\Gwilherm\SDL\SDL2_image-2.0.3\lib\x86;C:\Users\Gwilherm\SDL\SDL2-2.0.8\lib\x86;%(AdditionalLibraryDirectories) - - - - - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDLL - Level3 - ProgramDatabase - .\include;C:\Users\Gwilherm\SDL\SDL2_ttf-2.0.14\include;C:\Users\Gwilherm\SDL\SDL2_image-2.0.3\include;C:\Users\Gwilherm\SDL\SDL2-2.0.8\include;%(AdditionalIncludeDirectories) - - - MachineX86 - true - Windows - true - true - - - SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;%(AdditionalDependencies) - - - C:\Users\Gwilherm\SDL\SDL2_ttf-2.0.14\lib\x86;C:\Users\Gwilherm\SDL\SDL2_image-2.0.3\lib\x86;C:\Users\Gwilherm\SDL\SDL2-2.0.8\lib\x86;%(AdditionalLibraryDirectories) - - - - - C:\Users\Gwilherm\SDL\SDL2_ttf-2.0.14\include;C:\Users\Gwilherm\SDL\SDL2_image-2.0.3\include;C:\Users\Gwilherm\SDL\SDL2-2.0.8\include;.\include;%(AdditionalIncludeDirectories) - - - - - ProgramDatabase - - - C:\Users\Gwilherm\SDL\SDL2_ttf-2.0.14\lib\x64;C:\Users\Gwilherm\SDL\SDL2_image-2.0.3\lib\x64;C:\Users\Gwilherm\SDL\SDL2-2.0.8\lib\x64;%(AdditionalLibraryDirectories) - SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;%(AdditionalDependencies) - - - - - C:\Users\Gwilherm\SDL\SDL2_ttf-2.0.14\include;C:\Users\Gwilherm\SDL\SDL2_image-2.0.3\include;C:\Users\Gwilherm\SDL\SDL2-2.0.8\include;.\include;%(AdditionalIncludeDirectories) - - - C:\Users\Gwilherm\SDL\SDL2_ttf-2.0.14\lib\x64;C:\Users\Gwilherm\SDL\SDL2_image-2.0.3\lib\x64;C:\Users\Gwilherm\SDL\SDL2-2.0.8\lib\x64;%(AdditionalLibraryDirectories) - SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demo/ff/src/ffdemo.cpp b/demo/ff/src/ffdemo.cpp index 6d9627e..2552ce9 100644 --- a/demo/ff/src/ffdemo.cpp +++ b/demo/ff/src/ffdemo.cpp @@ -700,7 +700,7 @@ void FFDemo::input() { Mix_PlayChannel(-1, mEscapeSound, 0); - action(gcn::ActionEvent(NULL, "escape")); + action(gcn::ActionEvent(nullptr, "escape")); } else if (mEvent.key.keysym.sym == SDLK_RETURN || mEvent.key.keysym.sym == SDLK_UP diff --git a/demo/ff/src/fflistbox.cpp b/demo/ff/src/fflistbox.cpp index 00131bb..7ed49e7 100644 --- a/demo/ff/src/fflistbox.cpp +++ b/demo/ff/src/fflistbox.cpp @@ -83,7 +83,7 @@ FFListBox::~FFListBox() void FFListBox::draw(gcn::Graphics* graphics) { - if (mListModel == NULL) + if (mListModel == nullptr) { return; } diff --git a/examples/opengl_helper.hpp b/examples/opengl_helper.hpp index de1e419..7055b4b 100644 --- a/examples/opengl_helper.hpp +++ b/examples/opengl_helper.hpp @@ -11,10 +11,10 @@ #if defined(_WIN32) # include -// Sometimes windows.h defines DELETE which causes a compilation -// error in a Guichan header. -# if defined(DELETE) -# undef DELETE +// #defines MessageBox (as MessageBoxA or MessageBoxW) +// which causes a compilation error in a Guichan header. +# if defined(MessageBox) +# undef MessageBox # endif #endif diff --git a/examples/widgets_example.hpp b/examples/widgets_example.hpp index 674b1a1..79728f7 100644 --- a/examples/widgets_example.hpp +++ b/examples/widgets_example.hpp @@ -1,4 +1,6 @@ #include + +#include #include namespace WidgetsExample @@ -28,7 +30,7 @@ namespace WidgetsExample } }; - class MainContainer + class MainContainer : public gcn::ActionListener { public: MainContainer(gcn::Gui& gui, int width, int height) @@ -54,6 +56,27 @@ namespace WidgetsExample button = std::make_unique("Button"); + button->setHotKey('b'); + button->addActionListener(this); + + imageButton = std::make_unique("guisan-logo.png"); + + imageButton->setSize(220, 90); + imageButton->setHotKey('g'); + imageButton->addActionListener(this); + + imageTextButton = std::make_unique("guisan-logo.png", "Change color"); + imageTextButton->setSize(220, 100); + imageTextButton->setAlignment(gcn::ImageTextButton::TOP); + imageTextButton->addActionListener(this); + + inputBox = std::make_unique("Change name", " Set name of label "); + + inputBox->setVisible(false); + inputBox->setMovable(true); + inputBox->setFrameSize(1); + inputBox->addActionListener(this); + textField = std::make_unique("Text field"); textBox = std::make_unique("Lorem ipsum dolor sit amet consectetur\n" @@ -78,6 +101,8 @@ namespace WidgetsExample checkBox1 = std::make_unique("Checkbox 1"); checkBox2 = std::make_unique("Checkbox 2"); + toggleButton = std::make_unique("Toggle button"); + radioButton1 = std::make_unique("Radio Button 1", "radiogroup", true); radioButton2 = std::make_unique("Radio Button 2", "radiogroup"); radioButton3 = std::make_unique("Radio Button 3", "radiogroup"); @@ -92,6 +117,14 @@ namespace WidgetsExample progress->setCaption("Loading"); progress->setWidth(100); + std::vector button_names{"0", "25", "50", "75", "100", "-1", "+1"}; + messageBox = std::make_unique("Change progression", + "Set progression value", + button_names); + messageBox->setMovable(true); + messageBox->setFrameSize(1); + messageBox->addActionListener(this); + guisanLogoImage.reset(gcn::Image::load("guisan-logo.png")); guisanLogoIcon = std::make_unique(guisanLogoImage.get()); window->add(guisanLogoIcon.get()); @@ -114,24 +147,72 @@ namespace WidgetsExample top->add(label.get(), 290, 10); top->add(icon.get(), 10, 10); top->add(button.get(), 325, 10); + top->add(imageButton.get(), 10, 290); + top->add(imageTextButton.get(), 10, 380); top->add(textField.get(), 375, 10); top->add(textBoxScrollArea.get(), 290, 50); + top->add(inputBox.get(), 270, 180); top->add(listBox.get(), 290, 200); top->add(dropDown.get(), 580, 10); top->add(checkBox1.get(), 580, 50); top->add(checkBox2.get(), 580, 70); + top->add(toggleButton.get(), 580, 90); top->add(radioButton1.get(), 580, 120); top->add(radioButton2.get(), 580, 140); top->add(radioButton3.get(), 580, 160); - top->add(slider.get(), 580, 200); + top->add(slider.get(), 580, 180); top->add(window.get(), 100, 350); top->add(nestedScrollArea.get(), 440, 350); top->add(progress.get(), 580, 200); + top->add(messageBox.get(), 480, 220); } ~MainContainer() = default; + // Implement the action function in ActionListener to receive actions + // The eventId tells us which widget called the action function. + void action(const gcn::ActionEvent& actionEvent) override { + if (actionEvent.getSource() == button.get()) + { + inputBox->setVisible(true); + top->moveToTop(inputBox.get()); + } + else if (actionEvent.getSource() == imageButton.get() + || actionEvent.getSource() == imageTextButton.get()) + { + const gcn::Color colours[] = {gcn::Color(212, 255, 150, 190), + gcn::Color(212, 0, 0, 190), + gcn::Color(0, 0, 150, 190)}; + const auto it = std::find(std::begin(colours), std::end(colours), window->getBaseColor()); + window->setBaseColor( + colours[(std::distance(std::begin(colours), it) + 1) % std::size(colours)]); + } + else if (actionEvent.getSource() == inputBox.get()) + { + inputBox->setVisible(false); + if (inputBox->getClickedButton() == 0) + { + label->setCaption(inputBox->getText()); + label->adjustSize(); + } + } + else if (actionEvent.getSource() == messageBox.get()) + { + switch (messageBox->getClickedButton()) + { + default: + case 0: progress->setValue(0); break; + case 1: progress->setValue(25); break; + case 2: progress->setValue(50); break; + case 3: progress->setValue(75); break; + case 4: progress->setValue(100); break; + case 5: progress->setValue(progress->getValue() - 1); break; + case 6: progress->setValue(progress->getValue() + 1); break; + } + } + } + private: std::unique_ptr font; // A font @@ -143,6 +224,9 @@ namespace WidgetsExample std::unique_ptr label; // A label std::unique_ptr icon; // An icon (image) std::unique_ptr button; // A button + std::unique_ptr imageButton; // An image button + std::unique_ptr imageTextButton; // An image text button + std::unique_ptr inputBox; // An input box std::unique_ptr textField; // One-line text field std::unique_ptr textBox; // Multi-line text box std::unique_ptr textBoxScrollArea; // Scroll area for the text box @@ -153,9 +237,11 @@ namespace WidgetsExample std::unique_ptr radioButton1; // Three radio buttons std::unique_ptr radioButton2; std::unique_ptr radioButton3; + std::unique_ptr toggleButton; std::unique_ptr slider; // A slider std::unique_ptr image; // An image for the icon std::unique_ptr window; + std::unique_ptr messageBox; std::unique_ptr progress; std::unique_ptr guisanLogoImage; std::unique_ptr guisanLogoIcon; diff --git a/include/guisan/focushandler.hpp b/include/guisan/focushandler.hpp index 982834f..2775383 100644 --- a/include/guisan/focushandler.hpp +++ b/include/guisan/focushandler.hpp @@ -64,6 +64,7 @@ namespace gcn { + class KeyInput; class Widget; /** @@ -164,14 +165,14 @@ namespace gcn /** * Gets the widget with focus. * - * @return The widget with focus. NULL if no widget has focus. + * @return The widget with focus. nullptr if no widget has focus. */ virtual Widget* getFocused() const; /** * Gets the widget with modal focus. * - * @return The widget with modal focus. NULL if no widget has + * @return The widget with modal focus. nullptr if no widget has * modal focus. */ virtual Widget* getModalFocused() const; @@ -179,7 +180,7 @@ namespace gcn /** * Gets the widget with modal mouse input focus. * - * @return The widget with modal mouse input focus. NULL if + * @return The widget with modal mouse input focus. nullptr if * no widget has modal mouse input focus. */ virtual Widget* getModalMouseInputFocused() const; @@ -329,6 +330,11 @@ namespace gcn */ virtual void setLastWidgetPressed(Widget* lastWidgetPressed); + /** + * + * @param keyInput + */ + void checkHotKey(const KeyInput& keyInput); protected: /** * Distributes a focus lost event. @@ -356,24 +362,24 @@ namespace gcn WidgetVector mWidgets; /** - * Holds the focused widget. NULL if no widget has focus. + * Holds the focused widget. nullptr if no widget has focus. */ Widget* mFocusedWidget = nullptr; /** - * Holds the modal focused widget. NULL if no widget has + * Holds the modal focused widget. nullptr if no widget has * modal focused. */ Widget* mModalFocusedWidget = nullptr; /** - * Holds the modal mouse input focused widget. NULL if no widget + * Holds the modal mouse input focused widget. nullptr if no widget * is being dragged. */ Widget* mModalMouseInputFocusedWidget = nullptr; /** - * Holds the dragged widget. NULL if no widget is + * Holds the dragged widget. nullptr if no widget is * being dragged. */ Widget* mDraggedWidget = nullptr; diff --git a/include/guisan/gui.hpp b/include/guisan/gui.hpp index a536e52..3c46b85 100644 --- a/include/guisan/gui.hpp +++ b/include/guisan/gui.hpp @@ -136,7 +136,7 @@ namespace gcn * Gets the top widget. The top widget is the root widget * of the GUI. * - * @return The top widget. NULL if no top widget has been set. + * @return The top widget. nullptr if no top widget has been set. * @since 0.1.0 */ virtual Widget* getTop() const; @@ -153,7 +153,7 @@ namespace gcn /** * Gets the graphics object used for drawing. * - * @return The graphics object used for drawing. NULL if no + * @return The graphics object used for drawing. nullptr if no * graphics object has been set. * @see setGraphics, OpenGLGraphics, SDLGraphics * @since 0.1.0 @@ -172,7 +172,7 @@ namespace gcn /** * Gets the input object being used for input handling. * - * @return The input object used for handling input. NULL if no + * @return The input object used for handling input. nullptr if no * input object has been set. * @see setInput, SDLInput * @since 0.1.0 diff --git a/include/guisan/keylistener.hpp b/include/guisan/keylistener.hpp index f54491c..c6307db 100644 --- a/include/guisan/keylistener.hpp +++ b/include/guisan/keylistener.hpp @@ -94,6 +94,9 @@ namespace gcn */ virtual void keyReleased(KeyEvent& keyEvent) { } + virtual void hotKeyPressed(const Key&) {} + virtual void hotKeyReleased(const Key&) {} + protected: /** * Constructor. diff --git a/include/guisan/opengl/openglsdlimageloader.hpp b/include/guisan/opengl/openglsdlimageloader.hpp index ec4f3d9..20f662a 100644 --- a/include/guisan/opengl/openglsdlimageloader.hpp +++ b/include/guisan/opengl/openglsdlimageloader.hpp @@ -79,7 +79,7 @@ namespace gcn { SDL_Surface *loadedSurface = loadSDLSurface(filename); - if (loadedSurface == NULL) + if (loadedSurface == nullptr) { throw GCN_EXCEPTION( std::string("Unable to load image file: ") + filename); @@ -88,7 +88,7 @@ namespace gcn SDL_Surface *surface = convertToStandardFormat(loadedSurface); SDL_FreeSurface(loadedSurface); - if (surface == NULL) + if (surface == nullptr) { throw GCN_EXCEPTION( std::string("Not enough memory to load: ") + filename); diff --git a/include/guisan/platform.hpp b/include/guisan/platform.hpp index 55643aa..2192b97 100644 --- a/include/guisan/platform.hpp +++ b/include/guisan/platform.hpp @@ -85,8 +85,4 @@ #define GCN_EXTENSION_DECLSPEC #endif -#ifndef NULL -#define NULL 0 -#endif - #endif // end GCN_PLATFORM_HPP diff --git a/include/guisan/sdl/sdlimage.hpp b/include/guisan/sdl/sdlimage.hpp index 2ecfcff..afc0bcb 100644 --- a/include/guisan/sdl/sdlimage.hpp +++ b/include/guisan/sdl/sdlimage.hpp @@ -83,7 +83,7 @@ namespace gcn * @param autoFree true if the surface should automatically be deleted. * @param renderer renderer object to create the texture (last parameter to avoid breaking stuff) */ - SDLImage(SDL_Surface* surface, bool autoFree, SDL_Renderer* renderer = NULL); + SDLImage(SDL_Surface* surface, bool autoFree, SDL_Renderer* renderer = nullptr); /** * Destructor. diff --git a/include/guisan/widget.hpp b/include/guisan/widget.hpp index e8e6495..c5103b1 100644 --- a/include/guisan/widget.hpp +++ b/include/guisan/widget.hpp @@ -189,7 +189,7 @@ namespace gcn /** * Gets the widget's parent container. * - * @return The widget's parent container. NULL if the widget + * @return The widget's parent container. nullptr if the widget * has no parent. * @since 0.1.0 */ @@ -199,7 +199,7 @@ namespace gcn * Gets the top widget, or top parent, of this widget. * * @return The top widget, or top parent, for this widget. - * NULL if no top widget exists + * nullptr if no top widget exists * (that is this widget doesn't have a parent). * @since 1.1.0 */ @@ -722,7 +722,7 @@ namespace gcn static void setGlobalFont(Font* font); /** - * Sets the font for the widget. If NULL is passed, the global font + * Sets the font for the widget. If nullptr is passed, the global font * will be used. * * @param font The font to set for the widget. @@ -861,12 +861,12 @@ namespace gcn * This function is used to decide which gets mouse input, * thus it can be overloaded to change that behaviour. * - * NOTE: This always returns NULL if the widget is not + * NOTE: This always returns nullptr if the widget is not * a container. * * @param x The x coordinate of the widget to get. * @param y The y coordinate of the widget to get. - * @return The widget at the specified coodinate, NULL + * @return The widget at the specified coodinate, nullptr * if no widget is found. * @since 0.6.0 */ @@ -883,7 +883,7 @@ namespace gcn * @return A list of widgets. An empty list if no widgets was found. * @since 1.1.0 */ - virtual std::list getWidgetsIn(const Rectangle& area, Widget* ignore = NULL); + virtual std::list getWidgetsIn(const Rectangle& area, Widget* ignore = nullptr); /** * Gets the mouse listeners of the widget. @@ -937,7 +937,7 @@ namespace gcn * Gets the internal focus handler used. * * @return the internalFocusHandler used. If no internal focus handler - * is used, NULL will be returned. + * is used, nullptr will be returned. * @see setInternalFocusHandler * @since 0.1.0 */ @@ -1040,6 +1040,26 @@ namespace gcn */ virtual void showPart(Rectangle rectangle); + /** + * Called when a Widget's hot key is pressed + */ + virtual void hotKeyPressed() {} + + /** + * Called when a Widget's hot key is released + */ + virtual void hotKeyReleased() {} + + /** + * Get the hot key + */ + int getHotKey() const { return mHotKey; } + + /** + * Set the hot key + */ + void setHotKey(const int key) { mHotKey = key; } + protected: /** * Distributes an action event to all action listeners @@ -1119,7 +1139,7 @@ namespace gcn * * @param id The id to find a widget by. * @return The widget with the corrosponding id, - * NULL of no widget is found. + * nullptr of no widget is found. * * @since 1.1.0 */ @@ -1196,13 +1216,13 @@ namespace gcn FocusHandler* mFocusHandler = nullptr; /** - * Holds the focus handler used by the widget. NULL + * Holds the focus handler used by the widget. nullptr * if no internal focus handler is used. */ FocusHandler* mInternalFocusHandler = nullptr; /** - * Holds the parent of the widget. NULL if the widget + * Holds the parent of the widget. nullptr if the widget * has no parent. */ Widget* mParent = nullptr; @@ -1262,6 +1282,8 @@ namespace gcn */ std::list mChildren; + int mHotKey = 0; + /** * Holds the default font used by the widget. */ diff --git a/include/guisan/widgets/button.hpp b/include/guisan/widgets/button.hpp index 3d076d7..cf7d0ae 100644 --- a/include/guisan/widgets/button.hpp +++ b/include/guisan/widgets/button.hpp @@ -147,6 +147,8 @@ namespace gcn //Inherited from Widget void draw(Graphics* graphics) override; + void hotKeyPressed() override; + void hotKeyReleased() override; // Inherited from FocusListener @@ -156,6 +158,7 @@ namespace gcn void mousePressed(MouseEvent& mouseEvent) override; void mouseReleased(MouseEvent& mouseEvent) override; + void mouseClicked(MouseEvent& mouseEvent) override; void mouseEntered(MouseEvent& mouseEvent) override; void mouseExited(MouseEvent& mouseEvent) override; void mouseDragged(MouseEvent& mouseEvent) override; @@ -194,6 +197,8 @@ namespace gcn */ bool mMousePressed = false; + bool mHotKeyPressed = false; + /** * Holds the alignment of the caption. */ diff --git a/include/guisan/widgets/container.hpp b/include/guisan/widgets/container.hpp index 6b42ca0..a366849 100644 --- a/include/guisan/widgets/container.hpp +++ b/include/guisan/widgets/container.hpp @@ -154,7 +154,7 @@ namespace gcn * Finds a widget given an id. * * @param id The id to find a widget by. - * @return A widget with a corrosponding id, NULL if no widget + * @return A widget with a corrosponding id, nullptr if no widget * is found. * @see Widget::setId */ diff --git a/include/guisan/widgets/dropdown.hpp b/include/guisan/widgets/dropdown.hpp index a781a36..add22e3 100644 --- a/include/guisan/widgets/dropdown.hpp +++ b/include/guisan/widgets/dropdown.hpp @@ -105,9 +105,9 @@ namespace gcn * @param listBox the listBox to use. * @see ListModel, ScrollArea, ListBox. */ - DropDown(ListModel *listModel = NULL, - ScrollArea *scrollArea = NULL, - ListBox *listBox = NULL); + DropDown(ListModel *listModel = nullptr, + ScrollArea *scrollArea = nullptr, + ListBox *listBox = nullptr); /** * Destructor. diff --git a/include/guisan/widgets/imagetextbutton.hpp b/include/guisan/widgets/imagetextbutton.hpp index 67481eb..96e9933 100644 --- a/include/guisan/widgets/imagetextbutton.hpp +++ b/include/guisan/widgets/imagetextbutton.hpp @@ -91,27 +91,13 @@ namespace gcn /** * Destructor. */ - ~ImageTextButton() override; + ~ImageTextButton() override = default; /** * Adjusts the size of the image button to fit the image. */ void adjustSize(); - /** - * Sets the image to display. - * - * @param image The image to display. - */ - void setImage(Image* image); - - /** - * Gets the image of the image button. - * - * @return The image of the image button. - */ - Image* getImage(); - // Inherited from Widget void draw(gcn::Graphics* graphics) override; @@ -141,14 +127,6 @@ namespace gcn }; protected: - gcn::Image* mImage = nullptr; - - /** - * True if the image has been loaded internally, false otherwise. - * An image not loaded internally should not be deleted in the - * destructor. - */ - bool mInternalImage = false; unsigned int mAlignment = ImageTextButton::BOTTOM; }; } diff --git a/include/guisan/widgets/inputbox.hpp b/include/guisan/widgets/inputbox.hpp index 99332b8..763b224 100644 --- a/include/guisan/widgets/inputbox.hpp +++ b/include/guisan/widgets/inputbox.hpp @@ -57,6 +57,7 @@ #ifndef GCN_INPUTBOX_HPP #define GCN_INPUTBOX_HPP +#include #include #include "guisan/mouselistener.hpp" @@ -73,7 +74,7 @@ namespace gcn /** * A non-movable window to get a short string from the user. */ - class GCN_CORE_DECLSPEC InputBox : public Window + class GCN_CORE_DECLSPEC InputBox : public Window, public ActionListener { public: @@ -85,7 +86,10 @@ namespace gcn * @param ok the string corresponding to the "OK" button * @param cancel the string corresponding to the "Cancel" button */ - InputBox(const std::string& caption, const std::string& message, const std::string &ok = "OK", const std::string &cancel = "Cancel"); + InputBox(const std::string& caption, + const std::string& message, + const std::string& ok = "OK", + const std::string& cancel = "Cancel"); /** * Destructor. @@ -103,7 +107,7 @@ namespace gcn /** * Get the text that was input by the user * Use in conjunction with getClickedButton() to tell an empty string from a cancel operation. - * + * * @return the text which was typed by the user */ std::string getText() const; @@ -114,24 +118,17 @@ namespace gcn */ int getClickedButton() const; - // Inherited from Widget - - void draw(Graphics* graphics) override; - - // Inherited from MouseListener + // Inherited from ActionListener - void mousePressed(MouseEvent& mouseEvent) override; - void mouseDragged(MouseEvent& mouseEvent) override; - void mouseReleased(MouseEvent& mouseEvent) override; + void action(const ActionEvent& actionEvent) override; protected: - std::string mMessage; int mClickedButton = -1; - Button *mButtonOK = nullptr; - Button *mButtonCancel = nullptr; - Label *mLabel = nullptr; - TextField *mText = nullptr; + std::unique_ptr