* [2SF] Used more up-to-date asmjit, despite the ugly looking code.
| 1 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,677 +0,0 @@ |
| 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 |
| 1 | 1 |
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 |