diff --git a/Code/Examples/1-SimpleExample/EntryPoint.cpp b/Code/Examples/1-SimpleExample/EntryPoint.cpp index 3831227..075aa87 100644 --- a/Code/Examples/1-SimpleExample/EntryPoint.cpp +++ b/Code/Examples/1-SimpleExample/EntryPoint.cpp @@ -11,7 +11,7 @@ class CustomForm { void OnCreated(maxGUI::FormConcept* form) noexcept { // Add controls inside the Form's OnCreated(). - multiline_textbox_ = form->AddControl(max::Containers::MakeRectangle(0, 0, 100, 100), "Multi-line" MAXGUI_PLATFORM_NEWLINE "test"); + multiline_textbox_ = form->AddControl>(max::Containers::MakeRectangle(0, 0, 100, 100), "Multi-line" MAXGUI_PLATFORM_NEWLINE "test"); } void OnResized(maxGUI::FormConcept* /*form*/, int new_width, int new_height) noexcept { @@ -24,7 +24,7 @@ class CustomForm { maxGUI::PostExitMessage(0); } - maxGUI::MultilineTextBox* multiline_textbox_ = nullptr; + maxGUI::MultilineTextBox<>* multiline_textbox_ = nullptr; }; diff --git a/Code/Examples/2-StylingExample/EntryPoint.cpp b/Code/Examples/2-StylingExample/EntryPoint.cpp index 6fbcc84..9a6ad09 100644 --- a/Code/Examples/2-StylingExample/EntryPoint.cpp +++ b/Code/Examples/2-StylingExample/EntryPoint.cpp @@ -26,12 +26,12 @@ class LoginForm { void OnCreated(maxGUI::FormConcept* form) noexcept { form->AddControl(max::Containers::MakeRectangle(50, 50, 300, 500), "Login"); - username_textbox_ = form->AddControl(max::Containers::MakeRectangle(50, 100, 300, 50), ""); + username_textbox_ = form->AddControl>(max::Containers::MakeRectangle(50, 100, 300, 50), ""); // The extra optional parameter at the end is a bitmask of styles. // Different controls have different optional styles available. // For example, a TextBox can have the Password style which hides the character typed by the user. - password_textbox_ = form->AddControl(max::Containers::MakeRectangle(50, 150, 300, 50), "", maxGUI::TextBoxStyles::Password); + password_textbox_ = form->AddControl>(max::Containers::MakeRectangle(50, 150, 300, 50), "", maxGUI::TextBoxStyles::Password); // A Button can have the Default style, which allows the user to press Enter at any time to press the button. form->AddControl>(max::Containers::MakeRectangle(50, 250, 100, 100), "Login", maxGUI::ButtonStyles::Default | maxGUI::ButtonStyles::Disabled); @@ -41,8 +41,8 @@ class LoginForm { maxGUI::PostExitMessage(0); } - maxGUI::TextBox* username_textbox_ = nullptr; - maxGUI::TextBox* password_textbox_ = nullptr; + maxGUI::TextBox<>* username_textbox_ = nullptr; + maxGUI::TextBox<>* password_textbox_ = nullptr; }; diff --git a/Code/Examples/3-ControlGalleryExample/EntryPoint.cpp b/Code/Examples/3-ControlGalleryExample/EntryPoint.cpp index 7f8f576..75b6f1e 100644 --- a/Code/Examples/3-ControlGalleryExample/EntryPoint.cpp +++ b/Code/Examples/3-ControlGalleryExample/EntryPoint.cpp @@ -9,8 +9,7 @@ #include -class CustomButtonBehavior -{ +class CustomButtonBehavior { public: static void OnPressed() noexcept { @@ -26,7 +25,7 @@ class ControlGalleryForm { form->AddControl>(max::Containers::MakeRectangle(25, 25, 150, 50), "Custom Button"); std::vector dropdown_options{"Option 1", "Option 2", "Option 3"}; - form->AddControl(max::Containers::MakeRectangle(25, 100, 300, 250), std::move(dropdown_options)); + form->AddControl>(max::Containers::MakeRectangle(25, 100, 300, 250), std::move(dropdown_options)); // TODO: Add the radio buttons inside the frame form->AddControl(max::Containers::MakeRectangle(25, 150, 300, 50), "Frame"); @@ -34,20 +33,20 @@ class ControlGalleryForm { form->AddControl(max::Containers::MakeRectangle(25, 225, 300, 25), "Label"); std::vector listbox_options{"Item 1", "Item 2", "Item 3"}; - form->AddControl(max::Containers::MakeRectangle(25, 275, 300, 150), std::move(listbox_options)); + form->AddControl>(max::Containers::MakeRectangle(25, 275, 300, 150), std::move(listbox_options)); - form->AddControl(max::Containers::MakeRectangle(25, 450, 300, 150), "Multiline\r\ntextbox"); + form->AddControl>(max::Containers::MakeRectangle(25, 450, 300, 150), "Multiline\r\ntextbox"); form->AddControl(max::Containers::MakeRectangle(25, 625, 300, 25), 0, 100, 50); - form->AddControl(max::Containers::MakeRectangle(25, 675, 300, 25), "Check 1"); + form->AddControl>(max::Containers::MakeRectangle(25, 675, 300, 25), "Check 1"); // When using multiple RadioButtons that belong to one group, be sure to add the FirstInGroup style to the first option. - form->AddControl(max::Containers::MakeRectangle(25, 725, 300, 25), "Option 1", maxGUI::RadioButtonStyles::FirstInGroup); + form->AddControl>(max::Containers::MakeRectangle(25, 725, 300, 25), "Option 1", maxGUI::RadioButtonStyles::FirstInGroup); - form->AddControl(max::Containers::MakeRectangle(25, 750, 300, 25), "Option 2"); + form->AddControl>(max::Containers::MakeRectangle(25, 750, 300, 25), "Option 2"); - form->AddControl(max::Containers::MakeRectangle(25, 800, 300, 25), "Textbox"); + form->AddControl>(max::Containers::MakeRectangle(25, 800, 300, 25), "Textbox"); } void OnClosed(maxGUI::FormConcept* /*form*/) noexcept { diff --git a/Code/maxGUI/Button.hpp b/Code/maxGUI/Button.hpp index ad445d9..b60e013 100644 --- a/Code/maxGUI/Button.hpp +++ b/Code/maxGUI/Button.hpp @@ -6,16 +6,16 @@ #define MAXGUI_BUTTON_HPP #include -#include #include +#include #include #include -#include #if defined(MAX_PLATFORM_WINDOWS) #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN #endif + #include #endif @@ -23,20 +23,6 @@ #include #endif -namespace maxGUI -{ - - enum class ButtonStyles : uint8_t { - None = 0, - Disabled = 1, - Default = 2, - Flat = 4, - }; - -} // namespace maxGUI - -MAX_BITMASKABLE_ENUM_CLASS(maxGUI::ButtonStyles); - namespace maxGUI { @@ -68,7 +54,7 @@ namespace maxGUI explicit Button(HWND window_handle) noexcept; #endif - ~Button() noexcept override = default; + ~Button() noexcept override; #if defined(MAX_PLATFORM_WINDOWS) static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, ButtonStyles styles = ButtonStyles::None) noexcept; @@ -81,6 +67,7 @@ namespace maxGUI #endif Behavior behavior_; + ButtonImplementation implementation_; }; diff --git a/Code/maxGUI/Button.inl b/Code/maxGUI/Button.inl index 38dd891..6ed3ebc 100644 --- a/Code/maxGUI/Button.inl +++ b/Code/maxGUI/Button.inl @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include + #if defined(MAX_PLATFORM_WINDOWS) #include #endif @@ -16,8 +18,9 @@ namespace maxGUI template< class Behavior > #endif Button< Behavior >::Button(HWND window_handle) noexcept - : ControlWithText(std::move(window_handle)) + : ControlWithText(window_handle) , behavior_() + , implementation_(window_handle) {} #endif @@ -27,27 +30,17 @@ namespace maxGUI #else template< class Behavior > #endif - HWND Button< Behavior >::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, ButtonStyles styles) noexcept { - DWORD win32_styles = WS_CHILD | WS_VISIBLE | WS_TABSTOP; - // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" - // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. - // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 -#pragma warning(push) -#pragma warning(disable: 26813) - if ((styles & ButtonStyles::Disabled) == ButtonStyles::Disabled) { - win32_styles |= WS_DISABLED; - } - if ((styles & ButtonStyles::Default) == ButtonStyles::Default) { - win32_styles |= BS_DEFPUSHBUTTON; - } - if ((styles & ButtonStyles::Flat) == ButtonStyles::Flat) { - win32_styles |= BS_FLAT; - } -#pragma warning(pop) - - Win32String win32_text = Utf8ToWin32String(std::move(text)); + Button< Behavior >::~Button() noexcept = default; +#endif - return CreateWindowEx(0, TEXT("BUTTON"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); +#if defined(MAX_PLATFORM_WINDOWS) +#if defined(MAX_CONCEPTS_SUPPORTED) + template< ButtonRequirements Behavior > +#else + template< class Behavior > +#endif + HWND Button< Behavior >::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, ButtonStyles styles) noexcept { + return ButtonImplementation::Create(std::move(parent_window_handle), std::move(rectangle), std::move(text), std::move(styles)); } #endif @@ -58,12 +51,21 @@ namespace maxGUI template< class Behavior > #endif void Button< Behavior >::OnCommand(WORD notification) noexcept { - //if constexpr (Exists::value) { - //if constexpr (Exists2::value) { - if (notification == BN_CLICKED) { - behavior_.OnPressed(); + if constexpr (HasOnGainedFocus< Behavior >::value) { + if (notification == BN_SETFOCUS ) { + behavior_.OnGainedFocus(&implementation_); + } + } + + if constexpr (HasOnLostFocus< Behavior >::value) { + if (notification == BN_KILLFOCUS ) { + behavior_.OnLostFocus(&implementation_); } - //} + } + + if (notification == BN_CLICKED) { + behavior_.OnPressed(); + } } #endif diff --git a/Code/maxGUI/ButtonImplementation.cpp b/Code/maxGUI/ButtonImplementation.cpp new file mode 100644 index 0000000..23a42fd --- /dev/null +++ b/Code/maxGUI/ButtonImplementation.cpp @@ -0,0 +1,58 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #include +#endif + +namespace maxGUI +{ + +#if defined(MAX_PLATFORM_WINDOWS) + ButtonImplementation::ButtonImplementation(HWND window_handle) noexcept + : ControlWithTextImplementation(std::move(window_handle)) + {} +#endif + + ButtonImplementation::~ButtonImplementation() noexcept = default; + +#if defined(MAX_PLATFORM_WINDOWS) + HWND ButtonImplementation::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, ButtonStyles styles) noexcept { + DWORD win32_styles = WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_NOTIFY; + // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" + // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. + // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 +#pragma warning(push) +#pragma warning(disable: 26813) + if ((styles & ButtonStyles::Disabled) == ButtonStyles::Disabled) { + win32_styles |= WS_DISABLED; + } + if ((styles & ButtonStyles::Default) == ButtonStyles::Default) { + win32_styles |= BS_DEFPUSHBUTTON; + } + if ((styles & ButtonStyles::Flat) == ButtonStyles::Flat) { + win32_styles |= BS_FLAT; + } +#pragma warning(pop) + + Win32String win32_text = Utf8ToWin32String(std::move(text)); + + //return CreateWindowEx(0, TEXT("BUTTON"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); + HWND window_handle = CreateWindowEx(0, TEXT("BUTTON"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); + + const int font_height_in_points = 10; + HDC screen_device_context = GetDC(NULL); + const int font_height_in_logical_units = -MulDiv(font_height_in_points, GetDeviceCaps(screen_device_context, LOGPIXELSY), 72); + //const int font_height_in_logical_units = -12; + HFONT font = CreateFont(font_height_in_logical_units, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE | DEFAULT_PITCH, TEXT("Segoe UI")); + + SendMessage(window_handle, WM_SETFONT, reinterpret_cast(font), TRUE); + + return window_handle; + } +#endif + +} // namespace maxGUI \ No newline at end of file diff --git a/Code/maxGUI/ButtonImplementation.hpp b/Code/maxGUI/ButtonImplementation.hpp new file mode 100644 index 0000000..14f1277 --- /dev/null +++ b/Code/maxGUI/ButtonImplementation.hpp @@ -0,0 +1,59 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXGUI_BUTTONIMPLEMENTATION_HPP +#define MAXGUI_BUTTONIMPLEMENTATION_HPP + +#include + +#include +#include +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + + #include +#endif + +#include + +namespace maxGUI +{ + + enum class ButtonStyles : uint8_t { + None = 0, + Disabled = 1, + Default = 2, + Flat = 4, + }; + +} // namespace maxGUI + +MAX_BITMASKABLE_ENUM_CLASS(maxGUI::ButtonStyles); + +namespace maxGUI +{ + + class ButtonImplementation : public ControlWithTextImplementation + { + public: + +#if defined(MAX_PLATFORM_WINDOWS) + explicit ButtonImplementation(HWND window_handle) noexcept; +#endif + + ~ButtonImplementation() noexcept; + +#if defined(MAX_PLATFORM_WINDOWS) + static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, ButtonStyles styles) noexcept; +#endif + + }; + +} // namespace maxGUI + +#endif // #ifndef MAXGUI_BUTTONIMPLEMENTATION_HPP \ No newline at end of file diff --git a/Code/maxGUI/CheckBox.cpp b/Code/maxGUI/CheckBox.cpp deleted file mode 100644 index e177ae5..0000000 --- a/Code/maxGUI/CheckBox.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2020, The maxGUI Contributors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include - -#include - -namespace maxGUI -{ - - CheckBox::CheckBox(HWND window_handle) noexcept - : ControlWithText(std::move(window_handle)) - {} - - HWND CheckBox::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, CheckBoxStyles styles) noexcept { - DWORD win32_styles = WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_CHECKBOX; - // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" - // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. - // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 - #pragma warning(push) - #pragma warning(disable: 26813) - if ((styles & CheckBoxStyles::Disabled) == CheckBoxStyles::Disabled) { - win32_styles |= WS_DISABLED; - } - if ((styles & CheckBoxStyles::Flat) == CheckBoxStyles::Flat) { - win32_styles |= BS_FLAT; - } - #pragma warning(pop) - Win32String win32_text = Utf8ToWin32String(std::move(text)); - return CreateWindowEx(0, TEXT("BUTTON"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); - } - - void CheckBox::OnPressed() noexcept { - if (IsChecked()) { - Uncheck(); - } else { - Check(); - } - } - - void CheckBox::OnCommand(WORD notification) noexcept { - if (notification == BN_CLICKED) - { - OnPressed(); - } - } - - bool CheckBox::IsChecked() const noexcept { - return SendMessage(window_handle_, BM_GETCHECK, 0, 0) == BST_CHECKED; - } - - void CheckBox::Check() noexcept { - SendMessage(window_handle_, BM_SETCHECK, BST_CHECKED, 0); - } - - void CheckBox::Uncheck() noexcept { - SendMessage(window_handle_, BM_SETCHECK, BST_UNCHECKED, 0); - } - -} // namespace maxGUI \ No newline at end of file diff --git a/Code/maxGUI/CheckBox.hpp b/Code/maxGUI/CheckBox.hpp index 7972cf3..86ec1dc 100644 --- a/Code/maxGUI/CheckBox.hpp +++ b/Code/maxGUI/CheckBox.hpp @@ -5,39 +5,30 @@ #ifndef MAXGUI_CHECKBOX_HPP #define MAXGUI_CHECKBOX_HPP +#include + #include #include +#include +#include -#if defined(MAX_PLATFORM_WINDOWS) -#include -#include -#include -#include +#if defined(MAX_PLATFORM_WINDOWS) namespace maxGUI { - enum class CheckBoxStyles : uint8_t { - None = 0, - Disabled = 1, - Flat = 2, + class DefaultCheckBoxBehavior { }; -} // namespace maxGUI - -MAX_BITMASKABLE_ENUM_CLASS(maxGUI::CheckBoxStyles); - -namespace maxGUI -{ - + template< class Behavior = DefaultCheckBoxBehavior > class CheckBox : public ControlWithText { public: explicit CheckBox(HWND window_handle) noexcept; - ~CheckBox() noexcept override = default; + ~CheckBox() noexcept override; static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, CheckBoxStyles styles = CheckBoxStyles::None) noexcept; @@ -51,10 +42,17 @@ namespace maxGUI void OnCommand(WORD notification) noexcept override; + private: + + Behavior behavior_; + CheckBoxImplementation implementation_; + }; } // namespace maxGUI #endif // #if defined(MAX_PLATFORM_WINDOWS) +#include + #endif // #ifndef MAXGUI_BUTTON_HPP \ No newline at end of file diff --git a/Code/maxGUI/CheckBox.inl b/Code/maxGUI/CheckBox.inl new file mode 100644 index 0000000..ef81278 --- /dev/null +++ b/Code/maxGUI/CheckBox.inl @@ -0,0 +1,71 @@ +// Copyright 2020, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +namespace maxGUI +{ + +#if defined(MAX_PLATFORM_WINDOWS) + + template< class Behavior > + CheckBox< Behavior >::CheckBox(HWND window_handle) noexcept + : ControlWithText(window_handle) + , behavior_() + , implementation_(window_handle) + {} + + template< class Behavior > + CheckBox< Behavior >::~CheckBox() noexcept = default; + + template< class Behavior > + HWND CheckBox< Behavior >::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, CheckBoxStyles styles) noexcept { + return CheckBoxImplementation::Create(std::move(parent_window_handle), std::move(rectangle), std::move(text), std::move(styles)); + } + + template< class Behavior > + void CheckBox< Behavior >::OnPressed() noexcept { + if (IsChecked()) { + Uncheck(); + } else { + Check(); + } + } + + template< class Behavior > + void CheckBox< Behavior >::OnCommand(WORD notification) noexcept { + if constexpr (HasOnGainedFocus< Behavior >::value) { + if (notification == BN_SETFOCUS) { + behavior_.OnGainedFocus(&implementation_); + } + } + + if constexpr (HasOnLostFocus< Behavior >::value) { + if (notification == BN_KILLFOCUS) { + behavior_.OnLostFocus(&implementation_); + } + } + + if (notification == BN_CLICKED) + { + OnPressed(); + } + } + + template< class Behavior > + bool CheckBox< Behavior >::IsChecked() const noexcept { + return implementation_.IsChecked(); + } + + template< class Behavior > + void CheckBox< Behavior >::Check() noexcept { + return implementation_.Check(); + } + + template< class Behavior > + void CheckBox< Behavior >::Uncheck() noexcept { + return implementation_.Uncheck(); + } + +#endif + +} // namespace maxGUI \ No newline at end of file diff --git a/Code/maxGUI/CheckBoxImplementation.cpp b/Code/maxGUI/CheckBoxImplementation.cpp new file mode 100644 index 0000000..b65a02d --- /dev/null +++ b/Code/maxGUI/CheckBoxImplementation.cpp @@ -0,0 +1,74 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #include +#endif + +namespace maxGUI +{ + +#if defined(MAX_PLATFORM_WINDOWS) + CheckBoxImplementation::CheckBoxImplementation(HWND window_handle) noexcept + : ControlWithTextImplementation(std::move(window_handle)) + {} +#endif + + CheckBoxImplementation::~CheckBoxImplementation() noexcept = default; + +#if defined(MAX_PLATFORM_WINDOWS) + HWND CheckBoxImplementation::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, CheckBoxStyles styles) noexcept { + DWORD win32_styles = WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_CHECKBOX | BS_NOTIFY; + // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" + // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. + // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 +#pragma warning(push) +#pragma warning(disable: 26813) + if ((styles & CheckBoxStyles::Disabled) == CheckBoxStyles::Disabled) { + win32_styles |= WS_DISABLED; + } + if ((styles & CheckBoxStyles::Flat) == CheckBoxStyles::Flat) { + win32_styles |= BS_FLAT; + } +#pragma warning(pop) + Win32String win32_text = Utf8ToWin32String(std::move(text)); + //return CreateWindowEx(0, TEXT("BUTTON"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); + HWND window_handle = CreateWindowEx(0, TEXT("BUTTON"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); + + /* + LOGFONT lf; + SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0); + HFONT font = CreateFontIndirect(&lf); + */ + + const int font_height_in_points = 10; + HDC screen_device_context = GetDC(NULL); + const int font_height_in_logical_units = -MulDiv(font_height_in_points, GetDeviceCaps(screen_device_context, LOGPIXELSY), 72); + //const int font_height_in_logical_units = -12; + HFONT font = CreateFont(font_height_in_logical_units, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE | DEFAULT_PITCH, TEXT("Segoe UI")); + + SendMessage(window_handle, WM_SETFONT, reinterpret_cast(font), TRUE); + + return window_handle; + } + + bool CheckBoxImplementation::IsChecked() const noexcept { + return SendMessage(window_handle_, BM_GETCHECK, 0, 0) == BST_CHECKED; + } + + void CheckBoxImplementation::Check() noexcept { + SendMessage(window_handle_, BM_SETCHECK, BST_CHECKED, 0); + } + + void CheckBoxImplementation::Uncheck() noexcept { + SendMessage(window_handle_, BM_SETCHECK, BST_UNCHECKED, 0); + } + +#endif + +} // namespace maxGUI \ No newline at end of file diff --git a/Code/maxGUI/CheckBoxImplementation.hpp b/Code/maxGUI/CheckBoxImplementation.hpp new file mode 100644 index 0000000..04fec73 --- /dev/null +++ b/Code/maxGUI/CheckBoxImplementation.hpp @@ -0,0 +1,61 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXGUI_CHECKBOXIMPLEMENTATION_HPP +#define MAXGUI_CHECKBOXIMPLEMENTATION_HPP + +#include + +#include +#include +#include +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + + #include +#endif + +namespace maxGUI +{ + + enum class CheckBoxStyles : uint8_t { + None = 0, + Disabled = 1, + Flat = 2, + }; + +} // namespace maxGUI + +MAX_BITMASKABLE_ENUM_CLASS(maxGUI::CheckBoxStyles); + +namespace maxGUI +{ + + class CheckBoxImplementation : public ControlWithTextImplementation + { + public: + +#if defined(MAX_PLATFORM_WINDOWS) + explicit CheckBoxImplementation(HWND window_handle) noexcept; +#endif + + ~CheckBoxImplementation() noexcept; + +#if defined(MAX_PLATFORM_WINDOWS) + static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, CheckBoxStyles styles) noexcept; +#endif + + bool IsChecked() const noexcept; + void Check() noexcept; + void Uncheck() noexcept; + + }; + +} // namespace maxGUI + +#endif // #ifndef MAXGUI_CHECKBOXIMPLEMENTATION_HPP \ No newline at end of file diff --git a/Code/maxGUI/Control.hpp b/Code/maxGUI/Control.hpp index d49763c..c2716e6 100644 --- a/Code/maxGUI/Control.hpp +++ b/Code/maxGUI/Control.hpp @@ -8,16 +8,49 @@ #include #include #include +#include #if defined(MAX_PLATFORM_WINDOWS) #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN #endif + #include #elif defined(MAX_PLATFORM_LINUX) #include #endif +namespace { + + // TODO: Use max's Exists here + template< typename T > + struct HasOnGainedFocus { + typedef char yes[1]; + typedef char no[2]; + + // If you want only non-static member functions: + //template static yes& test(typename std::enable_if, bool>::type = 0); + // If you want static and non-static member functions: + template static yes& test(typename std::enable_if, bool>::type = 0); + template static no& test(...); + static bool const value = sizeof(test::type>(0)) == sizeof(yes&); + }; + + template< typename T > + struct HasOnLostFocus { + typedef char yes[1]; + typedef char no[2]; + + // If you want only non-static member functions: + //template static yes& test(typename std::enable_if, bool>::type = 0); + // If you want static and non-static member functions: + template static yes& test(typename std::enable_if, bool>::type = 0); + template static no& test(...); + static bool const value = sizeof(test::type>(0)) == sizeof(yes&); + }; + +} // anonymous namespace + namespace maxGUI { @@ -29,6 +62,7 @@ namespace maxGUI explicit Control(HWND window_handle) noexcept; #endif + // TODO: Do we really need this to be virtual? virtual ~Control() noexcept = default; void Move(max::Containers::Rectangle rectangle) noexcept; diff --git a/Code/maxGUI/ControlImplementation.cpp b/Code/maxGUI/ControlImplementation.cpp new file mode 100644 index 0000000..fdccf5c --- /dev/null +++ b/Code/maxGUI/ControlImplementation.cpp @@ -0,0 +1,20 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +namespace maxGUI +{ + +#if defined(MAX_PLATFORM_WINDOWS) + ControlImplementation::ControlImplementation(HWND window_handle) noexcept + : window_handle_(std::move(window_handle)) + {} +#endif + + ControlImplementation::~ControlImplementation() noexcept = default; + +} // namespace maxGUI diff --git a/Code/maxGUI/ControlImplementation.hpp b/Code/maxGUI/ControlImplementation.hpp new file mode 100644 index 0000000..dcb6687 --- /dev/null +++ b/Code/maxGUI/ControlImplementation.hpp @@ -0,0 +1,41 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXGUI_CONTROLIMPLEMENTATION_HPP +#define MAXGUI_CONTROLIMPLEMENTATION_HPP + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAD_AND_MEAN + #endif + + #include +#endif + +namespace maxGUI +{ + + class ControlImplementation + { + public: + +#if defined(MAX_PLATFORM_WINDOWS) + ControlImplementation(HWND window_handle) noexcept; +#endif + + virtual ~ControlImplementation() noexcept; + + //private: + +#if defined(MAX_PLATFORM_WINDOWS) + HWND window_handle_; +#endif + + }; + +} // namespace maxGUI + +#endif // #ifndef MAXGUI_CONTROLIMPLEMENTATION_HPP diff --git a/Code/maxGUI/ControlWithList.cpp b/Code/maxGUI/ControlWithList.cpp index b4da330..e6b09ba 100644 --- a/Code/maxGUI/ControlWithList.cpp +++ b/Code/maxGUI/ControlWithList.cpp @@ -9,9 +9,11 @@ namespace maxGUI { +#if defined(MAX_PLATFORM_WINDOWS) ControlWithList::ControlWithList(HWND window_handle) noexcept : Control(std::move(window_handle)) {} +#endif void ControlWithList::OnSelectionChanged(int /*newly_selected_index*/) noexcept {} diff --git a/Code/maxGUI/ControlWithList.hpp b/Code/maxGUI/ControlWithList.hpp index ceed6e4..b3992db 100644 --- a/Code/maxGUI/ControlWithList.hpp +++ b/Code/maxGUI/ControlWithList.hpp @@ -5,13 +5,20 @@ #ifndef MAXGUI_CONTROLWITHLIST_HPP #define MAXGUI_CONTROLWITHLIST_HPP -#include #include #include -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN + +#include + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + + #include #endif -#include namespace maxGUI { @@ -19,7 +26,9 @@ namespace maxGUI class ControlWithList : public Control { public: +#if defined(MAX_PLATFORM_WINDOWS) explicit ControlWithList(HWND window_handle) noexcept; +#endif ~ControlWithList() noexcept override = default; diff --git a/Code/maxGUI/ControlWithTextImplementation.cpp b/Code/maxGUI/ControlWithTextImplementation.cpp new file mode 100644 index 0000000..0bec91f --- /dev/null +++ b/Code/maxGUI/ControlWithTextImplementation.cpp @@ -0,0 +1,45 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #include +#endif + +namespace maxGUI +{ + +#if defined(MAX_PLATFORM_WINDOWS) + ControlWithTextImplementation::ControlWithTextImplementation(HWND window_handle) noexcept + : ControlImplementation(std::move(window_handle)) + {} +#endif + + ControlWithTextImplementation::~ControlWithTextImplementation() noexcept = default; + + std::string ControlWithTextImplementation::GetText() const noexcept { +#if defined(MAX_PLATFORM_WINDOWS) + size_t length_in_chars = static_cast(SendMessage(window_handle_, WM_GETTEXTLENGTH, 0, 0)) + 1; // +1 for the null terminator + TCHAR* buffer = new wchar_t[length_in_chars]; + SendMessage(window_handle_, WM_GETTEXT, length_in_chars, reinterpret_cast(buffer)); + Win32String win32_string(std::move(buffer), length_in_chars - 1); + return Win32StringToUtf8(std::move(win32_string)); +#endif +#if defined(MAX_PLATFORM_LINUX) + return std::string(); +#endif + } + + void ControlWithTextImplementation::SetText(std::string text) noexcept { +#if defined(MAX_PLATFORM_WINDOWS) + Win32String win32_text = Utf8ToWin32String(std::move(text)); + SendMessage(window_handle_, WM_SETTEXT, 0, reinterpret_cast(win32_text.text_)); +#endif +#if defined(MAX_PLATFORM_LINUX) + (void)text; +#endif + } + +} // namespace maxGUI \ No newline at end of file diff --git a/Code/maxGUI/ControlWithTextImplementation.hpp b/Code/maxGUI/ControlWithTextImplementation.hpp new file mode 100644 index 0000000..2061eea --- /dev/null +++ b/Code/maxGUI/ControlWithTextImplementation.hpp @@ -0,0 +1,42 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXGUI_CONTROLWITHTEXTIMPLEMENTATION_HPP +#define MAXGUI_CONTROLWITHTEXTIMPLEMENTATION_HPP + +#include + +#include +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + + #include +#endif + + +namespace maxGUI +{ + + class ControlWithTextImplementation : public ControlImplementation + { + public: + +#if defined(MAX_PLATFORM_WINDOWS) + ControlWithTextImplementation(HWND window_handle) noexcept; +#endif + + ~ControlWithTextImplementation() noexcept override; + + std::string GetText() const noexcept; + void SetText(std::string text) noexcept; + + }; + +} // namespace maxGUI + +#endif // #ifndef MAXGUI_CONTROLWITHTEXTIMPLEMENTATION_HPP \ No newline at end of file diff --git a/Code/maxGUI/DropDownBox.hpp b/Code/maxGUI/DropDownBox.hpp index f6d7c72..4f4001b 100644 --- a/Code/maxGUI/DropDownBox.hpp +++ b/Code/maxGUI/DropDownBox.hpp @@ -5,38 +5,31 @@ #ifndef MAXGUI_DROPDOWNBOX_HPP #define MAXGUI_DROPDOWNBOX_HPP +#include +#include + #include +#include #include +#include +#include #if defined(MAX_PLATFORM_WINDOWS) -#include -#include -#include -#include -#include - namespace maxGUI { - enum class DropDownBoxStyles : uint8_t { - None = 0, - Disabled = 1, + class DefaultDropDownBoxBehavior { }; -} // namespace maxGUI - -MAX_BITMASKABLE_ENUM_CLASS(maxGUI::DropDownBoxStyles); - -namespace maxGUI -{ + template< class Behavior = DefaultDropDownBoxBehavior > class DropDownBox : public ControlWithList { public: explicit DropDownBox(HWND window_handle) noexcept; - ~DropDownBox() noexcept override = default; + ~DropDownBox() noexcept override; static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::vector list, DropDownBoxStyles styles = DropDownBoxStyles::None) noexcept; @@ -44,10 +37,17 @@ namespace maxGUI void OnCommand(WORD notification) noexcept override; + private: + + Behavior behavior_; + DropDownBoxImplementation implementation_; + }; } // namespace maxGUI #endif // #if defined(MAX_PLATFORM_WINDOWS) +#include + #endif // #ifndef MAXGUI_DROPDOWNBOX_HPP \ No newline at end of file diff --git a/Code/maxGUI/DropDownBox.inl b/Code/maxGUI/DropDownBox.inl new file mode 100644 index 0000000..95d85f3 --- /dev/null +++ b/Code/maxGUI/DropDownBox.inl @@ -0,0 +1,50 @@ +// Copyright 2020, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + +namespace maxGUI +{ + + template< class Behavior > + DropDownBox< Behavior >::DropDownBox(HWND window_handle) noexcept + : ControlWithList(window_handle) + , behavior_() + , implementation_(window_handle) + {} + + template< class Behavior > + DropDownBox< Behavior >::~DropDownBox() noexcept = default; + + template< class Behavior > + void DropDownBox< Behavior >::OnCommand(WORD notification) noexcept { + if constexpr (HasOnGainedFocus< Behavior >::value) { + if (notification == CBN_SETFOCUS ) { + behavior_.OnGainedFocus(&implementation_); + } + } + + if constexpr (HasOnLostFocus< Behavior >::value) { + if (notification == CBN_KILLFOCUS ) { + behavior_.OnLostFocus(&implementation_); + } + } + + if (notification == CBN_SELCHANGE) + { + int index = static_cast(SendMessage(window_handle_, CB_GETCURSEL, 0, 0)); + OnSelectionChanged(index); + } + } + + template< class Behavior > + HWND DropDownBox< Behavior >::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::vector list, DropDownBoxStyles styles) noexcept { + return DropDownBoxImplementation::Create(std::move(parent_window_handle), std::move(rectangle), std::move(list), std::move(styles)); + }; + +} // namespace maxGUI + +#endif \ No newline at end of file diff --git a/Code/maxGUI/DropDownBox.cpp b/Code/maxGUI/DropDownBoxImplementation.cpp similarity index 60% rename from Code/maxGUI/DropDownBox.cpp rename to Code/maxGUI/DropDownBoxImplementation.cpp index 1701b6d..b42a190 100644 --- a/Code/maxGUI/DropDownBox.cpp +++ b/Code/maxGUI/DropDownBoxImplementation.cpp @@ -1,50 +1,52 @@ -// Copyright 2020, The maxGUI Contributors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include - -#include - -namespace maxGUI -{ - - DropDownBox::DropDownBox(HWND window_handle) noexcept - : ControlWithList(std::move(window_handle)) - {} - - void DropDownBox::OnCommand(WORD notification) noexcept { - if (notification == CBN_SELCHANGE) - { - int index = static_cast(SendMessage(window_handle_, CB_GETCURSEL, 0, 0)); - OnSelectionChanged(index); - } - } - - HWND DropDownBox::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::vector list, DropDownBoxStyles styles) noexcept { - DWORD win32_styles = WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWN | CBS_HASSTRINGS /*| CBS_DROPDOWNLIST*/; - // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" - // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. - // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 - #pragma warning(push) - #pragma warning(disable: 26813) - if ((styles & DropDownBoxStyles::Disabled) == DropDownBoxStyles::Disabled) { - win32_styles |= WS_DISABLED; - } - #pragma warning(pop) - HWND window_handle = CreateWindowEx(0, TEXT("COMBOBOX"), TEXT(""), win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); - - for (const auto& text : list) { - Win32String win32_text = Utf8ToWin32String(text); - SendMessage(window_handle, CB_ADDSTRING, 0, reinterpret_cast(win32_text.text_)); - } - - // Default select the first item - if (list.size() != 0) { - SendMessage(window_handle, CB_SETCURSEL, 0, 0); - } - - return window_handle; - }; - -} // namespace maxGUI \ No newline at end of file +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #include +#endif + +namespace maxGUI +{ + +#if defined(MAX_PLATFORM_WINDOWS) + DropDownBoxImplementation::DropDownBoxImplementation(HWND window_handle) noexcept + : ControlWithTextImplementation(std::move(window_handle)) + {} +#endif + + DropDownBoxImplementation::~DropDownBoxImplementation() noexcept = default; + +#if defined(MAX_PLATFORM_WINDOWS) + HWND DropDownBoxImplementation::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::vector list, DropDownBoxStyles styles) noexcept { + DWORD win32_styles = WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWN | CBS_HASSTRINGS /*| CBS_DROPDOWNLIST*/; + // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" + // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. + // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 +#pragma warning(push) +#pragma warning(disable: 26813) + if ((styles & DropDownBoxStyles::Disabled) == DropDownBoxStyles::Disabled) { + win32_styles |= WS_DISABLED; + } +#pragma warning(pop) + HWND window_handle = CreateWindowEx(0, TEXT("COMBOBOX"), TEXT(""), win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); + + for (const auto& text : list) { + Win32String win32_text = Utf8ToWin32String(text); + SendMessage(window_handle, CB_ADDSTRING, 0, reinterpret_cast(win32_text.text_)); + } + + // Default select the first item + if (list.size() != 0) { + SendMessage(window_handle, CB_SETCURSEL, 0, 0); + } + + return window_handle; + } +#endif + +} // namespace maxGUI \ No newline at end of file diff --git a/Code/maxGUI/DropDownBoxImplementation.hpp b/Code/maxGUI/DropDownBoxImplementation.hpp new file mode 100644 index 0000000..7b0fa91 --- /dev/null +++ b/Code/maxGUI/DropDownBoxImplementation.hpp @@ -0,0 +1,57 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXGUI_DROPDOWNBOXIMPLEMENTATION_HPP +#define MAXGUI_DROPDOWNBOXIMPLEMENTATION_HPP + +#include +#include + +#include +#include +#include +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + + #include +#endif + +namespace maxGUI +{ + + enum class DropDownBoxStyles : uint8_t { + None = 0, + Disabled = 1, + }; + +} // namespace maxGUI + +MAX_BITMASKABLE_ENUM_CLASS(maxGUI::DropDownBoxStyles); + +namespace maxGUI +{ + + class DropDownBoxImplementation : public ControlWithTextImplementation + { + public: + +#if defined(MAX_PLATFORM_WINDOWS) + explicit DropDownBoxImplementation(HWND window_handle) noexcept; +#endif + + ~DropDownBoxImplementation() noexcept; + +#if defined(MAX_PLATFORM_WINDOWS) + static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::vector list, DropDownBoxStyles styles) noexcept; +#endif + + }; + +} // namespace maxGUI + +#endif // #ifndef MAXGUI_DROPDOWNBOXIMPLEMENTATION_HPP \ No newline at end of file diff --git a/Code/maxGUI/ListBox.hpp b/Code/maxGUI/ListBox.hpp index bf65c72..c3a3cca 100644 --- a/Code/maxGUI/ListBox.hpp +++ b/Code/maxGUI/ListBox.hpp @@ -5,41 +5,31 @@ #ifndef MAXGUI_LISTBOX_HPP #define MAXGUI_LISTBOX_HPP -#include - -#if defined(MAX_PLATFORM_WINDOWS) +#include +#include #include +#include #include #include -#include -#include -#include +#include + +#if defined(MAX_PLATFORM_WINDOWS) namespace maxGUI { - enum class ListBoxStyles : uint8_t { - None = 0, - Disabled = 1, - SingleClickMultipleSelection = 2, - KeyboardAndClickMultipleSelection = 4, + class DefaultListBoxBehavior { }; -} // namespace maxGUI - -MAX_BITMASKABLE_ENUM_CLASS(maxGUI::ListBoxStyles); - -namespace maxGUI -{ - + template< class Behavior = DefaultListBoxBehavior > class ListBox : public ControlWithList { public: explicit ListBox(HWND window_handle) noexcept; - ~ListBox() noexcept override = default; + ~ListBox() noexcept override; static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::vector list, ListBoxStyles styles = ListBoxStyles::None) noexcept; @@ -47,10 +37,15 @@ namespace maxGUI void OnCommand(WORD notification) noexcept override; + Behavior behavior_; + ListBoxImplementation implementation_; + }; } // namespace maxGUI #endif // #if defined(MAX_PLATFORM_WINDOWS) +#include + #endif // #ifndef MAXGUI_LISTBOX_HPP \ No newline at end of file diff --git a/Code/maxGUI/ListBox.inl b/Code/maxGUI/ListBox.inl new file mode 100644 index 0000000..fe27c8c --- /dev/null +++ b/Code/maxGUI/ListBox.inl @@ -0,0 +1,48 @@ +// Copyright 2020, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#if defined(MAX_PLATFORM_WINDOWS) + +namespace maxGUI +{ + + template< class Behavior > + ListBox< Behavior >::ListBox(HWND window_handle) noexcept + : ControlWithList(window_handle) + , behavior_() + , implementation_(window_handle) + {} + + template< class Behavior > + ListBox< Behavior >::~ListBox() noexcept = default; + + template< class Behavior > + HWND ListBox< Behavior >::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::vector list, ListBoxStyles styles) noexcept { + return ListBoxImplementation::Create(std::move(parent_window_handle), std::move(rectangle), std::move(list), std::move(styles)); + } + + template< class Behavior > + void ListBox< Behavior >::OnCommand(WORD notification) noexcept { + if constexpr (HasOnGainedFocus< Behavior >::value) { + if (notification == LBN_SETFOCUS ) { + behavior_.OnGainedFocus(&implementation_); + } + } + + if constexpr (HasOnLostFocus< Behavior >::value) { + if (notification == LBN_KILLFOCUS ) { + behavior_.OnLostFocus(&implementation_); + } + } + + if (notification == LBN_SELCHANGE) + { + int index = static_cast(SendMessage(window_handle_, LB_GETCURSEL, 0, 0)); + OnSelectionChanged(index); + } + } + +} // namespace maxGUI + +#endif \ No newline at end of file diff --git a/Code/maxGUI/ListBox.cpp b/Code/maxGUI/ListBoxImplementation.cpp similarity index 64% rename from Code/maxGUI/ListBox.cpp rename to Code/maxGUI/ListBoxImplementation.cpp index 606f740..369ad69 100644 --- a/Code/maxGUI/ListBox.cpp +++ b/Code/maxGUI/ListBoxImplementation.cpp @@ -1,52 +1,53 @@ -// Copyright 2020, The maxGUI Contributors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include - -#include -#include - -namespace maxGUI -{ - - ListBox::ListBox(HWND window_handle) noexcept - : ControlWithList(std::move(window_handle)) - {} - - HWND ListBox::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::vector list, ListBoxStyles styles) noexcept { - DWORD win32_styles = WS_CHILD | WS_VISIBLE | WS_TABSTOP | LBS_STANDARD; - // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" - // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. - // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 - #pragma warning(push) - #pragma warning(disable: 26813) - if ((styles & ListBoxStyles::Disabled) == ListBoxStyles::Disabled) { - win32_styles |= WS_DISABLED; - } - if ((styles & ListBoxStyles::SingleClickMultipleSelection) == ListBoxStyles::SingleClickMultipleSelection) { - win32_styles |= LBS_MULTIPLESEL; - } - if ((styles & ListBoxStyles::KeyboardAndClickMultipleSelection) == ListBoxStyles::KeyboardAndClickMultipleSelection) { - win32_styles |= LBS_EXTENDEDSEL; - } - #pragma warning(pop) - HWND window_handle = CreateWindowEx(0, TEXT("LISTBOX"), TEXT(""), win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); - - for (const auto& text : list) { - Win32String win32_text = Utf8ToWin32String(text); - SendMessage(window_handle, LB_ADDSTRING, 0, reinterpret_cast(win32_text.text_)); - } - - return window_handle; - } - - void ListBox::OnCommand(WORD notification) noexcept { - if (notification == LBN_SELCHANGE) - { - int index = static_cast(SendMessage(window_handle_, LB_GETCURSEL, 0, 0)); - OnSelectionChanged(index); - } - } - -} // namespace maxGUI \ No newline at end of file +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #include +#endif + +namespace maxGUI +{ + +#if defined(MAX_PLATFORM_WINDOWS) + ListBoxImplementation::ListBoxImplementation(HWND window_handle) noexcept + : ControlWithTextImplementation(std::move(window_handle)) + {} +#endif + + ListBoxImplementation::~ListBoxImplementation() noexcept = default; + +#if defined(MAX_PLATFORM_WINDOWS) + HWND ListBoxImplementation::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::vector list, ListBoxStyles styles) noexcept { + DWORD win32_styles = WS_CHILD | WS_VISIBLE | WS_TABSTOP | LBS_STANDARD; + // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" + // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. + // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 +#pragma warning(push) +#pragma warning(disable: 26813) + if ((styles & ListBoxStyles::Disabled) == ListBoxStyles::Disabled) { + win32_styles |= WS_DISABLED; + } + if ((styles & ListBoxStyles::SingleClickMultipleSelection) == ListBoxStyles::SingleClickMultipleSelection) { + win32_styles |= LBS_MULTIPLESEL; + } + if ((styles & ListBoxStyles::KeyboardAndClickMultipleSelection) == ListBoxStyles::KeyboardAndClickMultipleSelection) { + win32_styles |= LBS_EXTENDEDSEL; + } +#pragma warning(pop) + HWND window_handle = CreateWindowEx(0, TEXT("LISTBOX"), TEXT(""), win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); + + for (const auto& text : list) { + Win32String win32_text = Utf8ToWin32String(text); + SendMessage(window_handle, LB_ADDSTRING, 0, reinterpret_cast(win32_text.text_)); + } + + return window_handle; + } +#endif + +} // namespace maxGUI \ No newline at end of file diff --git a/Code/maxGUI/ListBoxImplementation.hpp b/Code/maxGUI/ListBoxImplementation.hpp new file mode 100644 index 0000000..d57335a --- /dev/null +++ b/Code/maxGUI/ListBoxImplementation.hpp @@ -0,0 +1,59 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXGUI_LISTBOXIMPLEMENTATION_HPP +#define MAXGUI_LISTBOXIMPLEMENTATION_HPP + +#include +#include + +#include +#include +#include +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + + #include +#endif + +namespace maxGUI +{ + + enum class ListBoxStyles : uint8_t { + None = 0, + Disabled = 1, + SingleClickMultipleSelection = 2, + KeyboardAndClickMultipleSelection = 4, + }; + +} // namespace maxGUI + +MAX_BITMASKABLE_ENUM_CLASS(maxGUI::ListBoxStyles); + +namespace maxGUI +{ + + class ListBoxImplementation : public ControlWithTextImplementation + { + public: + +#if defined(MAX_PLATFORM_WINDOWS) + explicit ListBoxImplementation(HWND window_handle) noexcept; +#endif + + ~ListBoxImplementation() noexcept; + +#if defined(MAX_PLATFORM_WINDOWS) + static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::vector list, ListBoxStyles styles) noexcept; +#endif + + }; + +} // namespace maxGUI + +#endif // #ifndef MAXGUI_LISTBOXIMPLEMENTATION_HPP \ No newline at end of file diff --git a/Code/maxGUI/MultilineTextBox.hpp b/Code/maxGUI/MultilineTextBox.hpp index e9bb168..9a2ffc5 100644 --- a/Code/maxGUI/MultilineTextBox.hpp +++ b/Code/maxGUI/MultilineTextBox.hpp @@ -5,12 +5,12 @@ #ifndef MAXGUI_MULTILINETEXTBOX_HPP #define MAXGUI_MULTILINETEXTBOX_HPP +#include + #include -#include #include #include -#include -#include +#include #if defined(MAX_PLATFORM_LINUX) #include @@ -19,18 +19,10 @@ namespace maxGUI { - enum class MultilineTextBoxStyles : uint8_t { - None = 0, - Disabled = 1, + class DefaultMultilineTextBoxBehavior { }; - -} // namespace maxGUI - -MAX_BITMASKABLE_ENUM_CLASS(maxGUI::MultilineTextBoxStyles); - -namespace maxGUI -{ + template< class Behavior = DefaultMultilineTextBoxBehavior > class MultilineTextBox : public ControlWithText { public: @@ -40,7 +32,8 @@ namespace maxGUI #elif defined(MAX_PLATFORM_LINUX) explicit MultilineTextBox(QTextEdit* widget) noexcept; #endif - ~MultilineTextBox() noexcept override = default; + + ~MultilineTextBox() noexcept; #if defined(MAX_PLATFORM_WINDOWS) static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, MultilineTextBoxStyles styles = MultilineTextBoxStyles::None) noexcept; @@ -48,8 +41,20 @@ namespace maxGUI static QTextEdit* Create(QWidget* parent_window, max::Containers::Rectangle rectangle, std::string text, MultilineTextBoxStyles styles = MultilineTextBoxStyles::None) noexcept; #endif + //protected: +#if defined(MAX_PLATFORM_WINDOWS) + void OnCommand(WORD notification) noexcept override; +#endif + + private: + + Behavior behavior_; + MultilineTextBoxImplementation implementation_; + }; } // namespace maxGUI +#include + #endif // #ifndef MAXGUI_MULTILINETEXTBOX_HPP diff --git a/Code/maxGUI/MultilineTextBox.inl b/Code/maxGUI/MultilineTextBox.inl new file mode 100644 index 0000000..a4bec18 --- /dev/null +++ b/Code/maxGUI/MultilineTextBox.inl @@ -0,0 +1,64 @@ +// Copyright 2020, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #include +#endif + +namespace maxGUI +{ + +#if defined(MAX_PLATFORM_WINDOWS) + template< class Behavior > + MultilineTextBox< Behavior >::MultilineTextBox(HWND window_handle) noexcept + : ControlWithText(window_handle) + , behavior_() + , implementation_(window_handle) + {} +#elif defined(MAX_PLATFORM_LINUX) + template< class Behavior > + MultilineTextBox< Behavior >::MultilineTextBox(QTextEdit* widget) noexcept + : ControlWithText() + , behavior_() + , implementation_() + { + (void)widget; + } +#endif + + template< class Behavior > + MultilineTextBox< Behavior >::~MultilineTextBox() noexcept = default; + +#if defined(MAX_PLATFORM_WINDOWS) + template< class Behavior > + HWND MultilineTextBox< Behavior >::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, MultilineTextBoxStyles styles) noexcept { + return MultilineTextBoxImplementation::Create(std::move(parent_window_handle), std::move(rectangle), std::move(text), std::move(styles)); + } +#elif defined(MAX_PLATFORM_LINUX) + template< class Behavior > + QTextEdit* MultilineTextBox< Behavior >::Create(QWidget* parent_window, max::Containers::Rectangle rectangle, std::string text, MultilineTextBoxStyles styles) noexcept { + return MultilineTextBoxImplementation::Create(std::move(parent_window), std::move(rectangle), std::move(text), std::move(styles)); + } +#endif + +#if defined(MAX_PLATFORM_WINDOWS) + template< class Behavior > + void MultilineTextBox< Behavior >::OnCommand(WORD notification) noexcept { + if constexpr (HasOnGainedFocus< Behavior >::value) { + if (notification == EN_SETFOCUS ) { + behavior_.OnGainedFocus(&implementation_); + } + } + + if constexpr (HasOnLostFocus< Behavior >::value) { + if (notification == EN_KILLFOCUS ) { + behavior_.OnLostFocus(&implementation_); + } + } + } +#endif + +} // namespace maxGUI diff --git a/Code/maxGUI/MultilineTextBox.cpp b/Code/maxGUI/MultilineTextBoxImplementation.cpp similarity index 67% rename from Code/maxGUI/MultilineTextBox.cpp rename to Code/maxGUI/MultilineTextBoxImplementation.cpp index 33ce0ac..6b87dde 100644 --- a/Code/maxGUI/MultilineTextBox.cpp +++ b/Code/maxGUI/MultilineTextBoxImplementation.cpp @@ -1,52 +1,48 @@ -// Copyright 2020, The maxGUI Contributors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include - -#if defined(MAX_PLATFORM_WINDOWS) - #include -#endif - -#include - -namespace maxGUI -{ - -#if defined(MAX_PLATFORM_WINDOWS) - MultilineTextBox::MultilineTextBox(HWND window_handle) noexcept - : ControlWithText(std::move(window_handle)) - {} -#elif defined(MAX_PLATFORM_LINUX) - MultilineTextBox::MultilineTextBox(QTextEdit* widget) noexcept - : ControlWithText() - { - (void)widget; - } -#endif - -#if defined(MAX_PLATFORM_WINDOWS) - HWND MultilineTextBox::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, MultilineTextBoxStyles styles) noexcept { - DWORD win32_styles = WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | ES_AUTOHSCROLL; - // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" - // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. - // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 - #pragma warning(push) - #pragma warning(disable: 26813) - if ((styles & MultilineTextBoxStyles::Disabled) == MultilineTextBoxStyles::Disabled) { - win32_styles |= WS_DISABLED; - } - #pragma warning(pop) - Win32String win32_text = Utf8ToWin32String(std::move(text)); - return CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); - } -#elif defined(MAX_PLATFORM_LINUX) - QTextEdit* MultilineTextBox::Create(QWidget* parent_window, max::Containers::Rectangle rectangle, std::string text, MultilineTextBoxStyles styles) noexcept { - QTextEdit* multiline_textbox = new QTextEdit(text.c_str(), parent_window); - multiline_textbox->setGeometry(rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height); - // TODO: Handle MultilineTextBoxStyles styles - return multiline_textbox; - } -#endif - -} // namespace maxGUI +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #include +#endif + +namespace maxGUI +{ + +#if defined(MAX_PLATFORM_WINDOWS) + MultilineTextBoxImplementation::MultilineTextBoxImplementation(HWND window_handle) noexcept + : ControlWithTextImplementation(std::move(window_handle)) + {} +#endif + + MultilineTextBoxImplementation::~MultilineTextBoxImplementation() noexcept = default; + +#if defined(MAX_PLATFORM_WINDOWS) + HWND MultilineTextBoxImplementation::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, MultilineTextBoxStyles styles) noexcept { + DWORD win32_styles = WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | ES_AUTOHSCROLL; + // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" + // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. + // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 + #pragma warning(push) + #pragma warning(disable: 26813) + if ((styles & MultilineTextBoxStyles::Disabled) == MultilineTextBoxStyles::Disabled) { + win32_styles |= WS_DISABLED; + } + #pragma warning(pop) + Win32String win32_text = Utf8ToWin32String(std::move(text)); + return CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); + } +#elif defined(MAX_PLATFORM_LINUX) + QTextEdit* MultilineTextBoxImplementation::Create(QWidget* parent_window, max::Containers::Rectangle rectangle, std::string text, MultilineTextBoxStyles styles) noexcept { + QTextEdit* multiline_textbox = new QTextEdit(text.c_str(), parent_window); + multiline_textbox->setGeometry(rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height); + // TODO: Handle MultilineTextBoxStyles styles + return multiline_textbox; + } +#endif + +} // namespace maxGUI \ No newline at end of file diff --git a/Code/maxGUI/MultilineTextBoxImplementation.hpp b/Code/maxGUI/MultilineTextBoxImplementation.hpp new file mode 100644 index 0000000..0643200 --- /dev/null +++ b/Code/maxGUI/MultilineTextBoxImplementation.hpp @@ -0,0 +1,60 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXGUI_MULTILINETEXTBOXIMPLEMENTATION_HPP +#define MAXGUI_MULTILINETEXTBOXIMPLEMENTATION_HPP + +#include + +#include +#include +#include +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + + #include +#elif defined(MAX_PLATFORM_LINUX) + #include +#endif + +namespace maxGUI +{ + + enum class MultilineTextBoxStyles : uint8_t { + None = 0, + Disabled = 1, + }; + +} // namespace maxGUI + +MAX_BITMASKABLE_ENUM_CLASS(maxGUI::MultilineTextBoxStyles); + +namespace maxGUI +{ + + class MultilineTextBoxImplementation : public ControlWithTextImplementation + { + public: + +#if defined(MAX_PLATFORM_WINDOWS) + explicit MultilineTextBoxImplementation(HWND window_handle) noexcept; +#endif + + ~MultilineTextBoxImplementation() noexcept; + +#if defined(MAX_PLATFORM_WINDOWS) + static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, MultilineTextBoxStyles styles = MultilineTextBoxStyles::None) noexcept; +#elif defined(MAX_PLATFORM_LINUX) + static QTextEdit* Create(QWidget* parent_window, max::Containers::Rectangle rectangle, std::string text, MultilineTextBoxStyles styles = MultilineTextBoxStyles::None) noexcept; +#endif + + }; + +} // namespace maxGUI + +#endif // #ifndef MAXGUI_MULTILINETEXTBOXIMPLEMENTATION_HPP \ No newline at end of file diff --git a/Code/maxGUI/RadioButton.cpp b/Code/maxGUI/RadioButton.cpp deleted file mode 100644 index 1bad710..0000000 --- a/Code/maxGUI/RadioButton.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2020, The maxGUI Contributors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include - -#include - -namespace maxGUI -{ - - RadioButton::RadioButton(HWND window_handle) noexcept - : ControlWithText(std::move(window_handle)) - {} - - HWND RadioButton::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, RadioButtonStyles style) noexcept { - DWORD win32_styles = WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON; - // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" - // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. - // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 - #pragma warning(push) - #pragma warning(disable: 26813) - if ((style & RadioButtonStyles::Disabled) == RadioButtonStyles::Disabled) { - win32_styles |= WS_DISABLED; - } - if ((style & RadioButtonStyles::FirstInGroup) == RadioButtonStyles::FirstInGroup) { - win32_styles |= WS_GROUP | WS_TABSTOP; - } - if ((style & RadioButtonStyles::Flat) == RadioButtonStyles::Flat) { - win32_styles |= BS_FLAT; - } - #pragma warning(pop) - Win32String win32_text = Utf8ToWin32String(std::move(text)); - return CreateWindowEx(0, TEXT("BUTTON"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); - } - - void RadioButton::OnPressed() noexcept - {} - - void RadioButton::OnCommand(WORD notification) noexcept { - if (notification == BN_CLICKED) { - OnPressed(); - } - } - -} // namespace maxGUI \ No newline at end of file diff --git a/Code/maxGUI/RadioButton.hpp b/Code/maxGUI/RadioButton.hpp index cc94ba8..895f222 100644 --- a/Code/maxGUI/RadioButton.hpp +++ b/Code/maxGUI/RadioButton.hpp @@ -5,41 +5,30 @@ #ifndef MAXGUI_RADIOBUTTON_HPP #define MAXGUI_RADIOBUTTON_HPP - -#include - -#if defined(MAX_PLATFORM_WINDOWS) +#include #include +#include #include #include -#include -#include +#include + +#if defined(MAX_PLATFORM_WINDOWS) namespace maxGUI { - enum class RadioButtonStyles : uint8_t { - None = 0, - Disabled = 1, - FirstInGroup = 2, - Flat = 4, + class DefaultRadioButtonBehavior { }; -} // namespace maxGUI - -MAX_BITMASKABLE_ENUM_CLASS(maxGUI::RadioButtonStyles); - -namespace maxGUI -{ - + template< class Behavior = DefaultRadioButtonBehavior > class RadioButton : public ControlWithText { public: explicit RadioButton(HWND window_handle) noexcept; - ~RadioButton() noexcept override = default; + ~RadioButton() noexcept override; static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, RadioButtonStyles styles = RadioButtonStyles::None) noexcept; @@ -49,10 +38,17 @@ namespace maxGUI void OnCommand(WORD notification) noexcept override; + private: + + Behavior behavior_; + RadioButtonImplementation implementation_; + }; } // namespace maxGUI #endif // #if defined(MAX_PLATFORM_WINDOWS) +#include + #endif // #ifndef MAXGUI_RADIOBUTTON_HPP \ No newline at end of file diff --git a/Code/maxGUI/RadioButton.inl b/Code/maxGUI/RadioButton.inl new file mode 100644 index 0000000..52b0e1e --- /dev/null +++ b/Code/maxGUI/RadioButton.inl @@ -0,0 +1,52 @@ +// Copyright 2020, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#if defined(MAX_PLATFORM_WINDOWS) + +#include + +namespace maxGUI +{ + + template< class Behavior > + RadioButton< Behavior >::RadioButton(HWND window_handle) noexcept + : ControlWithText(window_handle) + , behavior_() + , implementation_(window_handle) + {} + + template< class Behavior > + RadioButton< Behavior >::~RadioButton() noexcept = default; + + template< class Behavior > + HWND RadioButton< Behavior >::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, RadioButtonStyles style) noexcept { + return RadioButtonImplementation::Create(std::move(parent_window_handle), std::move(rectangle), std::move(text), std::move(style)); + } + + template< class Behavior > + void RadioButton< Behavior >::OnPressed() noexcept + {} + + template< class Behavior > + void RadioButton< Behavior >::OnCommand(WORD notification) noexcept { + if constexpr (HasOnGainedFocus< Behavior >::value) { + if (notification == BN_SETFOCUS ) { + behavior_.OnGainedFocus(&implementation_); + } + } + + if constexpr (HasOnLostFocus< Behavior >::value) { + if (notification == BN_KILLFOCUS ) { + behavior_.OnLostFocus(&implementation_); + } + } + + if (notification == BN_CLICKED) { + OnPressed(); + } + } + +} // namespace maxGUI + +#endif \ No newline at end of file diff --git a/Code/maxGUI/RadioButtonImplementation.cpp b/Code/maxGUI/RadioButtonImplementation.cpp new file mode 100644 index 0000000..d00acc4 --- /dev/null +++ b/Code/maxGUI/RadioButtonImplementation.cpp @@ -0,0 +1,66 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #include +#endif + +namespace maxGUI +{ + +#if defined(MAX_PLATFORM_WINDOWS) + RadioButtonImplementation::RadioButtonImplementation(HWND window_handle) noexcept + : ControlWithTextImplementation(std::move(window_handle)) + {} +#endif + + RadioButtonImplementation::~RadioButtonImplementation() noexcept = default; + +#if defined(MAX_PLATFORM_WINDOWS) + HWND RadioButtonImplementation::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, RadioButtonStyles style) noexcept { + DWORD win32_styles = WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | BS_NOTIFY; + // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" + // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. + // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 +#pragma warning(push) +#pragma warning(disable: 26813) + if ((style & RadioButtonStyles::Disabled) == RadioButtonStyles::Disabled) { + win32_styles |= WS_DISABLED; + } + if ((style & RadioButtonStyles::FirstInGroup) == RadioButtonStyles::FirstInGroup) { + win32_styles |= WS_GROUP | WS_TABSTOP; + } + if ((style & RadioButtonStyles::Flat) == RadioButtonStyles::Flat) { + win32_styles |= BS_FLAT; + } +#pragma warning(pop) + Win32String win32_text = Utf8ToWin32String(std::move(text)); + //return CreateWindowEx(0, TEXT("BUTTON"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); + HWND window_handle = CreateWindowEx(0, TEXT("BUTTON"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); + + static int count = 0; + if (count == 0) { + LOGFONT lf = {0}; + SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0); + HFONT font = CreateFontIndirect(&lf); + SendMessage(window_handle, WM_SETFONT, reinterpret_cast(font), TRUE); + } else { + //const int font_height_in_points = 14; + //HDC screen_device_context = GetDC(NULL); + //const int font_height_in_logical_units = -MulDiv(font_height_in_points, GetDeviceCaps(screen_device_context, LOGPIXELSY), 72); + const int font_height_in_logical_units = -14; + HFONT font = CreateFont(font_height_in_logical_units, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE | DEFAULT_PITCH, TEXT("Segoe UI Variable")); + SendMessage(window_handle, WM_SETFONT, reinterpret_cast(font), TRUE); + } + count++; + + return window_handle; + } +#endif + +} // namespace maxGUI \ No newline at end of file diff --git a/Code/maxGUI/RadioButtonImplementation.hpp b/Code/maxGUI/RadioButtonImplementation.hpp new file mode 100644 index 0000000..de5f465 --- /dev/null +++ b/Code/maxGUI/RadioButtonImplementation.hpp @@ -0,0 +1,58 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXGUI_RADIOBUTTONIMPLEMENTATION_HPP +#define MAXGUI_RADIOBUTTONIMPLEMENTATION_HPP + +#include + +#include +#include +#include +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + + #include +#endif + +namespace maxGUI +{ + + enum class RadioButtonStyles : uint8_t { + None = 0, + Disabled = 1, + FirstInGroup = 2, + Flat = 4, + }; + +} // namespace maxGUI + +MAX_BITMASKABLE_ENUM_CLASS(maxGUI::RadioButtonStyles); + +namespace maxGUI +{ + + class RadioButtonImplementation : public ControlWithTextImplementation + { + public: + +#if defined(MAX_PLATFORM_WINDOWS) + explicit RadioButtonImplementation(HWND window_handle) noexcept; +#endif + + ~RadioButtonImplementation() noexcept; + +#if defined(MAX_PLATFORM_WINDOWS) + static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, RadioButtonStyles style) noexcept; +#endif + + }; + +} // namespace maxGUI + +#endif // #ifndef MAXGUI_RADIOBUTTONIMPLEMENTATION_HPP \ No newline at end of file diff --git a/Code/maxGUI/TextBox.hpp b/Code/maxGUI/TextBox.hpp index 5b0a74a..bb96be4 100644 --- a/Code/maxGUI/TextBox.hpp +++ b/Code/maxGUI/TextBox.hpp @@ -5,50 +5,47 @@ #ifndef MAXGUI_TEXTBOX_HPP #define MAXGUI_TEXTBOX_HPP -#include -#include -#include #include -#include - #include +#include +#include +#include -// TODO: Add Linux version of TextBox #if defined(MAX_PLATFORM_WINDOWS) namespace maxGUI { - enum class TextBoxStyles : uint8_t { - None = 0, - Disabled = 1, - Password = 2, - ReadOnly = 4, + class DefaultTextBoxBehavior { }; -} // namespace maxGUI - -MAX_BITMASKABLE_ENUM_CLASS(maxGUI::TextBoxStyles); - -namespace maxGUI -{ - + template< class Behavior = DefaultTextBoxBehavior > class TextBox : public ControlWithText { public: explicit TextBox(HWND window_handle) noexcept; - ~TextBox() noexcept override = default; + ~TextBox() noexcept override; static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, TextBoxStyles styles = TextBoxStyles::None) noexcept; + //protected: + +#if defined(MAX_PLATFORM_WINDOWS) + void OnCommand(WORD notification) noexcept override; +#endif + + Behavior behavior_; + TextBoxImplementation implementation_; + }; } // namespace maxGUI +#endif -#endif // #if defined(MAX_PLATFORM_WINDOWS) +#include #endif // #ifndef MAXGUI_TEXTBOX_HPP \ No newline at end of file diff --git a/Code/maxGUI/TextBox.inl b/Code/maxGUI/TextBox.inl new file mode 100644 index 0000000..7df49fc --- /dev/null +++ b/Code/maxGUI/TextBox.inl @@ -0,0 +1,48 @@ +// Copyright 2020, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + +#include + +namespace maxGUI +{ + + template< class Behavior > + TextBox< Behavior >::TextBox(HWND window_handle) noexcept + : ControlWithText(window_handle) + , behavior_() + , implementation_(window_handle) + {} + + template< class Behavior > + TextBox< Behavior >::~TextBox() noexcept = default; + + template< class Behavior > + HWND TextBox< Behavior >::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, TextBoxStyles styles) noexcept { + return TextBoxImplementation::Create(std::move(parent_window_handle), std::move(rectangle), std::move(text), std::move(styles)); + } + +#if defined(MAX_PLATFORM_WINDOWS) + template< class Behavior > + void TextBox< Behavior >::OnCommand(WORD notification) noexcept { + if constexpr (HasOnGainedFocus< Behavior >::value) { + if (notification == EN_SETFOCUS ) { + behavior_.OnGainedFocus(&implementation_); + } + } + + if constexpr (HasOnLostFocus< Behavior >::value) { + if (notification == EN_KILLFOCUS ) { + behavior_.OnLostFocus(&implementation_); + } + } + } +#endif + +} // namespace maxGUI + +#endif \ No newline at end of file diff --git a/Code/maxGUI/TextBox.cpp b/Code/maxGUI/TextBoxImplementation.cpp similarity index 59% rename from Code/maxGUI/TextBox.cpp rename to Code/maxGUI/TextBoxImplementation.cpp index 30a9450..3bd00bd 100644 --- a/Code/maxGUI/TextBox.cpp +++ b/Code/maxGUI/TextBoxImplementation.cpp @@ -1,55 +1,63 @@ -// Copyright 2020, The maxGUI Contributors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include - -#include -#include -#include - -namespace maxGUI -{ - - TextBox::TextBox(HWND window_handle) noexcept - : ControlWithText(std::move(window_handle)) - {} - - HWND TextBox::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, TextBoxStyles styles) noexcept { - DWORD win32_styles = WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL; - // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" - // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. - // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 - #pragma warning(push) - #pragma warning(disable: 26813) - if ((styles & TextBoxStyles::Disabled) == TextBoxStyles::Disabled) { - win32_styles |= WS_DISABLED; - } - if ((styles & TextBoxStyles::Password) == TextBoxStyles::Password) { - win32_styles |= ES_PASSWORD; - } - if ((styles & TextBoxStyles::ReadOnly) == TextBoxStyles::ReadOnly) { - win32_styles |= ES_READONLY; - } - #pragma warning(pop) - - //EM_GETSEL - Gets the starting (low-order word) and ending (first nonselected char, high-order word) character positions of the current selection. - //EM_LIMITTEXT - wParam holds max number of chars. If this is zero, the text length is set to the maximum number of bytes possible. - //EM_REPLACESEL - pointer to the text in the lParam parameter. The new text must be null-terminated. - //EM_SETPASSWORDCHAR - new password character in the wParam parameter. Doesn't work on multi-line - //EM_SETSEL - lParam specifies the starting (low-order word) and ending (high-order word) character for the selection. - //To select the 10th through 20th characters in an edit control: - //SendMessage(hEditWnd, EM_SETSEL, 0, MAKELONG(9,19) ); - //To deselect a selection: - //SendMessage(hEditWnd, EM_SETSEL, 0, MAKELONG(0xffff, 0) ); - //To set the caret at the end of the edit control: - //SendMessage(hEditWnd, EM_SETSEL, 0, MAKELONG(0xffff, 0xffff) ); - //To set the caret after the position of the Nth character: - //SendMessage(hEditWnd, EM_SETSEL, 0, MAKELONG(N, N) ); - //EN_UPDATE - text changed - - Win32String win32_text = Utf8ToWin32String(std::move(text)); - return CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); - } - -} // namespace maxGUI \ No newline at end of file +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #include +#endif + +namespace maxGUI +{ + +#if defined(MAX_PLATFORM_WINDOWS) + TextBoxImplementation::TextBoxImplementation(HWND window_handle) noexcept + : ControlWithTextImplementation(std::move(window_handle)) + {} +#endif + + TextBoxImplementation::~TextBoxImplementation() noexcept = default; + +#if defined(MAX_PLATFORM_WINDOWS) + HWND TextBoxImplementation::Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, TextBoxStyles styles) noexcept { + DWORD win32_styles = WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL; + // MSVC at warning level 4 issues C26813 because it wants "if (styles & ButtonStyles::Default) {" + // But this doesn't play nicely with enum classes because ultimately it needs to convert to bool. + // See https://developercommunity.visualstudio.com/t/C26813-incompatible-with-enum-class/10145182 +#pragma warning(push) +#pragma warning(disable: 26813) + if ((styles & TextBoxStyles::Disabled) == TextBoxStyles::Disabled) { + win32_styles |= WS_DISABLED; + } + if ((styles & TextBoxStyles::Password) == TextBoxStyles::Password) { + win32_styles |= ES_PASSWORD; + } + if ((styles & TextBoxStyles::ReadOnly) == TextBoxStyles::ReadOnly) { + win32_styles |= ES_READONLY; + } +#pragma warning(pop) + + //EM_GETSEL - Gets the starting (low-order word) and ending (first nonselected char, high-order word) character positions of the current selection. + //EM_LIMITTEXT - wParam holds max number of chars. If this is zero, the text length is set to the maximum number of bytes possible. + //EM_REPLACESEL - pointer to the text in the lParam parameter. The new text must be null-terminated. + //EM_SETPASSWORDCHAR - new password character in the wParam parameter. Doesn't work on multi-line + //EM_SETSEL - lParam specifies the starting (low-order word) and ending (high-order word) character for the selection. + //To select the 10th through 20th characters in an edit control: + //SendMessage(hEditWnd, EM_SETSEL, 0, MAKELONG(9,19) ); + //To deselect a selection: + //SendMessage(hEditWnd, EM_SETSEL, 0, MAKELONG(0xffff, 0) ); + //To set the caret at the end of the edit control: + //SendMessage(hEditWnd, EM_SETSEL, 0, MAKELONG(0xffff, 0xffff) ); + //To set the caret after the position of the Nth character: + //SendMessage(hEditWnd, EM_SETSEL, 0, MAKELONG(N, N) ); + //EN_UPDATE - text changed + + Win32String win32_text = Utf8ToWin32String(std::move(text)); + return CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), win32_text.text_, win32_styles, rectangle.TopLeft.X(), rectangle.TopLeft.Y(), rectangle.Width, rectangle.Height, parent_window_handle, NULL, reinterpret_cast(GetWindowLongPtr(parent_window_handle, GWLP_HINSTANCE)), NULL); + } +#endif + +} // namespace maxGUI \ No newline at end of file diff --git a/Code/maxGUI/TextBoxImplementation.hpp b/Code/maxGUI/TextBoxImplementation.hpp new file mode 100644 index 0000000..eed1ff0 --- /dev/null +++ b/Code/maxGUI/TextBoxImplementation.hpp @@ -0,0 +1,59 @@ +// Copyright 2023, The maxGUI Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXGUI_TEXTBOXIMPLEMENTATION_HPP +#define MAXGUI_TEXTBOXIMPLEMENTATION_HPP + +#include + +#include +#include +#include +#include + +#if defined(MAX_PLATFORM_WINDOWS) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + + #include +#endif + + +namespace maxGUI +{ + + enum class TextBoxStyles : uint8_t { + None = 0, + Disabled = 1, + Password = 2, + ReadOnly = 4, + }; + +} // namespace maxGUI + +MAX_BITMASKABLE_ENUM_CLASS(maxGUI::TextBoxStyles); + +namespace maxGUI +{ + + class TextBoxImplementation : public ControlWithTextImplementation + { + public: + +#if defined(MAX_PLATFORM_WINDOWS) + explicit TextBoxImplementation(HWND window_handle) noexcept; +#endif + + ~TextBoxImplementation() noexcept override; + +#if defined(MAX_PLATFORM_WINDOWS) + static HWND Create(HWND parent_window_handle, max::Containers::Rectangle rectangle, std::string text, TextBoxStyles styles) noexcept; +#endif + + }; + +} // namespace maxGUI + +#endif // #ifndef MAXGUI_TEXTBOXIMPLEMENTATION_HPP \ No newline at end of file diff --git a/Projects/Clang X86 Make/Makefile b/Projects/Clang X86 Make/Makefile index 5b8e421..048539d 100644 --- a/Projects/Clang X86 Make/Makefile +++ b/Projects/Clang X86 Make/Makefile @@ -1,22 +1,24 @@ PROGRAM_NAME = maxGUI CXX_SRCS = \ - ../../Code/maxGUI/Button.cpp \ + ../../Code/maxGUI/ButtonImplementation.cpp \ ../../Code/maxGUI/Control.cpp \ + ../../Code/maxGUI/ControlImplementation.cpp \ ../../Code/maxGUI/ControlWithText.cpp \ + ../../Code/maxGUI/ControlWithTextImplementation.cpp \ ../../Code/maxGUI/EntryPoint.cpp \ ../../Code/maxGUI/FormAllocatorConcept.cpp \ ../../Code/maxGUI/FormConcept.cpp \ ../../Code/maxGUI/FormContainer.cpp \ - ../../Code/maxGUI/MultilineTextBox.cpp - #../../Code/maxGUI/CheckBox.cpp \ + ../../Code/maxGUI/MultilineTextBoxImplementation.cpp + #../../Code/maxGUI/CheckBoxImplementation.cpp \ #../../Code/maxGUI/ControlWithList.cpp \ - #../../Code/maxGUI/DropDownBox.cpp \ + #../../Code/maxGUI/DropDownBoxImplementation.cpp \ #../../Code/maxGUI/Frame.cpp \ #../../Code/maxGUI/Label.cpp \ - #../../Code/maxGUI/ListBox.cpp \ + #../../Code/maxGUI/ListBoxImplementation.cpp \ #../../Code/maxGUI/ProgressBar.cpp \ - #../../Code/maxGUI/RadioButton.cpp \ - #../../Code/maxGUI/TextBox.cpp + #../../Code/maxGUI/RadioButtonImplementation.cpp \ + #../../Code/maxGUI/TextBoxImplementation.cpp CXX_OBJS = $(CXX_SRCS:.cpp=.o) INCLUDE_PATHS = \ diff --git a/Projects/Clang X86-64 Make/Makefile b/Projects/Clang X86-64 Make/Makefile index 32c29ad..efb7ba8 100644 --- a/Projects/Clang X86-64 Make/Makefile +++ b/Projects/Clang X86-64 Make/Makefile @@ -1,22 +1,24 @@ PROGRAM_NAME = maxGUI CXX_SRCS = \ - ../../Code/maxGUI/Button.cpp \ + ../../Code/maxGUI/ButtonImplementation.cpp \ ../../Code/maxGUI/Control.cpp \ + ../../Code/maxGUI/ControlImplementation.cpp \ ../../Code/maxGUI/ControlWithText.cpp \ + ../../Code/maxGUI/ControlWithTextImplementation.cpp \ ../../Code/maxGUI/EntryPoint.cpp \ ../../Code/maxGUI/FormAllocatorConcept.cpp \ ../../Code/maxGUI/FormConcept.cpp \ ../../Code/maxGUI/FormContainer.cpp \ - ../../Code/maxGUI/MultilineTextBox.cpp - #../../Code/maxGUI/CheckBox.cpp \ + ../../Code/maxGUI/MultilineTextBoxImplementation.cpp + #../../Code/maxGUI/CheckBoxImplementation.cpp \ #../../Code/maxGUI/ControlWithList.cpp \ - #../../Code/maxGUI/DropDownBox.cpp \ + #../../Code/maxGUI/DropDownBoxImplementation.cpp \ #../../Code/maxGUI/Frame.cpp \ #../../Code/maxGUI/Label.cpp \ - #../../Code/maxGUI/ListBox.cpp \ + #../../Code/maxGUI/ListBoxImplementation.cpp \ #../../Code/maxGUI/ProgressBar.cpp \ - #../../Code/maxGUI/RadioButton.cpp \ - #../../Code/maxGUI/TextBox.cpp + #../../Code/maxGUI/RadioButtonImplementation.cpp \ + #../../Code/maxGUI/TextBoxImplementation.cpp CXX_OBJS = $(CXX_SRCS:.cpp=.o) INCLUDE_PATHS = \ diff --git a/Projects/GCC X86 Make/Makefile b/Projects/GCC X86 Make/Makefile index e6a9702..e3446ca 100644 --- a/Projects/GCC X86 Make/Makefile +++ b/Projects/GCC X86 Make/Makefile @@ -1,22 +1,24 @@ PROGRAM_NAME = maxGUI CXX_SRCS = \ - ../../Code/maxGUI/Button.cpp \ + ../../Code/maxGUI/ButtonImplementation.cpp \ ../../Code/maxGUI/Control.cpp \ + ../../Code/maxGUI/ControlImplementation.cpp \ ../../Code/maxGUI/ControlWithText.cpp \ + ../../Code/maxGUI/ControlWithTextImplementation.cpp \ ../../Code/maxGUI/EntryPoint.cpp \ - ../../Code/maxGUI/FormAllocatorConcept.cpp \ + ../../Code/maxGUI/FormAllocatorConcept.cpp \ ../../Code/maxGUI/FormConcept.cpp \ ../../Code/maxGUI/FormContainer.cpp \ - ../../Code/maxGUI/MultilineTextBox.cpp - #../../Code/maxGUI/CheckBox.cpp \ + ../../Code/maxGUI/MultilineTextBoxImplementation.cpp + #../../Code/maxGUI/CheckBoxImplementation.cpp \ #../../Code/maxGUI/ControlWithList.cpp \ - #../../Code/maxGUI/DropDownBox.cpp \ + #../../Code/maxGUI/DropDownBoxImplementation.cpp \ #../../Code/maxGUI/Frame.cpp \ #../../Code/maxGUI/Label.cpp \ - #../../Code/maxGUI/ListBox.cpp \ + #../../Code/maxGUI/ListBoxImplementation.cpp \ #../../Code/maxGUI/ProgressBar.cpp \ - #../../Code/maxGUI/RadioButton.cpp \ - #../../Code/maxGUI/TextBox.cpp + #../../Code/maxGUI/RadioButtonImplementation.cpp \ + #../../Code/maxGUI/TextBoxImplementation.cpp CXX_OBJS = $(CXX_SRCS:.cpp=.o) INCLUDE_PATHS = \ diff --git a/Projects/GCC X86-64 Make/Makefile b/Projects/GCC X86-64 Make/Makefile index d9f8ce9..e2c68fa 100644 --- a/Projects/GCC X86-64 Make/Makefile +++ b/Projects/GCC X86-64 Make/Makefile @@ -1,22 +1,24 @@ PROGRAM_NAME = maxGUI CXX_SRCS = \ - ../../Code/maxGUI/Button.cpp \ + ../../Code/maxGUI/ButtonImplementation.cpp \ ../../Code/maxGUI/Control.cpp \ + ../../Code/maxGUI/ControlImplementation.cpp \ ../../Code/maxGUI/ControlWithText.cpp \ + ../../Code/maxGUI/ControlWithTextImplementation.cpp \ ../../Code/maxGUI/EntryPoint.cpp \ ../../Code/maxGUI/FormAllocatorConcept.cpp \ ../../Code/maxGUI/FormConcept.cpp \ ../../Code/maxGUI/FormContainer.cpp \ - ../../Code/maxGUI/MultilineTextBox.cpp - #../../Code/maxGUI/CheckBox.cpp \ + ../../Code/maxGUI/MultilineTextBoxImplementation.cpp + #../../Code/maxGUI/CheckBoxImplementation.cpp \ #../../Code/maxGUI/ControlWithList.cpp \ - #../../Code/maxGUI/DropDownBox.cpp \ + #../../Code/maxGUI/DropDownBoxImplementation.cpp \ #../../Code/maxGUI/Frame.cpp \ #../../Code/maxGUI/Label.cpp \ - #../../Code/maxGUI/ListBox.cpp \ + #../../Code/maxGUI/ListBoxImplementation.cpp \ #../../Code/maxGUI/ProgressBar.cpp \ - #../../Code/maxGUI/RadioButton.cpp \ - #../../Code/maxGUI/TextBox.cpp + #../../Code/maxGUI/RadioButtonImplementation.cpp \ + #../../Code/maxGUI/TextBoxImplementation.cpp CXX_OBJS = $(CXX_SRCS:.cpp=.o) INCLUDE_PATHS = \ diff --git a/Projects/VisualStudio/maxGUI/maxGUI.vcxproj b/Projects/VisualStudio/maxGUI/maxGUI.vcxproj index 1f9bd05..8fe63e1 100644 --- a/Projects/VisualStudio/maxGUI/maxGUI.vcxproj +++ b/Projects/VisualStudio/maxGUI/maxGUI.vcxproj @@ -24,9 +24,15 @@ + + + + + + @@ -43,30 +49,38 @@ - + + + - + + - - + + - - + + + + + + + @@ -78,11 +92,15 @@ + + + + @@ -193,6 +211,7 @@ true stdcpplatest + true Windows @@ -211,6 +230,7 @@ true stdcpplatest + true Windows @@ -231,6 +251,7 @@ true stdcpplatest + true Windows @@ -253,6 +274,7 @@ true stdcpplatest + true Windows diff --git a/Projects/VisualStudio/maxGUI/maxGUI.vcxproj.filters b/Projects/VisualStudio/maxGUI/maxGUI.vcxproj.filters index 2902d3f..c0aa93c 100644 --- a/Projects/VisualStudio/maxGUI/maxGUI.vcxproj.filters +++ b/Projects/VisualStudio/maxGUI/maxGUI.vcxproj.filters @@ -101,6 +101,24 @@ Dependencies\max\Containers + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + @@ -114,55 +132,64 @@ Code - - Code - Code Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + + Code + + + Code + + + Code + + + Code + + Code @@ -293,5 +320,32 @@ Dependencies\max\Compiling + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + \ No newline at end of file