| ... | ... |
@@ -50,7 +50,7 @@ |
| 50 | 50 |
<WarningLevel>Level4</WarningLevel> |
| 51 | 51 |
<Optimization>Disabled</Optimization> |
| 52 | 52 |
<PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_2SF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;HAVE_LIBZ;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| 53 |
- <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 53 |
+ <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 54 | 54 |
<DisableSpecificWarnings>4065;4100;4127;4146;4189;4201;4244;4245;4512;4706;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings> |
| 55 | 55 |
</ClCompile> |
| 56 | 56 |
<Link> |
| ... | ... |
@@ -67,7 +67,7 @@ |
| 67 | 67 |
<FunctionLevelLinking>true</FunctionLevelLinking> |
| 68 | 68 |
<IntrinsicFunctions>true</IntrinsicFunctions> |
| 69 | 69 |
<PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_2SF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;HAVE_LIBZ;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| 70 |
- <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 70 |
+ <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 71 | 71 |
<DisableSpecificWarnings>4065;4100;4127;4146;4189;4201;4244;4245;4512;4706;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings> |
| 72 | 72 |
</ClCompile> |
| 73 | 73 |
<Link> |
| ... | ... |
@@ -50,7 +50,7 @@ |
| 50 | 50 |
<WarningLevel>Level4</WarningLevel> |
| 51 | 51 |
<Optimization>Disabled</Optimization> |
| 52 | 52 |
<PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_GSF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| 53 |
- <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 53 |
+ <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 54 | 54 |
<DisableSpecificWarnings>4100;4127;4189;4244;4291;4310;4512;4800;%(DisableSpecificWarnings)</DisableSpecificWarnings> |
| 55 | 55 |
</ClCompile> |
| 56 | 56 |
<Link> |
| ... | ... |
@@ -67,7 +67,7 @@ |
| 67 | 67 |
<FunctionLevelLinking>true</FunctionLevelLinking> |
| 68 | 68 |
<IntrinsicFunctions>true</IntrinsicFunctions> |
| 69 | 69 |
<PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_GSF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| 70 |
- <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 70 |
+ <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 71 | 71 |
<DisableSpecificWarnings>4100;4127;4189;4244;4291;4310;4512;4800;%(DisableSpecificWarnings)</DisableSpecificWarnings> |
| 72 | 72 |
</ClCompile> |
| 73 | 73 |
<Link> |
| ... | ... |
@@ -50,7 +50,7 @@ |
| 50 | 50 |
<WarningLevel>Level4</WarningLevel> |
| 51 | 51 |
<Optimization>Disabled</Optimization> |
| 52 | 52 |
<PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_NCSF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| 53 |
- <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 53 |
+ <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 54 | 54 |
<DisableSpecificWarnings>4244;%(DisableSpecificWarnings)</DisableSpecificWarnings> |
| 55 | 55 |
</ClCompile> |
| 56 | 56 |
<Link> |
| ... | ... |
@@ -67,7 +67,7 @@ |
| 67 | 67 |
<FunctionLevelLinking>true</FunctionLevelLinking> |
| 68 | 68 |
<IntrinsicFunctions>true</IntrinsicFunctions> |
| 69 | 69 |
<PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_NCSF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| 70 |
- <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 70 |
+ <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 71 | 71 |
<DisableSpecificWarnings>4244;%(DisableSpecificWarnings)</DisableSpecificWarnings> |
| 72 | 72 |
</ClCompile> |
| 73 | 73 |
<Link> |
| ... | ... |
@@ -50,7 +50,7 @@ |
| 50 | 50 |
<WarningLevel>Level4</WarningLevel> |
| 51 | 51 |
<Optimization>Disabled</Optimization> |
| 52 | 52 |
<PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_SNSF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| 53 |
- <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 53 |
+ <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 54 | 54 |
<DisableSpecificWarnings>4100;4127;4244;4245;4310;%(DisableSpecificWarnings)</DisableSpecificWarnings> |
| 55 | 55 |
</ClCompile> |
| 56 | 56 |
<Link> |
| ... | ... |
@@ -67,7 +67,7 @@ |
| 67 | 67 |
<FunctionLevelLinking>true</FunctionLevelLinking> |
| 68 | 68 |
<IntrinsicFunctions>true</IntrinsicFunctions> |
| 69 | 69 |
<PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_SNSF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| 70 |
- <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 70 |
+ <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 71 | 71 |
<DisableSpecificWarnings>4100;4127;4244;4245;4310;%(DisableSpecificWarnings)</DisableSpecificWarnings> |
| 72 | 72 |
</ClCompile> |
| 73 | 73 |
<Link> |
| 74 | 74 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,677 @@ |
| 1 |
+/* |
|
| 2 |
+ * Windows Dynamic Dialog Builder framework |
|
| 3 |
+ * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com] |
|
| 4 |
+ * Last modification on 2013-04-23 |
|
| 5 |
+ */ |
|
| 6 |
+ |
|
| 7 |
+#ifndef DIALOG_BUILDER_H |
|
| 8 |
+#define DIALOG_BUILDER_H |
|
| 9 |
+ |
|
| 10 |
+#include <string> |
|
| 11 |
+#include <memory> |
|
| 12 |
+#include <vector> |
|
| 13 |
+#include <algorithm> |
|
| 14 |
+#include <stdexcept> |
|
| 15 |
+#include <cstdint> |
|
| 16 |
+#include "windowsh_wrapper.h" |
|
| 17 |
+#include "UtfConverter.h" |
|
| 18 |
+ |
|
| 19 |
+template<typename T> struct Point |
|
| 20 |
+{
|
|
| 21 |
+ T x, y; |
|
| 22 |
+ |
|
| 23 |
+ Point() : x(), y() { }
|
|
| 24 |
+ Point(T X, T Y) : x(X), y(Y) { }
|
|
| 25 |
+}; |
|
| 26 |
+ |
|
| 27 |
+template<typename T> struct Size |
|
| 28 |
+{
|
|
| 29 |
+ T width, height; |
|
| 30 |
+ |
|
| 31 |
+ Size() : width(), height() { }
|
|
| 32 |
+ Size(T Width, T Height) : width(Width), height(Height) { }
|
|
| 33 |
+}; |
|
| 34 |
+ |
|
| 35 |
+template<typename T> struct Rect |
|
| 36 |
+{
|
|
| 37 |
+ Point<T> position; |
|
| 38 |
+ Size<T> size; |
|
| 39 |
+ |
|
| 40 |
+ Rect() : position(), size() { }
|
|
| 41 |
+ Rect(const Point<T> &Position, const Size<T> &Sz) : position(Position), size(Sz) { }
|
|
| 42 |
+ Rect(T X, T Y, T Width, T Height) : position(X, Y), size(Width, Height) { }
|
|
| 43 |
+}; |
|
| 44 |
+ |
|
| 45 |
+class RelativePosition |
|
| 46 |
+{
|
|
| 47 |
+public: |
|
| 48 |
+ Point<short> relativePosition; |
|
| 49 |
+ enum BaseType |
|
| 50 |
+ {
|
|
| 51 |
+ TO_PARENT, |
|
| 52 |
+ TO_SIBLING |
|
| 53 |
+ } type; |
|
| 54 |
+ enum PositionType |
|
| 55 |
+ {
|
|
| 56 |
+ FROM_TOP, |
|
| 57 |
+ FROM_BOTTOM, |
|
| 58 |
+ FROM_LEFT, |
|
| 59 |
+ FROM_RIGHT, |
|
| 60 |
+ FROM_TOPLEFT, |
|
| 61 |
+ FROM_BOTTOMLEFT, |
|
| 62 |
+ FROM_TOPRIGHT, |
|
| 63 |
+ FROM_BOTTOMRIGHT |
|
| 64 |
+ } positionType; |
|
| 65 |
+ |
|
| 66 |
+ RelativePosition(const Point<short> &RelPosition, BaseType Type, PositionType PosType) : relativePosition(RelPosition), type(Type), positionType(PosType) { }
|
|
| 67 |
+ virtual ~RelativePosition() { }
|
|
| 68 |
+ virtual RelativePosition *Clone() const = 0; |
|
| 69 |
+ Point<short> CalculatePosition(const Rect<short> &child, const Rect<short> &other); |
|
| 70 |
+}; |
|
| 71 |
+ |
|
| 72 |
+class RelativePositionToParent : public RelativePosition |
|
| 73 |
+{
|
|
| 74 |
+public: |
|
| 75 |
+ RelativePositionToParent(const Point<short> &RelPosition, PositionType PosType) : RelativePosition(RelPosition, TO_PARENT, PosType) { }
|
|
| 76 |
+ RelativePositionToParent *Clone() const { return new RelativePositionToParent(this->relativePosition, this->positionType); }
|
|
| 77 |
+}; |
|
| 78 |
+ |
|
| 79 |
+class RelativePositionToSibling : public RelativePosition |
|
| 80 |
+{
|
|
| 81 |
+public: |
|
| 82 |
+ short siblingsBack; |
|
| 83 |
+ |
|
| 84 |
+ RelativePositionToSibling(const Point<short> &RelPosition, PositionType PosType, short SiblingsBack = 1) : RelativePosition(RelPosition, TO_SIBLING, PosType), siblingsBack(SiblingsBack) { }
|
|
| 85 |
+ RelativePositionToSibling *Clone() const { return new RelativePositionToSibling(this->relativePosition, this->positionType, this->siblingsBack); }
|
|
| 86 |
+}; |
|
| 87 |
+ |
|
| 88 |
+enum DialogControlType |
|
| 89 |
+{
|
|
| 90 |
+ NO_CONTROL, |
|
| 91 |
+ GROUP_CONTROL, |
|
| 92 |
+ EDITBOX_CONTROL, |
|
| 93 |
+ LABEL_CONTROL, |
|
| 94 |
+ CHECKBOX_CONTROL, |
|
| 95 |
+ BUTTON_CONTROL, |
|
| 96 |
+ LISTBOX_CONTROL, |
|
| 97 |
+ COMBOBOX_CONTROL |
|
| 98 |
+}; |
|
| 99 |
+ |
|
| 100 |
+class DialogTemplate; |
|
| 101 |
+ |
|
| 102 |
+class DialogBuilder |
|
| 103 |
+{
|
|
| 104 |
+protected: |
|
| 105 |
+ friend class DialogTemplate; |
|
| 106 |
+ std::wstring title, fontName; |
|
| 107 |
+ uint32_t style, exstyle; |
|
| 108 |
+ uint16_t fontSizeInPts; |
|
| 109 |
+ Size<short> size; |
|
| 110 |
+ bool resetControls; |
|
| 111 |
+public: |
|
| 112 |
+ DialogBuilder() : title(L""), fontName(L""), style(0), exstyle(0), fontSizeInPts(0), size(), resetControls(false) { }
|
|
| 113 |
+ DialogBuilder &WithTitle(const std::wstring &Title) { this->title = Title; return *this; }
|
|
| 114 |
+ DialogBuilder &WithFont(const std::wstring &FontName, uint16_t FontSizeInPts) { this->fontName = FontName; this->fontSizeInPts = FontSizeInPts; return *this; }
|
|
| 115 |
+ DialogBuilder &WithSize(short Width, short Height) { this->size.width = Width; this->size.height = Height; return *this; }
|
|
| 116 |
+ DialogBuilder &WithSize(const Size<short> &Sz) { this->size = Sz; return *this; }
|
|
| 117 |
+ DialogBuilder &ResetControls(bool Reset = true) { this->resetControls = Reset; return *this; }
|
|
| 118 |
+ DialogBuilder &IsOverlapped() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_OVERLAPPED; return *this; }
|
|
| 119 |
+ DialogBuilder &IsPopup() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_POPUP; return *this; }
|
|
| 120 |
+ DialogBuilder &IsChild() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_CHILD; return *this; }
|
|
| 121 |
+ DialogBuilder &WithBorder(bool Border = true) { if (Border) this->style |= WS_BORDER; else this->style &= ~WS_BORDER; return *this; }
|
|
| 122 |
+ DialogBuilder &WithDialogFrame(bool DialogFrame = true) { if (DialogFrame) this->style |= WS_DLGFRAME; else this->style &= ~WS_DLGFRAME; return *this; }
|
|
| 123 |
+ DialogBuilder &WithVerticalScrollbar(bool VerticalScrollbar = true) { if (VerticalScrollbar) this->style |= WS_VSCROLL; else this->style &= ~WS_VSCROLL; return *this; }
|
|
| 124 |
+ DialogBuilder &WithHorizontalScrollbar(bool HorizontalScrollbar = true) { if (HorizontalScrollbar) this->style |= WS_HSCROLL; else this->style &= ~WS_HSCROLL; return *this; }
|
|
| 125 |
+ DialogBuilder &WithSystemMenu(bool SystemMenu = true) { if (SystemMenu) this->style |= WS_SYSMENU; else this->style &= ~WS_SYSMENU; return *this; }
|
|
| 126 |
+ DialogBuilder &WithSizingBorder(bool SizingBorder = true) { if (SizingBorder) this->style |= WS_THICKFRAME; else this->style &= ~WS_THICKFRAME; return *this; }
|
|
| 127 |
+ DialogBuilder &WithMinimizeBox(bool MinimizeBox = true) { if (MinimizeBox) this->style |= WS_MINIMIZEBOX; else this->style &= ~WS_MINIMIZEBOX; return *this; }
|
|
| 128 |
+ DialogBuilder &WithMaximizeBox(bool MaximizeBox = true) { if (MaximizeBox) this->style |= WS_MAXIMIZEBOX; else this->style &= ~WS_MAXIMIZEBOX; return *this; }
|
|
| 129 |
+ DialogBuilder &WithDialogModalFrame(bool DialogModalFrame = true) { if (DialogModalFrame) this->exstyle |= WS_EX_DLGMODALFRAME; else this->exstyle &= ~WS_EX_DLGMODALFRAME; return *this; }
|
|
| 130 |
+#if WINVER >= 0x0400 |
|
| 131 |
+ DialogBuilder &WithRaisedEdge(bool RaisedEdge = true) { if (RaisedEdge) this->exstyle |= WS_EX_WINDOWEDGE; else this->exstyle &= ~WS_EX_WINDOWEDGE; return *this; }
|
|
| 132 |
+ DialogBuilder &WithSunkenEdge(bool SunkenEdge = true) { if (SunkenEdge) this->exstyle |= WS_EX_CLIENTEDGE; else this->exstyle &= ~WS_EX_CLIENTEDGE; return *this; }
|
|
| 133 |
+ DialogBuilder &WithContextHelp(bool ContextHelp = true) { if (ContextHelp) this->exstyle |= WS_EX_CONTEXTHELP; else this->exstyle &= ~WS_EX_CONTEXTHELP; return *this; }
|
|
| 134 |
+ DialogBuilder &IsControlWindow(bool ControlWindow = true) { if (ControlWindow) this->style |= DS_CONTROL; else this->style &= ~DS_CONTROL; return *this; }
|
|
| 135 |
+ DialogBuilder &IsCentered(bool Centered = true) { if (Centered) this->style |= DS_CENTER; else this->style &= ~DS_CENTER; return *this; }
|
|
| 136 |
+#endif |
|
| 137 |
+}; |
|
| 138 |
+ |
|
| 139 |
+template<class T> class DialogControlBuilder |
|
| 140 |
+{
|
|
| 141 |
+protected: |
|
| 142 |
+ friend class DialogTemplate; |
|
| 143 |
+ DialogControlType controlType; |
|
| 144 |
+ uint32_t style, exstyle; |
|
| 145 |
+ Rect<short> rect; |
|
| 146 |
+ short id; |
|
| 147 |
+ int index; |
|
| 148 |
+ std::unique_ptr<RelativePosition> relativePosition; |
|
| 149 |
+ |
|
| 150 |
+ T &me() { return dynamic_cast<T &>(*this); }
|
|
| 151 |
+public: |
|
| 152 |
+ DialogControlBuilder(DialogControlType Type = NO_CONTROL) : controlType(Type), style(0), exstyle(0), rect(), id(-1), index(-1), relativePosition() { }
|
|
| 153 |
+ virtual ~DialogControlBuilder() { }
|
|
| 154 |
+ T &WithPosition(short X, short Y) { this->rect.position.x = X; this->rect.position.y = Y; return this->me(); }
|
|
| 155 |
+ T &WithPosition(const Point<short> &Position) { this->rect.position = Position; return this->me(); }
|
|
| 156 |
+ T &WithRelativePositionToParent(RelativePosition::PositionType PosType, const Point<short> &RelativePosition) |
|
| 157 |
+ {
|
|
| 158 |
+ this->relativePosition.reset(new RelativePositionToParent(RelativePosition, PosType)); |
|
| 159 |
+ return this->me(); |
|
| 160 |
+ } |
|
| 161 |
+ T &WithRelativePositionToSibling(RelativePosition::PositionType PosType, const Point<short> &RelativePosition, short SiblingsBack = 1) |
|
| 162 |
+ {
|
|
| 163 |
+ this->relativePosition.reset(new RelativePositionToSibling(RelativePosition, PosType, SiblingsBack)); |
|
| 164 |
+ return this->me(); |
|
| 165 |
+ } |
|
| 166 |
+ T &WithSize(short Width, short Height) { this->rect.size.width = Width; this->rect.size.height = Height; return this->me(); }
|
|
| 167 |
+ T &WithSize(const Size<short> &Sz) { this->rect.size = Sz; return this->me(); }
|
|
| 168 |
+ T &WithID(short ID) { this->id = ID; return this->me(); }
|
|
| 169 |
+ T &AtIndex(int Index) { this->index = Index; return this->me(); }
|
|
| 170 |
+ T &IsDisabled(bool Disabled = true) { if (Disabled) this->style |= WS_DISABLED; else this->style &= ~WS_DISABLED; return this->me(); }
|
|
| 171 |
+ T &WithBorder(bool ThinBorder = true) { if (ThinBorder) this->style |= WS_BORDER; else this->style &= ~WS_BORDER; return this->me(); }
|
|
| 172 |
+ T &WithVerticalScrollbar(bool VerticalScrollbar = true) { if (VerticalScrollbar) this->style |= WS_VSCROLL; else this->style &= ~WS_VSCROLL; return this->me(); }
|
|
| 173 |
+ T &WithHorizontalScrollbar(bool HorizontalScrollbar = true) { if (HorizontalScrollbar) this->style |= WS_HSCROLL; else this->style &= ~WS_HSCROLL; return this->me(); }
|
|
| 174 |
+ T &WithTabStop(bool TabStop = true) { if (TabStop) this->style |= WS_TABSTOP; else this->style &= ~WS_TABSTOP; return this->me(); }
|
|
| 175 |
+#if WINVER >= 0x0400 |
|
| 176 |
+ T &WithRaisedEdge(bool RaisedEdge = true) { if (RaisedEdge) this->exstyle |= WS_EX_WINDOWEDGE; else this->exstyle &= ~WS_EX_WINDOWEDGE; return this->me(); }
|
|
| 177 |
+ T &WithSunkenEdge(bool SunkenEdge = true) { if (SunkenEdge) this->exstyle |= WS_EX_CLIENTEDGE; else this->exstyle &= ~WS_EX_CLIENTEDGE; return this->me(); }
|
|
| 178 |
+#endif |
|
| 179 |
+}; |
|
| 180 |
+ |
|
| 181 |
+class DialogGroupBuilder : public DialogControlBuilder<DialogGroupBuilder> |
|
| 182 |
+{
|
|
| 183 |
+protected: |
|
| 184 |
+ friend class DialogTemplate; |
|
| 185 |
+ std::wstring groupName; |
|
| 186 |
+public: |
|
| 187 |
+ DialogGroupBuilder(const std::wstring &newGroupName) : DialogControlBuilder(GROUP_CONTROL), groupName(newGroupName) { }
|
|
| 188 |
+}; |
|
| 189 |
+ |
|
| 190 |
+template<class T> class DialogInGroupBuilder : public DialogControlBuilder<T> |
|
| 191 |
+{
|
|
| 192 |
+protected: |
|
| 193 |
+ friend class DialogTemplate; |
|
| 194 |
+ std::wstring groupName; |
|
| 195 |
+public: |
|
| 196 |
+ DialogInGroupBuilder(DialogControlType Type) : DialogControlBuilder<T>(Type), groupName(L"") { }
|
|
| 197 |
+ T &InGroup(const std::wstring &GroupName) { this->groupName = GroupName; return this->me(); }
|
|
| 198 |
+}; |
|
| 199 |
+ |
|
| 200 |
+class DialogEditBoxBuilder : public DialogInGroupBuilder<DialogEditBoxBuilder> |
|
| 201 |
+{
|
|
| 202 |
+protected: |
|
| 203 |
+ friend class DialogTemplate; |
|
| 204 |
+public: |
|
| 205 |
+ DialogEditBoxBuilder() : DialogInGroupBuilder(EDITBOX_CONTROL) { }
|
|
| 206 |
+ DialogEditBoxBuilder &IsLeftJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_LEFT; return this->me(); }
|
|
| 207 |
+ DialogEditBoxBuilder &IsCenterJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_CENTER; return this->me(); }
|
|
| 208 |
+ DialogEditBoxBuilder &IsRightJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_RIGHT; return this->me(); }
|
|
| 209 |
+ DialogEditBoxBuilder &IsMultiline(bool Multiline = true) { if (Multiline) this->style |= ES_MULTILINE; else this->style &= ~ES_MULTILINE; return this->me(); }
|
|
| 210 |
+ DialogEditBoxBuilder &WithAllUppercase(bool AllUppercase = true) { if (AllUppercase) this->style |= ES_UPPERCASE; else this->style &= ~ES_UPPERCASE; return this->me(); }
|
|
| 211 |
+ DialogEditBoxBuilder &WithAllLowercase(bool AllLowercase = true) { if (AllLowercase) this->style |= ES_LOWERCASE; else this->style &= ~ES_LOWERCASE; return this->me(); }
|
|
| 212 |
+ DialogEditBoxBuilder &IsPasswordInput(bool PasswordInput = true) { if (PasswordInput) this->style |= ES_PASSWORD; else this->style &= ~ES_PASSWORD; return this->me(); }
|
|
| 213 |
+ DialogEditBoxBuilder &WithAutoVScroll(bool AutoVScroll = true) { if (AutoVScroll) this->style |= ES_AUTOVSCROLL; else this->style &= ~ES_AUTOVSCROLL; return this->me(); }
|
|
| 214 |
+ DialogEditBoxBuilder &WithAutoHScroll(bool AutoHScroll = true) { if (AutoHScroll) this->style |= ES_AUTOHSCROLL; else this->style &= ~ES_AUTOHSCROLL; return this->me(); }
|
|
| 215 |
+ DialogEditBoxBuilder &WithDontHideSelection(bool DontHideSelection = true) { if (DontHideSelection) this->style |= ES_NOHIDESEL; else this->style &= ~ES_NOHIDESEL; return this->me(); }
|
|
| 216 |
+ DialogEditBoxBuilder &IsReadOnly(bool ReadOnly = true) { if (ReadOnly) this->style |= ES_READONLY; else this->style &= ~ES_READONLY; return this->me(); }
|
|
| 217 |
+ DialogEditBoxBuilder &WithWantReturn(bool WantReturn = true) { if (WantReturn) this->style |= ES_WANTRETURN; else this->style &= ~ES_WANTRETURN; return this->me(); }
|
|
| 218 |
+}; |
|
| 219 |
+ |
|
| 220 |
+template<class T> class DialogControlWithLabelBuilder : public DialogInGroupBuilder<T> |
|
| 221 |
+{
|
|
| 222 |
+protected: |
|
| 223 |
+ friend class DialogTemplate; |
|
| 224 |
+ std::wstring label; |
|
| 225 |
+public: |
|
| 226 |
+ DialogControlWithLabelBuilder(DialogControlType Type, const std::wstring &Label) : DialogInGroupBuilder<T>(Type), label(Label) { }
|
|
| 227 |
+}; |
|
| 228 |
+ |
|
| 229 |
+class DialogLabelBuilder : public DialogControlWithLabelBuilder<DialogLabelBuilder> |
|
| 230 |
+{
|
|
| 231 |
+protected: |
|
| 232 |
+ friend class DialogTemplate; |
|
| 233 |
+public: |
|
| 234 |
+ DialogLabelBuilder(const std::wstring &Label) : DialogControlWithLabelBuilder(LABEL_CONTROL, Label) { }
|
|
| 235 |
+ DialogLabelBuilder &IsLeftJustified(bool WithWordWrap = false) |
|
| 236 |
+ {
|
|
| 237 |
+ this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); |
|
| 238 |
+ if (WithWordWrap) |
|
| 239 |
+ this->style |= SS_LEFTNOWORDWRAP; |
|
| 240 |
+ else |
|
| 241 |
+ this->style |= SS_LEFT; |
|
| 242 |
+ return this->me(); |
|
| 243 |
+ } |
|
| 244 |
+ DialogLabelBuilder &IsCenterJustified() { this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); this->style |= SS_CENTER; return this->me(); }
|
|
| 245 |
+ DialogLabelBuilder &IsRightJustified() { this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); this->style |= SS_RIGHT; return this->me(); }
|
|
| 246 |
+ DialogLabelBuilder &WithAmpsNotTranslated(bool AmpsNotTranslated = true) { if (AmpsNotTranslated) this->style |= SS_NOPREFIX; else this->style &= ~SS_NOPREFIX; return this->me(); }
|
|
| 247 |
+#if WINVER >= 0x0400 |
|
| 248 |
+ DialogLabelBuilder &WithNotify(bool Notify = true) { if (Notify) this->style |= SS_NOTIFY; else this->style &= ~SS_NOTIFY; return this->me(); }
|
|
| 249 |
+#endif |
|
| 250 |
+}; |
|
| 251 |
+ |
|
| 252 |
+template<class T> class DialogButtonBaseBuilder : public DialogControlWithLabelBuilder<T> |
|
| 253 |
+{
|
|
| 254 |
+protected: |
|
| 255 |
+ friend class DialogTemplate; |
|
| 256 |
+public: |
|
| 257 |
+ DialogButtonBaseBuilder(DialogControlType Type, const std::wstring &Label) : DialogControlWithLabelBuilder<T>(Type, Label) { }
|
|
| 258 |
+#if WINVER >= 0x0400 |
|
| 259 |
+ T &IsLeftJustified(bool LeftJustified = true) |
|
| 260 |
+ {
|
|
| 261 |
+ if (LeftJustified) |
|
| 262 |
+ {
|
|
| 263 |
+ this->style |= BS_LEFT; |
|
| 264 |
+ this->style &= ~BS_RIGHT; |
|
| 265 |
+ } |
|
| 266 |
+ else |
|
| 267 |
+ this->style &= ~BS_LEFT; |
|
| 268 |
+ return this->me(); |
|
| 269 |
+ } |
|
| 270 |
+ T &IsRightJustified(bool RightJustified = true) |
|
| 271 |
+ {
|
|
| 272 |
+ if (RightJustified) |
|
| 273 |
+ {
|
|
| 274 |
+ this->style |= BS_RIGHT; |
|
| 275 |
+ this->style &= ~BS_LEFT; |
|
| 276 |
+ } |
|
| 277 |
+ else |
|
| 278 |
+ this->style &= ~BS_RIGHT; |
|
| 279 |
+ return this->me(); |
|
| 280 |
+ } |
|
| 281 |
+ T &IsCenterJustified(bool CenterJustified = true) { if (CenterJustified) this->style |= BS_CENTER; else this->style &= ~BS_CENTER; return this->me(); }
|
|
| 282 |
+ T &WithVerticalTop(bool VerticalTop = true) |
|
| 283 |
+ {
|
|
| 284 |
+ if (VerticalTop) |
|
| 285 |
+ {
|
|
| 286 |
+ this->style |= BS_TOP; |
|
| 287 |
+ this->style &= ~BS_BOTTOM; |
|
| 288 |
+ } |
|
| 289 |
+ else |
|
| 290 |
+ this->style &= ~BS_TOP; |
|
| 291 |
+ return this->me(); |
|
| 292 |
+ } |
|
| 293 |
+ T &WithVerticalBottom(bool VerticalBottom = true) |
|
| 294 |
+ {
|
|
| 295 |
+ if (VerticalBottom) |
|
| 296 |
+ {
|
|
| 297 |
+ this->style |= BS_BOTTOM; |
|
| 298 |
+ this->style &= ~BS_TOP; |
|
| 299 |
+ } |
|
| 300 |
+ else |
|
| 301 |
+ this->style &= ~BS_BOTTOM; |
|
| 302 |
+ return this->me(); |
|
| 303 |
+ } |
|
| 304 |
+ T &WithVerticalCenter(bool VerticalCenter = true) { if (VerticalCenter) this->style |= BS_VCENTER; else this->style &= ~BS_VCENTER; return this->me(); }
|
|
| 305 |
+ T &IsMultiline(bool Multiline = true) { if (Multiline) this->style |= BS_MULTILINE; else this->style &= ~BS_MULTILINE; return this->me(); }
|
|
| 306 |
+ T &WithNotify(bool Notify = true) { if (Notify) this->style |= BS_NOTIFY; else this->style &= ~BS_NOTIFY; return this->me(); }
|
|
| 307 |
+ T &IsFlat(bool Flat = true) { if (Flat) this->style |= BS_FLAT; else this->style &= ~BS_FLAT; return this->me(); }
|
|
| 308 |
+#endif |
|
| 309 |
+}; |
|
| 310 |
+ |
|
| 311 |
+class DialogButtonBuilder : public DialogButtonBaseBuilder<DialogButtonBuilder> |
|
| 312 |
+{
|
|
| 313 |
+protected: |
|
| 314 |
+ friend class DialogTemplate; |
|
| 315 |
+public: |
|
| 316 |
+ DialogButtonBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(BUTTON_CONTROL, Label) { }
|
|
| 317 |
+ DialogButtonBuilder &IsDefault(bool Default = true) { if (Default) this->style |= BS_DEFPUSHBUTTON; else this->style &= ~BS_DEFPUSHBUTTON; return this->me(); }
|
|
| 318 |
+}; |
|
| 319 |
+ |
|
| 320 |
+class DialogCheckBoxBuilder : public DialogButtonBaseBuilder<DialogCheckBoxBuilder> |
|
| 321 |
+{
|
|
| 322 |
+protected: |
|
| 323 |
+ friend class DialogTemplate; |
|
| 324 |
+public: |
|
| 325 |
+ DialogCheckBoxBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(CHECKBOX_CONTROL, Label) { this->style |= BS_AUTOCHECKBOX; }
|
|
| 326 |
+ DialogCheckBoxBuilder &WithTextOnLeft(bool TextOnLeft = true) { if (TextOnLeft) this->style |= BS_LEFTTEXT; else this->style &= ~BS_LEFTTEXT; return this->me(); }
|
|
| 327 |
+ DialogCheckBoxBuilder &LikePushButton(bool PushButton = true) { if (PushButton) this->style |= BS_PUSHLIKE; else this->style &= ~BS_PUSHLIKE; return this->me(); }
|
|
| 328 |
+}; |
|
| 329 |
+ |
|
| 330 |
+class DialogListBoxBuilder : public DialogInGroupBuilder<DialogListBoxBuilder> |
|
| 331 |
+{
|
|
| 332 |
+protected: |
|
| 333 |
+ friend class DialogTemplate; |
|
| 334 |
+public: |
|
| 335 |
+ DialogListBoxBuilder() : DialogInGroupBuilder(LISTBOX_CONTROL) { }
|
|
| 336 |
+ DialogListBoxBuilder &WithNotify(bool Notify = true) { if (Notify) this->style |= LBS_NOTIFY; else this->style &= ~LBS_NOTIFY; return this->me(); }
|
|
| 337 |
+ DialogListBoxBuilder &WithSort(bool Sort = true) { if (Sort) this->style |= LBS_SORT; else this->style &= ~LBS_SORT; return this->me(); }
|
|
| 338 |
+ DialogListBoxBuilder &WithMultipleSelect(bool MultipleSelect = true) { if (MultipleSelect) this->style |= LBS_MULTIPLESEL; else this->style &= ~LBS_MULTIPLESEL; return this->me(); }
|
|
| 339 |
+ DialogListBoxBuilder &WithExactHeight(bool ExactHeight = true) { if (ExactHeight) this->style |= LBS_NOINTEGRALHEIGHT; else this->style &= ~LBS_NOINTEGRALHEIGHT; return this->me(); }
|
|
| 340 |
+ DialogListBoxBuilder &WithMultipleColumns(bool MultipleColumns = true) { if (MultipleColumns) this->style |= LBS_MULTICOLUMN; else this->style &= ~LBS_MULTICOLUMN; return this->me(); }
|
|
| 341 |
+ DialogListBoxBuilder &WithExtendedSelect(bool ExtendedSelect = true) { if (ExtendedSelect) this->style |= LBS_EXTENDEDSEL; else this->style &= ~LBS_EXTENDEDSEL; return this->me(); }
|
|
| 342 |
+ DialogListBoxBuilder &WithDisabledNoScroll(bool DisabledNoScroll = true) { if (DisabledNoScroll) this->style |= LBS_DISABLENOSCROLL; else this->style &= ~LBS_DISABLENOSCROLL; return this->me(); }
|
|
| 343 |
+#if WINVER >= 0x0400 |
|
| 344 |
+ DialogListBoxBuilder &WithNoSelect(bool NoSelect = true) { if (NoSelect) this->style |= LBS_NOSEL; else this->style &= ~LBS_NOSEL; return this->me(); }
|
|
| 345 |
+#endif |
|
| 346 |
+}; |
|
| 347 |
+ |
|
| 348 |
+class DialogComboBoxBuilder : public DialogInGroupBuilder<DialogComboBoxBuilder> |
|
| 349 |
+{
|
|
| 350 |
+protected: |
|
| 351 |
+ friend class DialogTemplate; |
|
| 352 |
+public: |
|
| 353 |
+ DialogComboBoxBuilder() : DialogInGroupBuilder(COMBOBOX_CONTROL) { }
|
|
| 354 |
+ DialogComboBoxBuilder &IsSimple() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_SIMPLE; return this->me(); }
|
|
| 355 |
+ DialogComboBoxBuilder &IsDropDown() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_DROPDOWN; return this->me(); }
|
|
| 356 |
+ DialogComboBoxBuilder &IsDropDownList() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_DROPDOWNLIST; return this->me(); }
|
|
| 357 |
+ DialogComboBoxBuilder &WithAutoHScroll(bool AutoHScroll = true) { if (AutoHScroll) this->style |= CBS_AUTOHSCROLL; else this->style &= ~CBS_AUTOHSCROLL; return this->me(); }
|
|
| 358 |
+ DialogComboBoxBuilder &WithSort(bool Sort = true) { if (Sort) this->style |= CBS_SORT; else this->style &= ~CBS_SORT; return this->me(); }
|
|
| 359 |
+ DialogComboBoxBuilder &WithExactHeight(bool ExactHeight = true) { if (ExactHeight) this->style |= CBS_NOINTEGRALHEIGHT; else this->style &= ~CBS_NOINTEGRALHEIGHT; return this->me(); }
|
|
| 360 |
+ DialogComboBoxBuilder &WithDisabledNoScroll(bool DisabledNoScroll = true) { if (DisabledNoScroll) this->style |= CBS_DISABLENOSCROLL; else this->style &= ~CBS_DISABLENOSCROLL; return this->me(); }
|
|
| 361 |
+#if WINVER >= 0x0400 |
|
| 362 |
+ DialogComboBoxBuilder &WithAllLowercase(bool AllLowercase = true) { if (AllLowercase) this->style |= CBS_LOWERCASE; else this->style &= ~CBS_LOWERCASE; return this->me(); }
|
|
| 363 |
+ DialogComboBoxBuilder &WithAllUppercase(bool AllUppercase = true) { if (AllUppercase) this->style |= CBS_UPPERCASE; else this->style &= ~CBS_UPPERCASE; return this->me(); }
|
|
| 364 |
+#endif |
|
| 365 |
+}; |
|
| 366 |
+ |
|
| 367 |
+class DialogTemplate |
|
| 368 |
+{
|
|
| 369 |
+ class DialogControl; |
|
| 370 |
+ |
|
| 371 |
+ typedef std::vector<std::unique_ptr<DialogControl>> Controls; |
|
| 372 |
+ |
|
| 373 |
+ class DialogControl |
|
| 374 |
+ {
|
|
| 375 |
+ protected: |
|
| 376 |
+ DialogControlType controlType; |
|
| 377 |
+ uint32_t style, exstyle; |
|
| 378 |
+ Rect<short> rect; |
|
| 379 |
+ short id; |
|
| 380 |
+ std::unique_ptr<RelativePosition> relativePosition; |
|
| 381 |
+ |
|
| 382 |
+ friend class DialogTemplate; |
|
| 383 |
+ DialogControl() : controlType(NO_CONTROL), style(0), exstyle(0), rect(), id(-1), relativePosition() { }
|
|
| 384 |
+ DialogControl(const DialogControl &control) : controlType(control.controlType), style(control.style), exstyle(control.exstyle), rect(control.rect), id(control.id), |
|
| 385 |
+ relativePosition(control.relativePosition ? control.relativePosition->Clone() : nullptr) { }
|
|
| 386 |
+ DialogControl &operator=(const DialogControl &control) |
|
| 387 |
+ {
|
|
| 388 |
+ this->controlType = control.controlType; |
|
| 389 |
+ this->style = control.style; |
|
| 390 |
+ this->exstyle = control.exstyle; |
|
| 391 |
+ this->rect = control.rect; |
|
| 392 |
+ this->id = control.id; |
|
| 393 |
+ if (control.relativePosition) |
|
| 394 |
+ this->relativePosition.reset(control.relativePosition->Clone()); |
|
| 395 |
+ else |
|
| 396 |
+ this->relativePosition.reset(); |
|
| 397 |
+ |
|
| 398 |
+ return *this; |
|
| 399 |
+ } |
|
| 400 |
+ public: |
|
| 401 |
+ virtual ~DialogControl() { }
|
|
| 402 |
+ template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder) |
|
| 403 |
+ {
|
|
| 404 |
+ auto control = std::unique_ptr<Control>(new Control()); |
|
| 405 |
+ |
|
| 406 |
+ control->controlType = builder.controlType; |
|
| 407 |
+ control->style = builder.style; |
|
| 408 |
+ control->exstyle = builder.exstyle; |
|
| 409 |
+ control->rect = builder.rect; |
|
| 410 |
+ control->id = builder.id; |
|
| 411 |
+ if (builder.relativePosition) |
|
| 412 |
+ control->relativePosition.reset(builder.relativePosition->Clone()); |
|
| 413 |
+ |
|
| 414 |
+ return control; |
|
| 415 |
+ } |
|
| 416 |
+ virtual uint16_t GetControlCount() const { return 1; }
|
|
| 417 |
+ virtual short GetControlHeight() const { return this->rect.size.height; }
|
|
| 418 |
+ virtual std::vector<uint8_t> GenerateControlTemplate() const = 0; |
|
| 419 |
+ virtual DialogControl *Clone() const = 0; |
|
| 420 |
+ }; |
|
| 421 |
+ |
|
| 422 |
+ class DialogGroup : public DialogControl |
|
| 423 |
+ {
|
|
| 424 |
+ protected: |
|
| 425 |
+ DialogTemplate::Controls controls; |
|
| 426 |
+ std::wstring groupName; |
|
| 427 |
+ |
|
| 428 |
+ friend class DialogTemplate; |
|
| 429 |
+ friend class DialogControl; |
|
| 430 |
+ DialogGroup() : DialogControl(), controls(), groupName(L"") { }
|
|
| 431 |
+ DialogGroup(const DialogGroup &control) : DialogControl(control), controls(), groupName(control.groupName) |
|
| 432 |
+ {
|
|
| 433 |
+ std::for_each(control.controls.begin(), control.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
|
|
| 434 |
+ } |
|
| 435 |
+ DialogGroup &operator=(const DialogGroup &control) |
|
| 436 |
+ {
|
|
| 437 |
+ DialogControl::operator=(control); |
|
| 438 |
+ |
|
| 439 |
+ this->controls.clear(); |
|
| 440 |
+ std::for_each(control.controls.begin(), control.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
|
|
| 441 |
+ |
|
| 442 |
+ this->groupName = control.groupName; |
|
| 443 |
+ |
|
| 444 |
+ return *this; |
|
| 445 |
+ } |
|
| 446 |
+ public: |
|
| 447 |
+ static std::unique_ptr<DialogGroup> CreateControl(const DialogControlBuilder<DialogGroupBuilder> &builder) |
|
| 448 |
+ {
|
|
| 449 |
+ auto control = DialogControl::CreateControl<DialogGroup>(builder); |
|
| 450 |
+ |
|
| 451 |
+ control->groupName = dynamic_cast<const DialogGroupBuilder &>(builder).groupName; |
|
| 452 |
+ |
|
| 453 |
+ return control; |
|
| 454 |
+ } |
|
| 455 |
+ void CalculatePositions(bool doRightAndBottom = false); |
|
| 456 |
+ void CalculateSize(); |
|
| 457 |
+ uint16_t GetControlCount() const; |
|
| 458 |
+ std::vector<uint8_t> GenerateControlTemplate() const; |
|
| 459 |
+ DialogGroup *Clone() const { return new DialogGroup(*this); }
|
|
| 460 |
+ }; |
|
| 461 |
+ |
|
| 462 |
+ class DialogControlWithoutLabel : public DialogControl |
|
| 463 |
+ {
|
|
| 464 |
+ protected: |
|
| 465 |
+ uint16_t type; |
|
| 466 |
+ |
|
| 467 |
+ friend class DialogTemplate; |
|
| 468 |
+ friend class DialogControl; |
|
| 469 |
+ DialogControlWithoutLabel() : DialogControl(), type(0) { }
|
|
| 470 |
+ DialogControlWithoutLabel(const DialogControlWithoutLabel &control) : DialogControl(control), type(control.type) { }
|
|
| 471 |
+ DialogControlWithoutLabel &operator=(const DialogControlWithoutLabel &control) |
|
| 472 |
+ {
|
|
| 473 |
+ DialogControl::operator=(control); |
|
| 474 |
+ |
|
| 475 |
+ this->type = control.type; |
|
| 476 |
+ |
|
| 477 |
+ return *this; |
|
| 478 |
+ } |
|
| 479 |
+ public: |
|
| 480 |
+ template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type) |
|
| 481 |
+ {
|
|
| 482 |
+ auto control = DialogControl::CreateControl<Control>(builder); |
|
| 483 |
+ |
|
| 484 |
+ control->type = Type; |
|
| 485 |
+ |
|
| 486 |
+ return control; |
|
| 487 |
+ } |
|
| 488 |
+ virtual std::vector<uint8_t> GenerateControlTemplate() const; |
|
| 489 |
+ virtual DialogControlWithoutLabel *Clone() const { return new DialogControlWithoutLabel(*this); }
|
|
| 490 |
+ }; |
|
| 491 |
+ |
|
| 492 |
+ class DialogControlWithLabel : public DialogControl |
|
| 493 |
+ {
|
|
| 494 |
+ protected: |
|
| 495 |
+ uint16_t type; |
|
| 496 |
+ std::wstring label; |
|
| 497 |
+ |
|
| 498 |
+ friend class DialogTemplate; |
|
| 499 |
+ friend class DialogControl; |
|
| 500 |
+ DialogControlWithLabel() : DialogControl(), type(0), label(L"") { }
|
|
| 501 |
+ DialogControlWithLabel(const DialogControlWithLabel &control) : DialogControl(control), type(control.type), label(control.label) { }
|
|
| 502 |
+ DialogControlWithLabel &operator=(const DialogControlWithLabel &control) |
|
| 503 |
+ {
|
|
| 504 |
+ DialogControl::operator=(control); |
|
| 505 |
+ |
|
| 506 |
+ this->type = control.type; |
|
| 507 |
+ this->label = control.label; |
|
| 508 |
+ |
|
| 509 |
+ return *this; |
|
| 510 |
+ } |
|
| 511 |
+ public: |
|
| 512 |
+ template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type) |
|
| 513 |
+ {
|
|
| 514 |
+ auto control = DialogControl::CreateControl<Control>(builder); |
|
| 515 |
+ |
|
| 516 |
+ control->type = Type; |
|
| 517 |
+ control->label = dynamic_cast<const DialogControlWithLabelBuilder<Builder> &>(builder).label; |
|
| 518 |
+ |
|
| 519 |
+ return control; |
|
| 520 |
+ } |
|
| 521 |
+ virtual std::vector<uint8_t> GenerateControlTemplate() const; |
|
| 522 |
+ virtual DialogControlWithLabel *Clone() const { return new DialogControlWithLabel(*this); }
|
|
| 523 |
+ }; |
|
| 524 |
+ |
|
| 525 |
+ class DialogEditBox : public DialogControlWithoutLabel |
|
| 526 |
+ {
|
|
| 527 |
+ protected: |
|
| 528 |
+ friend class DialogTemplate; |
|
| 529 |
+ friend class DialogControl; |
|
| 530 |
+ DialogEditBox() : DialogControlWithoutLabel() { }
|
|
| 531 |
+ public: |
|
| 532 |
+ static std::unique_ptr<DialogEditBox> CreateControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder) |
|
| 533 |
+ {
|
|
| 534 |
+ return DialogControlWithoutLabel::CreateControl<DialogEditBox>(builder, 0x0081); |
|
| 535 |
+ } |
|
| 536 |
+ }; |
|
| 537 |
+ |
|
| 538 |
+ class DialogLabel : public DialogControlWithLabel |
|
| 539 |
+ {
|
|
| 540 |
+ protected: |
|
| 541 |
+ friend class DialogTemplate; |
|
| 542 |
+ friend class DialogControl; |
|
| 543 |
+ DialogLabel() : DialogControlWithLabel() { }
|
|
| 544 |
+ public: |
|
| 545 |
+ static std::unique_ptr<DialogLabel> CreateControl(const DialogControlBuilder<DialogLabelBuilder> &builder) |
|
| 546 |
+ {
|
|
| 547 |
+ return DialogControlWithLabel::CreateControl<DialogLabel>(builder, 0x0082); |
|
| 548 |
+ } |
|
| 549 |
+ }; |
|
| 550 |
+ |
|
| 551 |
+ class DialogButton : public DialogControlWithLabel |
|
| 552 |
+ {
|
|
| 553 |
+ protected: |
|
| 554 |
+ friend class DialogTemplate; |
|
| 555 |
+ friend class DialogControl; |
|
| 556 |
+ DialogButton() : DialogControlWithLabel() { }
|
|
| 557 |
+ public: |
|
| 558 |
+ template<typename Builder> static std::unique_ptr<DialogButton> CreateControl(const DialogControlBuilder<Builder> &builder) |
|
| 559 |
+ {
|
|
| 560 |
+ return DialogControlWithLabel::CreateControl<DialogButton>(builder, 0x0080); |
|
| 561 |
+ } |
|
| 562 |
+ }; |
|
| 563 |
+ |
|
| 564 |
+ class DialogListBox : public DialogControlWithoutLabel |
|
| 565 |
+ {
|
|
| 566 |
+ protected: |
|
| 567 |
+ friend class DialogTemplate; |
|
| 568 |
+ friend class DialogControl; |
|
| 569 |
+ DialogListBox() : DialogControlWithoutLabel() { }
|
|
| 570 |
+ public: |
|
| 571 |
+ static std::unique_ptr<DialogListBox> CreateControl(const DialogControlBuilder<DialogListBoxBuilder> &builder) |
|
| 572 |
+ {
|
|
| 573 |
+ return DialogControlWithoutLabel::CreateControl<DialogListBox>(builder, 0x0083); |
|
| 574 |
+ } |
|
| 575 |
+ }; |
|
| 576 |
+ |
|
| 577 |
+ class DialogComboBox : public DialogControlWithoutLabel |
|
| 578 |
+ {
|
|
| 579 |
+ protected: |
|
| 580 |
+ friend class DialogTemplate; |
|
| 581 |
+ friend class DialogControl; |
|
| 582 |
+ DialogComboBox() : DialogControlWithoutLabel() { }
|
|
| 583 |
+ public: |
|
| 584 |
+ static std::unique_ptr<DialogComboBox> CreateControl(const DialogControlBuilder<DialogComboBoxBuilder> &builder) |
|
| 585 |
+ {
|
|
| 586 |
+ return DialogControlWithoutLabel::CreateControl<DialogComboBox>(builder, 0x0085); |
|
| 587 |
+ } |
|
| 588 |
+ short GetControlHeight() const { return (this->style & CBS_SIMPLE && !(this->style & CBS_DROPDOWNLIST)) ? this->rect.size.height : 14; }
|
|
| 589 |
+ }; |
|
| 590 |
+ |
|
| 591 |
+ std::wstring title; |
|
| 592 |
+ uint32_t style, exstyle; |
|
| 593 |
+ std::wstring fontName; |
|
| 594 |
+ uint16_t fontSizeInPts; |
|
| 595 |
+ Size<short> size; |
|
| 596 |
+ DialogTemplate::Controls controls; |
|
| 597 |
+ std::vector<uint8_t> templateData; |
|
| 598 |
+ |
|
| 599 |
+ template<typename Builder> void AddControlToGroup(std::unique_ptr<DialogControl> &&control, const DialogControlBuilder<Builder> &builder) |
|
| 600 |
+ {
|
|
| 601 |
+ const auto &groupBuilder = dynamic_cast<const DialogInGroupBuilder<Builder> &>(builder); |
|
| 602 |
+ if (groupBuilder.groupName.empty()) |
|
| 603 |
+ {
|
|
| 604 |
+ if (builder.index == -1) |
|
| 605 |
+ this->controls.push_back(std::move(control)); |
|
| 606 |
+ else |
|
| 607 |
+ this->controls.insert(this->controls.begin() + builder.index, std::move(control)); |
|
| 608 |
+ } |
|
| 609 |
+ else |
|
| 610 |
+ {
|
|
| 611 |
+ for (auto curr = this->controls.begin(), end = this->controls.end(); curr != end; ++curr) |
|
| 612 |
+ {
|
|
| 613 |
+ if ((*curr)->controlType != GROUP_CONTROL) |
|
| 614 |
+ continue; |
|
| 615 |
+ DialogGroup *group = dynamic_cast<DialogGroup *>(curr->get()); |
|
| 616 |
+ if (group->groupName == groupBuilder.groupName) |
|
| 617 |
+ {
|
|
| 618 |
+ if (builder.index == -1) |
|
| 619 |
+ group->controls.push_back(std::move(control)); |
|
| 620 |
+ else |
|
| 621 |
+ group->controls.insert(group->controls.begin() + builder.index, std::move(control)); |
|
| 622 |
+ return; |
|
| 623 |
+ } |
|
| 624 |
+ } |
|
| 625 |
+ throw std::runtime_error("Group " + UtfConverter::ToUtf8(groupBuilder.groupName) + " was not found.");
|
|
| 626 |
+ } |
|
| 627 |
+ } |
|
| 628 |
+ uint16_t GetTotalControlCount() const; |
|
| 629 |
+ bool CalculateControlPosition(short index, bool doRightAndBottom = false); |
|
| 630 |
+ void CalculateSize(); |
|
| 631 |
+public: |
|
| 632 |
+ DialogTemplate() : title(L""), style(0), exstyle(0), fontName(L""), fontSizeInPts(0), size(), controls(), templateData() { }
|
|
| 633 |
+ DialogTemplate(const DialogBuilder &builder) : title(builder.title), style(builder.style), exstyle(builder.exstyle), fontName(builder.fontName), fontSizeInPts(builder.fontSizeInPts), |
|
| 634 |
+ size(builder.size), controls(), templateData() { }
|
|
| 635 |
+ DialogTemplate(const DialogTemplate &dlg) : title(dlg.title), style(dlg.style), exstyle(dlg.style), fontName(dlg.fontName), fontSizeInPts(dlg.fontSizeInPts), size(dlg.size), |
|
| 636 |
+ controls(), templateData() |
|
| 637 |
+ {
|
|
| 638 |
+ std::for_each(dlg.controls.begin(), dlg.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
|
|
| 639 |
+ } |
|
| 640 |
+ DialogTemplate &operator=(const DialogBuilder &builder) |
|
| 641 |
+ {
|
|
| 642 |
+ this->title = builder.title; |
|
| 643 |
+ this->style = builder.style; |
|
| 644 |
+ this->exstyle = builder.exstyle; |
|
| 645 |
+ this->fontName = builder.fontName; |
|
| 646 |
+ this->fontSizeInPts = builder.fontSizeInPts; |
|
| 647 |
+ this->size = builder.size; |
|
| 648 |
+ if (builder.resetControls) |
|
| 649 |
+ this->controls.clear(); |
|
| 650 |
+ |
|
| 651 |
+ return *this; |
|
| 652 |
+ } |
|
| 653 |
+ DialogTemplate &operator=(const DialogTemplate &dlg) |
|
| 654 |
+ {
|
|
| 655 |
+ this->title = dlg.title; |
|
| 656 |
+ this->style = dlg.style; |
|
| 657 |
+ this->exstyle = dlg.exstyle; |
|
| 658 |
+ this->fontName = dlg.fontName; |
|
| 659 |
+ this->fontSizeInPts = dlg.fontSizeInPts; |
|
| 660 |
+ this->size = dlg.size; |
|
| 661 |
+ this->controls.clear(); |
|
| 662 |
+ std::for_each(dlg.controls.begin(), dlg.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
|
|
| 663 |
+ |
|
| 664 |
+ return *this; |
|
| 665 |
+ } |
|
| 666 |
+ void AddGroupControl(const DialogControlBuilder<DialogGroupBuilder> &builder); |
|
| 667 |
+ void AddEditBoxControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder); |
|
| 668 |
+ void AddLabelControl(const DialogControlBuilder<DialogLabelBuilder> &builder); |
|
| 669 |
+ void AddCheckBoxControl(const DialogControlBuilder<DialogCheckBoxBuilder> &builder); |
|
| 670 |
+ void AddButtonControl(const DialogControlBuilder<DialogButtonBuilder> &builder); |
|
| 671 |
+ void AddListBoxControl(const DialogControlBuilder<DialogListBoxBuilder> &builder); |
|
| 672 |
+ void AddComboBoxControl(const DialogControlBuilder<DialogComboBoxBuilder> &builder); |
|
| 673 |
+ void AutoSize(); |
|
| 674 |
+ const DLGTEMPLATE *GenerateTemplate(); |
|
| 675 |
+}; |
|
| 676 |
+ |
|
| 677 |
+#endif |
| ... | ... |
@@ -45,7 +45,7 @@ |
| 45 | 45 |
<WarningLevel>Level4</WarningLevel> |
| 46 | 46 |
<Optimization>Disabled</Optimization> |
| 47 | 47 |
<PreprocessorDefinitions>WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;UNICODE_INPUT_PLUGIN;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| 48 |
- <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 48 |
+ <AdditionalIncludeDirectories>$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 49 | 49 |
<DisableSpecificWarnings>4127;4244;4512;%(DisableSpecificWarnings)</DisableSpecificWarnings> |
| 50 | 50 |
</ClCompile> |
| 51 | 51 |
<Link> |
| ... | ... |
@@ -60,7 +60,7 @@ |
| 60 | 60 |
<FunctionLevelLinking>true</FunctionLevelLinking> |
| 61 | 61 |
<IntrinsicFunctions>true</IntrinsicFunctions> |
| 62 | 62 |
<PreprocessorDefinitions>WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;UNICODE_INPUT_PLUGIN;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| 63 |
- <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 63 |
+ <AdditionalIncludeDirectories>$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
|
| 64 | 64 |
<DisableSpecificWarnings>4127;4244;4512;%(DisableSpecificWarnings)</DisableSpecificWarnings> |
| 65 | 65 |
</ClCompile> |
| 66 | 66 |
<Link> |