| ... | ... |
@@ -72,7 +72,7 @@ class RelativePositionToParent : public RelativePosition |
| 72 | 72 |
{
|
| 73 | 73 |
public: |
| 74 | 74 |
RelativePositionToParent(const Point<short> &RelPosition, PositionType PosType) : RelativePosition(RelPosition, BaseType::ToParent, PosType) { }
|
| 75 |
- RelativePositionToParent *Clone() const { return new RelativePositionToParent(this->relativePosition, this->positionType); }
|
|
| 75 |
+ RelativePositionToParent *Clone() const override { return new RelativePositionToParent(this->relativePosition, this->positionType); }
|
|
| 76 | 76 |
}; |
| 77 | 77 |
|
| 78 | 78 |
class RelativePositionToSibling : public RelativePosition |
| ... | ... |
@@ -81,7 +81,7 @@ public: |
| 81 | 81 |
short siblingsBack; |
| 82 | 82 |
|
| 83 | 83 |
RelativePositionToSibling(const Point<short> &RelPosition, PositionType PosType, short SiblingsBack = 1) : RelativePosition(RelPosition, BaseType::ToSibling, PosType), siblingsBack(SiblingsBack) { }
|
| 84 |
- RelativePositionToSibling *Clone() const { return new RelativePositionToSibling(this->relativePosition, this->positionType, this->siblingsBack); }
|
|
| 84 |
+ RelativePositionToSibling *Clone() const override { return new RelativePositionToSibling(this->relativePosition, this->positionType, this->siblingsBack); }
|
|
| 85 | 85 |
}; |
| 86 | 86 |
|
| 87 | 87 |
enum class DialogControlType |
| ... | ... |
@@ -453,9 +453,9 @@ class DialogTemplate |
| 453 | 453 |
} |
| 454 | 454 |
void CalculatePositions(bool doRightAndBottom = false); |
| 455 | 455 |
void CalculateSize(); |
| 456 |
- std::uint16_t GetControlCount() const; |
|
| 457 |
- std::vector<std::uint8_t> GenerateControlTemplate() const; |
|
| 458 |
- DialogGroup *Clone() const { return new DialogGroup(*this); }
|
|
| 456 |
+ std::uint16_t GetControlCount() const override; |
|
| 457 |
+ std::vector<std::uint8_t> GenerateControlTemplate() const override; |
|
| 458 |
+ DialogGroup *Clone() const override { return new DialogGroup(*this); }
|
|
| 459 | 459 |
}; |
| 460 | 460 |
|
| 461 | 461 |
class DialogControlWithoutLabel : public DialogControl |
| ... | ... |
@@ -484,8 +484,8 @@ class DialogTemplate |
| 484 | 484 |
|
| 485 | 485 |
return control; |
| 486 | 486 |
} |
| 487 |
- virtual std::vector<std::uint8_t> GenerateControlTemplate() const; |
|
| 488 |
- virtual DialogControlWithoutLabel *Clone() const { return new DialogControlWithoutLabel(*this); }
|
|
| 487 |
+ virtual std::vector<std::uint8_t> GenerateControlTemplate() const override; |
|
| 488 |
+ virtual DialogControlWithoutLabel *Clone() const override{ return new DialogControlWithoutLabel(*this); }
|
|
| 489 | 489 |
}; |
| 490 | 490 |
|
| 491 | 491 |
class DialogControlWithLabel : public DialogControl |
| ... | ... |
@@ -517,8 +517,8 @@ class DialogTemplate |
| 517 | 517 |
|
| 518 | 518 |
return control; |
| 519 | 519 |
} |
| 520 |
- virtual std::vector<std::uint8_t> GenerateControlTemplate() const; |
|
| 521 |
- virtual DialogControlWithLabel *Clone() const { return new DialogControlWithLabel(*this); }
|
|
| 520 |
+ virtual std::vector<std::uint8_t> GenerateControlTemplate() const override; |
|
| 521 |
+ virtual DialogControlWithLabel *Clone() const override { return new DialogControlWithLabel(*this); }
|
|
| 522 | 522 |
}; |
| 523 | 523 |
|
| 524 | 524 |
class DialogEditBox : public DialogControlWithoutLabel |
| ... | ... |
@@ -584,7 +584,7 @@ class DialogTemplate |
| 584 | 584 |
{
|
| 585 | 585 |
return DialogControlWithoutLabel::CreateControl<DialogComboBox>(builder, 0x0085); |
| 586 | 586 |
} |
| 587 |
- short GetControlHeight() const { return (this->style & CBS_SIMPLE && !(this->style & CBS_DROPDOWNLIST)) ? this->rect.size.height : 14; }
|
|
| 587 |
+ short GetControlHeight() const override { return (this->style & CBS_SIMPLE && !(this->style & CBS_DROPDOWNLIST)) ? this->rect.size.height : 14; }
|
|
| 588 | 588 |
}; |
| 589 | 589 |
|
| 590 | 590 |
std::wstring title; |
* Use enum class instead of enum (except for the enums for the resource IDs, not really necessary there).
* For NCSF specifically, included a function to convert an enum class to its underlying integral type (as this is needed for use with the std::bitset class).
* Cleanup headers so all the ones needed in a file are explicitly included even if they may possibly be included in another header.
* Used forward declarations in a few spots.
* Explicitly namespaced all (u)int*_t uses (this might seem like overkill, but it helps me see when the standard types are being used with a simple search for std::).
* Made sure it all builds with MinGW-w64 as well (both gcc and clang).
* Removed some std::move from DialogBuilder.cpp based on clang's warnings for that.
* Replaced use of std::copy_n on strings in DialogBuilder.cpp with my CopyToString functions that use wcscpy.
* Replaced CHAR_MIN/CHAR_MAX in eqstr.h and ltstr.h with std::numeric_limits<char>::min/max().
| ... | ... |
@@ -5,14 +5,15 @@ |
| 5 | 5 |
|
| 6 | 6 |
#pragma once |
| 7 | 7 |
|
| 8 |
-#include <string> |
|
| 9 |
-#include <memory> |
|
| 10 |
-#include <vector> |
|
| 11 | 8 |
#include <algorithm> |
| 9 |
+#include <memory> |
|
| 12 | 10 |
#include <stdexcept> |
| 11 |
+#include <string> |
|
| 12 |
+#include <utility> |
|
| 13 |
+#include <vector> |
|
| 13 | 14 |
#include <cstdint> |
| 14 |
-#include "XSFCommon.h" |
|
| 15 | 15 |
#include "windowsh_wrapper.h" |
| 16 |
+#include "convert.h" |
|
| 16 | 17 |
|
| 17 | 18 |
template<typename T> struct Point |
| 18 | 19 |
{
|
| ... | ... |
@@ -44,21 +45,21 @@ class RelativePosition |
| 44 | 45 |
{
|
| 45 | 46 |
public: |
| 46 | 47 |
Point<short> relativePosition; |
| 47 |
- enum BaseType |
|
| 48 |
+ enum class BaseType |
|
| 48 | 49 |
{
|
| 49 |
- TO_PARENT, |
|
| 50 |
- TO_SIBLING |
|
| 50 |
+ ToParent, |
|
| 51 |
+ ToSibling |
|
| 51 | 52 |
} type; |
| 52 |
- enum PositionType |
|
| 53 |
+ enum class PositionType |
|
| 53 | 54 |
{
|
| 54 |
- FROM_TOP, |
|
| 55 |
- FROM_BOTTOM, |
|
| 56 |
- FROM_LEFT, |
|
| 57 |
- FROM_RIGHT, |
|
| 58 |
- FROM_TOPLEFT, |
|
| 59 |
- FROM_BOTTOMLEFT, |
|
| 60 |
- FROM_TOPRIGHT, |
|
| 61 |
- FROM_BOTTOMRIGHT |
|
| 55 |
+ FromTop, |
|
| 56 |
+ FromBottom, |
|
| 57 |
+ FromLeft, |
|
| 58 |
+ FromRight, |
|
| 59 |
+ FromTopLeft, |
|
| 60 |
+ FromBottomLeft, |
|
| 61 |
+ FromTopRight, |
|
| 62 |
+ FromBottomRight |
|
| 62 | 63 |
} positionType; |
| 63 | 64 |
|
| 64 | 65 |
RelativePosition(const Point<short> &RelPosition, BaseType Type, PositionType PosType) : relativePosition(RelPosition), type(Type), positionType(PosType) { }
|
| ... | ... |
@@ -70,7 +71,7 @@ public: |
| 70 | 71 |
class RelativePositionToParent : public RelativePosition |
| 71 | 72 |
{
|
| 72 | 73 |
public: |
| 73 |
- RelativePositionToParent(const Point<short> &RelPosition, PositionType PosType) : RelativePosition(RelPosition, TO_PARENT, PosType) { }
|
|
| 74 |
+ RelativePositionToParent(const Point<short> &RelPosition, PositionType PosType) : RelativePosition(RelPosition, BaseType::ToParent, PosType) { }
|
|
| 74 | 75 |
RelativePositionToParent *Clone() const { return new RelativePositionToParent(this->relativePosition, this->positionType); }
|
| 75 | 76 |
}; |
| 76 | 77 |
|
| ... | ... |
@@ -79,20 +80,20 @@ class RelativePositionToSibling : public RelativePosition |
| 79 | 80 |
public: |
| 80 | 81 |
short siblingsBack; |
| 81 | 82 |
|
| 82 |
- RelativePositionToSibling(const Point<short> &RelPosition, PositionType PosType, short SiblingsBack = 1) : RelativePosition(RelPosition, TO_SIBLING, PosType), siblingsBack(SiblingsBack) { }
|
|
| 83 |
+ RelativePositionToSibling(const Point<short> &RelPosition, PositionType PosType, short SiblingsBack = 1) : RelativePosition(RelPosition, BaseType::ToSibling, PosType), siblingsBack(SiblingsBack) { }
|
|
| 83 | 84 |
RelativePositionToSibling *Clone() const { return new RelativePositionToSibling(this->relativePosition, this->positionType, this->siblingsBack); }
|
| 84 | 85 |
}; |
| 85 | 86 |
|
| 86 |
-enum DialogControlType |
|
| 87 |
+enum class DialogControlType |
|
| 87 | 88 |
{
|
| 88 |
- NO_CONTROL, |
|
| 89 |
- GROUP_CONTROL, |
|
| 90 |
- EDITBOX_CONTROL, |
|
| 91 |
- LABEL_CONTROL, |
|
| 92 |
- CHECKBOX_CONTROL, |
|
| 93 |
- BUTTON_CONTROL, |
|
| 94 |
- LISTBOX_CONTROL, |
|
| 95 |
- COMBOBOX_CONTROL |
|
| 89 |
+ None, |
|
| 90 |
+ Group, |
|
| 91 |
+ EditBox, |
|
| 92 |
+ Label, |
|
| 93 |
+ CheckBox, |
|
| 94 |
+ Button, |
|
| 95 |
+ ListBox, |
|
| 96 |
+ ComboBox |
|
| 96 | 97 |
}; |
| 97 | 98 |
|
| 98 | 99 |
class DialogTemplate; |
| ... | ... |
@@ -102,14 +103,14 @@ class DialogBuilder |
| 102 | 103 |
protected: |
| 103 | 104 |
friend class DialogTemplate; |
| 104 | 105 |
std::wstring title, fontName; |
| 105 |
- uint32_t style, exstyle; |
|
| 106 |
- uint16_t fontSizeInPts; |
|
| 106 |
+ std::uint32_t style, exstyle; |
|
| 107 |
+ std::uint16_t fontSizeInPts; |
|
| 107 | 108 |
Size<short> size; |
| 108 | 109 |
bool resetControls; |
| 109 | 110 |
public: |
| 110 | 111 |
DialogBuilder() : title(L""), fontName(L""), style(0), exstyle(0), fontSizeInPts(0), size(), resetControls(false) { }
|
| 111 | 112 |
DialogBuilder &WithTitle(const std::wstring &Title) { this->title = Title; return *this; }
|
| 112 |
- DialogBuilder &WithFont(const std::wstring &FontName, uint16_t FontSizeInPts) { this->fontName = FontName; this->fontSizeInPts = FontSizeInPts; return *this; }
|
|
| 113 |
+ DialogBuilder &WithFont(const std::wstring &FontName, std::uint16_t FontSizeInPts) { this->fontName = FontName; this->fontSizeInPts = FontSizeInPts; return *this; }
|
|
| 113 | 114 |
DialogBuilder &WithSize(short Width, short Height) { this->size.width = Width; this->size.height = Height; return *this; }
|
| 114 | 115 |
DialogBuilder &WithSize(const Size<short> &Sz) { this->size = Sz; return *this; }
|
| 115 | 116 |
DialogBuilder &ResetControls(bool Reset = true) { this->resetControls = Reset; return *this; }
|
| ... | ... |
@@ -139,7 +140,7 @@ template<class T> class DialogControlBuilder |
| 139 | 140 |
protected: |
| 140 | 141 |
friend class DialogTemplate; |
| 141 | 142 |
DialogControlType controlType; |
| 142 |
- uint32_t style, exstyle; |
|
| 143 |
+ std::uint32_t style, exstyle; |
|
| 143 | 144 |
Rect<short> rect; |
| 144 | 145 |
short id; |
| 145 | 146 |
int index; |
| ... | ... |
@@ -147,7 +148,7 @@ protected: |
| 147 | 148 |
|
| 148 | 149 |
T &me() { return dynamic_cast<T &>(*this); }
|
| 149 | 150 |
public: |
| 150 |
- DialogControlBuilder(DialogControlType Type = NO_CONTROL) : controlType(Type), style(0), exstyle(0), rect(), id(-1), index(-1), relativePosition() { }
|
|
| 151 |
+ DialogControlBuilder(DialogControlType Type = DialogControlType::None) : controlType(Type), style(0), exstyle(0), rect(), id(-1), index(-1), relativePosition() { }
|
|
| 151 | 152 |
virtual ~DialogControlBuilder() { }
|
| 152 | 153 |
T &WithPosition(short X, short Y) { this->rect.position.x = X; this->rect.position.y = Y; return this->me(); }
|
| 153 | 154 |
T &WithPosition(const Point<short> &Position) { this->rect.position = Position; return this->me(); }
|
| ... | ... |
@@ -182,7 +183,7 @@ protected: |
| 182 | 183 |
friend class DialogTemplate; |
| 183 | 184 |
std::wstring groupName; |
| 184 | 185 |
public: |
| 185 |
- DialogGroupBuilder(const std::wstring &newGroupName) : DialogControlBuilder(GROUP_CONTROL), groupName(newGroupName) { }
|
|
| 186 |
+ DialogGroupBuilder(const std::wstring &newGroupName) : DialogControlBuilder(DialogControlType::Group), groupName(newGroupName) { }
|
|
| 186 | 187 |
}; |
| 187 | 188 |
|
| 188 | 189 |
template<class T> class DialogInGroupBuilder : public DialogControlBuilder<T> |
| ... | ... |
@@ -200,7 +201,7 @@ class DialogEditBoxBuilder : public DialogInGroupBuilder<DialogEditBoxBuilder> |
| 200 | 201 |
protected: |
| 201 | 202 |
friend class DialogTemplate; |
| 202 | 203 |
public: |
| 203 |
- DialogEditBoxBuilder() : DialogInGroupBuilder(EDITBOX_CONTROL) { }
|
|
| 204 |
+ DialogEditBoxBuilder() : DialogInGroupBuilder(DialogControlType::EditBox) { }
|
|
| 204 | 205 |
DialogEditBoxBuilder &IsLeftJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_LEFT; return this->me(); }
|
| 205 | 206 |
DialogEditBoxBuilder &IsCenterJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_CENTER; return this->me(); }
|
| 206 | 207 |
DialogEditBoxBuilder &IsRightJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_RIGHT; return this->me(); }
|
| ... | ... |
@@ -229,7 +230,7 @@ class DialogLabelBuilder : public DialogControlWithLabelBuilder<DialogLabelBuild |
| 229 | 230 |
protected: |
| 230 | 231 |
friend class DialogTemplate; |
| 231 | 232 |
public: |
| 232 |
- DialogLabelBuilder(const std::wstring &Label) : DialogControlWithLabelBuilder(LABEL_CONTROL, Label) { }
|
|
| 233 |
+ DialogLabelBuilder(const std::wstring &Label) : DialogControlWithLabelBuilder(DialogControlType::Label, Label) { }
|
|
| 233 | 234 |
DialogLabelBuilder &IsLeftJustified(bool WithWordWrap = false) |
| 234 | 235 |
{
|
| 235 | 236 |
this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); |
| ... | ... |
@@ -311,7 +312,7 @@ class DialogButtonBuilder : public DialogButtonBaseBuilder<DialogButtonBuilder> |
| 311 | 312 |
protected: |
| 312 | 313 |
friend class DialogTemplate; |
| 313 | 314 |
public: |
| 314 |
- DialogButtonBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(BUTTON_CONTROL, Label) { }
|
|
| 315 |
+ DialogButtonBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(DialogControlType::Button, Label) { }
|
|
| 315 | 316 |
DialogButtonBuilder &IsDefault(bool Default = true) { if (Default) this->style |= BS_DEFPUSHBUTTON; else this->style &= ~BS_DEFPUSHBUTTON; return this->me(); }
|
| 316 | 317 |
}; |
| 317 | 318 |
|
| ... | ... |
@@ -320,7 +321,7 @@ class DialogCheckBoxBuilder : public DialogButtonBaseBuilder<DialogCheckBoxBuild |
| 320 | 321 |
protected: |
| 321 | 322 |
friend class DialogTemplate; |
| 322 | 323 |
public: |
| 323 |
- DialogCheckBoxBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(CHECKBOX_CONTROL, Label) { this->style |= BS_AUTOCHECKBOX; }
|
|
| 324 |
+ DialogCheckBoxBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(DialogControlType::CheckBox, Label) { this->style |= BS_AUTOCHECKBOX; }
|
|
| 324 | 325 |
DialogCheckBoxBuilder &WithTextOnLeft(bool TextOnLeft = true) { if (TextOnLeft) this->style |= BS_LEFTTEXT; else this->style &= ~BS_LEFTTEXT; return this->me(); }
|
| 325 | 326 |
DialogCheckBoxBuilder &LikePushButton(bool PushButton = true) { if (PushButton) this->style |= BS_PUSHLIKE; else this->style &= ~BS_PUSHLIKE; return this->me(); }
|
| 326 | 327 |
}; |
| ... | ... |
@@ -330,7 +331,7 @@ class DialogListBoxBuilder : public DialogInGroupBuilder<DialogListBoxBuilder> |
| 330 | 331 |
protected: |
| 331 | 332 |
friend class DialogTemplate; |
| 332 | 333 |
public: |
| 333 |
- DialogListBoxBuilder() : DialogInGroupBuilder(LISTBOX_CONTROL) { }
|
|
| 334 |
+ DialogListBoxBuilder() : DialogInGroupBuilder(DialogControlType::ListBox) { }
|
|
| 334 | 335 |
DialogListBoxBuilder &WithNotify(bool Notify = true) { if (Notify) this->style |= LBS_NOTIFY; else this->style &= ~LBS_NOTIFY; return this->me(); }
|
| 335 | 336 |
DialogListBoxBuilder &WithSort(bool Sort = true) { if (Sort) this->style |= LBS_SORT; else this->style &= ~LBS_SORT; return this->me(); }
|
| 336 | 337 |
DialogListBoxBuilder &WithMultipleSelect(bool MultipleSelect = true) { if (MultipleSelect) this->style |= LBS_MULTIPLESEL; else this->style &= ~LBS_MULTIPLESEL; return this->me(); }
|
| ... | ... |
@@ -348,7 +349,7 @@ class DialogComboBoxBuilder : public DialogInGroupBuilder<DialogComboBoxBuilder> |
| 348 | 349 |
protected: |
| 349 | 350 |
friend class DialogTemplate; |
| 350 | 351 |
public: |
| 351 |
- DialogComboBoxBuilder() : DialogInGroupBuilder(COMBOBOX_CONTROL) { }
|
|
| 352 |
+ DialogComboBoxBuilder() : DialogInGroupBuilder(DialogControlType::ComboBox) { }
|
|
| 352 | 353 |
DialogComboBoxBuilder &IsSimple() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_SIMPLE; return this->me(); }
|
| 353 | 354 |
DialogComboBoxBuilder &IsDropDown() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_DROPDOWN; return this->me(); }
|
| 354 | 355 |
DialogComboBoxBuilder &IsDropDownList() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_DROPDOWNLIST; return this->me(); }
|
| ... | ... |
@@ -372,13 +373,13 @@ class DialogTemplate |
| 372 | 373 |
{
|
| 373 | 374 |
protected: |
| 374 | 375 |
DialogControlType controlType; |
| 375 |
- uint32_t style, exstyle; |
|
| 376 |
+ std::uint32_t style, exstyle; |
|
| 376 | 377 |
Rect<short> rect; |
| 377 | 378 |
short id; |
| 378 | 379 |
std::unique_ptr<RelativePosition> relativePosition; |
| 379 | 380 |
|
| 380 | 381 |
friend class DialogTemplate; |
| 381 |
- DialogControl() : controlType(NO_CONTROL), style(0), exstyle(0), rect(), id(-1), relativePosition() { }
|
|
| 382 |
+ DialogControl() : controlType(DialogControlType::None), style(0), exstyle(0), rect(), id(-1), relativePosition() { }
|
|
| 382 | 383 |
DialogControl(const DialogControl &control) : controlType(control.controlType), style(control.style), exstyle(control.exstyle), rect(control.rect), id(control.id), |
| 383 | 384 |
relativePosition(control.relativePosition ? control.relativePosition->Clone() : nullptr) { }
|
| 384 | 385 |
DialogControl &operator=(const DialogControl &control) |
| ... | ... |
@@ -411,9 +412,9 @@ class DialogTemplate |
| 411 | 412 |
|
| 412 | 413 |
return control; |
| 413 | 414 |
} |
| 414 |
- virtual uint16_t GetControlCount() const { return 1; }
|
|
| 415 |
+ virtual std::uint16_t GetControlCount() const { return 1; }
|
|
| 415 | 416 |
virtual short GetControlHeight() const { return this->rect.size.height; }
|
| 416 |
- virtual std::vector<uint8_t> GenerateControlTemplate() const = 0; |
|
| 417 |
+ virtual std::vector<std::uint8_t> GenerateControlTemplate() const = 0; |
|
| 417 | 418 |
virtual DialogControl *Clone() const = 0; |
| 418 | 419 |
}; |
| 419 | 420 |
|
| ... | ... |
@@ -452,15 +453,15 @@ class DialogTemplate |
| 452 | 453 |
} |
| 453 | 454 |
void CalculatePositions(bool doRightAndBottom = false); |
| 454 | 455 |
void CalculateSize(); |
| 455 |
- uint16_t GetControlCount() const; |
|
| 456 |
- std::vector<uint8_t> GenerateControlTemplate() const; |
|
| 456 |
+ std::uint16_t GetControlCount() const; |
|
| 457 |
+ std::vector<std::uint8_t> GenerateControlTemplate() const; |
|
| 457 | 458 |
DialogGroup *Clone() const { return new DialogGroup(*this); }
|
| 458 | 459 |
}; |
| 459 | 460 |
|
| 460 | 461 |
class DialogControlWithoutLabel : public DialogControl |
| 461 | 462 |
{
|
| 462 | 463 |
protected: |
| 463 |
- uint16_t type; |
|
| 464 |
+ std::uint16_t type; |
|
| 464 | 465 |
|
| 465 | 466 |
friend class DialogTemplate; |
| 466 | 467 |
friend class DialogControl; |
| ... | ... |
@@ -475,7 +476,7 @@ class DialogTemplate |
| 475 | 476 |
return *this; |
| 476 | 477 |
} |
| 477 | 478 |
public: |
| 478 |
- template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type) |
|
| 479 |
+ template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, std::uint16_t Type) |
|
| 479 | 480 |
{
|
| 480 | 481 |
auto control = DialogControl::CreateControl<Control>(builder); |
| 481 | 482 |
|
| ... | ... |
@@ -483,14 +484,14 @@ class DialogTemplate |
| 483 | 484 |
|
| 484 | 485 |
return control; |
| 485 | 486 |
} |
| 486 |
- virtual std::vector<uint8_t> GenerateControlTemplate() const; |
|
| 487 |
+ virtual std::vector<std::uint8_t> GenerateControlTemplate() const; |
|
| 487 | 488 |
virtual DialogControlWithoutLabel *Clone() const { return new DialogControlWithoutLabel(*this); }
|
| 488 | 489 |
}; |
| 489 | 490 |
|
| 490 | 491 |
class DialogControlWithLabel : public DialogControl |
| 491 | 492 |
{
|
| 492 | 493 |
protected: |
| 493 |
- uint16_t type; |
|
| 494 |
+ std::uint16_t type; |
|
| 494 | 495 |
std::wstring label; |
| 495 | 496 |
|
| 496 | 497 |
friend class DialogTemplate; |
| ... | ... |
@@ -507,7 +508,7 @@ class DialogTemplate |
| 507 | 508 |
return *this; |
| 508 | 509 |
} |
| 509 | 510 |
public: |
| 510 |
- template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type) |
|
| 511 |
+ template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, std::uint16_t Type) |
|
| 511 | 512 |
{
|
| 512 | 513 |
auto control = DialogControl::CreateControl<Control>(builder); |
| 513 | 514 |
|
| ... | ... |
@@ -516,7 +517,7 @@ class DialogTemplate |
| 516 | 517 |
|
| 517 | 518 |
return control; |
| 518 | 519 |
} |
| 519 |
- virtual std::vector<uint8_t> GenerateControlTemplate() const; |
|
| 520 |
+ virtual std::vector<std::uint8_t> GenerateControlTemplate() const; |
|
| 520 | 521 |
virtual DialogControlWithLabel *Clone() const { return new DialogControlWithLabel(*this); }
|
| 521 | 522 |
}; |
| 522 | 523 |
|
| ... | ... |
@@ -587,12 +588,12 @@ class DialogTemplate |
| 587 | 588 |
}; |
| 588 | 589 |
|
| 589 | 590 |
std::wstring title; |
| 590 |
- uint32_t style, exstyle; |
|
| 591 |
+ std::uint32_t style, exstyle; |
|
| 591 | 592 |
std::wstring fontName; |
| 592 |
- uint16_t fontSizeInPts; |
|
| 593 |
+ std::uint16_t fontSizeInPts; |
|
| 593 | 594 |
Size<short> size; |
| 594 | 595 |
DialogTemplate::Controls controls; |
| 595 |
- std::vector<uint8_t> templateData; |
|
| 596 |
+ std::vector<std::uint8_t> templateData; |
|
| 596 | 597 |
|
| 597 | 598 |
template<typename Builder> void AddControlToGroup(std::unique_ptr<DialogControl> &&control, const DialogControlBuilder<Builder> &builder) |
| 598 | 599 |
{
|
| ... | ... |
@@ -608,7 +609,7 @@ class DialogTemplate |
| 608 | 609 |
{
|
| 609 | 610 |
for (auto curr = this->controls.begin(), end = this->controls.end(); curr != end; ++curr) |
| 610 | 611 |
{
|
| 611 |
- if ((*curr)->controlType != GROUP_CONTROL) |
|
| 612 |
+ if ((*curr)->controlType != DialogControlType::Group) |
|
| 612 | 613 |
continue; |
| 613 | 614 |
DialogGroup *group = dynamic_cast<DialogGroup *>(curr->get()); |
| 614 | 615 |
if (group->groupName == groupBuilder.groupName) |
| ... | ... |
@@ -623,7 +624,7 @@ class DialogTemplate |
| 623 | 624 |
throw std::runtime_error("Group " + ConvertFuncs::WStringToString(groupBuilder.groupName) + " was not found.");
|
| 624 | 625 |
} |
| 625 | 626 |
} |
| 626 |
- uint16_t GetTotalControlCount() const; |
|
| 627 |
+ std::uint16_t GetTotalControlCount() const; |
|
| 627 | 628 |
bool CalculateControlPosition(short index, bool doRightAndBottom = false); |
| 628 | 629 |
void CalculateSize(); |
| 629 | 630 |
public: |
(I never remember to update these and besides, GitHub history can show when they were last modified.)
* Removed my custom String class, as well as removed the really old
Unicode ConvertUTF, the UTF Converter, and the UTF Encode/Decode
functions.
* Replaced the above with using standard C++ std::wstring_convert and
std::codecvt_utf8.
* Added headers adapted from llvm's libc++ project for allowing the
above C++ classes to exist with GCC and Clang when libc++ isn't being
used.
* Used std::string over std::wstring whenever possible.
* Added header adapted from llvm's libc++ project to create special
versions of the ifstream and ofstream classes that would utilize _wfopen
on non-MSVC Windows compilers, so those compilers could access files on
Windows that use characters outside the current codepage.
* Removed the -static-libgcc and -static-libstdc++ flags from the
Makefile for non-MSVC builds. The generated DLLs will require extra DLLs
from either Cygwin or MinGW (whichever is used to compile), I've only
tested with MinGW and for some reason they crash Winamp on exit, I have
no idea why.
| ... | ... |
@@ -1,7 +1,7 @@ |
| 1 | 1 |
/* |
| 2 | 2 |
* Windows Dynamic Dialog Builder framework |
| 3 | 3 |
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com] |
| 4 |
- * Last modification on 2014-09-17 |
|
| 4 |
+ * Last modification on 2014-09-24 |
|
| 5 | 5 |
*/ |
| 6 | 6 |
|
| 7 | 7 |
#pragma once |
| ... | ... |
@@ -12,8 +12,8 @@ |
| 12 | 12 |
#include <algorithm> |
| 13 | 13 |
#include <stdexcept> |
| 14 | 14 |
#include <cstdint> |
| 15 |
+#include "XSFCommon.h" |
|
| 15 | 16 |
#include "windowsh_wrapper.h" |
| 16 |
-#include "UtfConverter.h" |
|
| 17 | 17 |
|
| 18 | 18 |
template<typename T> struct Point |
| 19 | 19 |
{
|
| ... | ... |
@@ -621,7 +621,7 @@ class DialogTemplate |
| 621 | 621 |
return; |
| 622 | 622 |
} |
| 623 | 623 |
} |
| 624 |
- throw std::runtime_error("Group " + UtfConverter::ToUtf8(groupBuilder.groupName) + " was not found.");
|
|
| 624 |
+ throw std::runtime_error("Group " + ConvertFuncs::WStringToString(groupBuilder.groupName) + " was not found.");
|
|
| 625 | 625 |
} |
| 626 | 626 |
} |
| 627 | 627 |
uint16_t GetTotalControlCount() const; |
* [2SF] Used more up-to-date asmjit, despite the ugly looking code.
| ... | ... |
@@ -1,7 +1,7 @@ |
| 1 | 1 |
/* |
| 2 | 2 |
* Windows Dynamic Dialog Builder framework |
| 3 | 3 |
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com] |
| 4 |
- * Last modification on 2014-09-08 |
|
| 4 |
+ * Last modification on 2014-09-17 |
|
| 5 | 5 |
*/ |
| 6 | 6 |
|
| 7 | 7 |
#pragma once |
| ... | ... |
@@ -429,14 +429,14 @@ class DialogTemplate |
| 429 | 429 |
DialogGroup() : DialogControl(), controls(), groupName(L"") { }
|
| 430 | 430 |
DialogGroup(const DialogGroup &control) : DialogControl(control), controls(), groupName(control.groupName) |
| 431 | 431 |
{
|
| 432 |
- 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())); });
|
|
| 432 |
+ std::for_each(control.controls.begin(), control.controls.end(), [&](const std::unique_ptr<DialogControl> &ctl) { this->controls.push_back(std::unique_ptr<DialogControl>(ctl->Clone())); });
|
|
| 433 | 433 |
} |
| 434 | 434 |
DialogGroup &operator=(const DialogGroup &control) |
| 435 | 435 |
{
|
| 436 | 436 |
DialogControl::operator=(control); |
| 437 | 437 |
|
| 438 | 438 |
this->controls.clear(); |
| 439 |
- 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())); });
|
|
| 439 |
+ std::for_each(control.controls.begin(), control.controls.end(), [&](const std::unique_ptr<DialogControl> &ctl) { this->controls.push_back(std::unique_ptr<DialogControl>(ctl->Clone())); });
|
|
| 440 | 440 |
|
| 441 | 441 |
this->groupName = control.groupName; |
| 442 | 442 |
|
| ... | ... |
@@ -1,11 +1,10 @@ |
| 1 | 1 |
/* |
| 2 | 2 |
* Windows Dynamic Dialog Builder framework |
| 3 | 3 |
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com] |
| 4 |
- * Last modification on 2013-04-23 |
|
| 4 |
+ * Last modification on 2014-09-08 |
|
| 5 | 5 |
*/ |
| 6 | 6 |
|
| 7 |
-#ifndef DIALOG_BUILDER_H |
|
| 8 |
-#define DIALOG_BUILDER_H |
|
| 7 |
+#pragma once |
|
| 9 | 8 |
|
| 10 | 9 |
#include <string> |
| 11 | 10 |
#include <memory> |
| ... | ... |
@@ -673,5 +672,3 @@ public: |
| 673 | 672 |
void AutoSize(); |
| 674 | 673 |
const DLGTEMPLATE *GenerateTemplate(); |
| 675 | 674 |
}; |
| 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 |
| 1 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,695 +0,0 @@ |
| 1 |
-/* |
|
| 2 |
- * Windows Dynamic Dialog Builder framework |
|
| 3 |
- * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com] |
|
| 4 |
- * Last modification on 2013-03-30 |
|
| 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 "pstdint.h" |
|
| 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(Point<T> Position, 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(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(Rect<short> child, Rect<short> other) |
|
| 70 |
- {
|
|
| 71 |
- Point<short> newPosition = child.position; |
|
| 72 |
- if (this->relativePosition.y != -1) |
|
| 73 |
- {
|
|
| 74 |
- if (this->positionType == FROM_TOP || this->positionType == FROM_TOPLEFT || this->positionType == FROM_TOPRIGHT) |
|
| 75 |
- newPosition.y = other.position.y + this->relativePosition.y; |
|
| 76 |
- if (this->positionType == FROM_BOTTOM || this->positionType == FROM_BOTTOMLEFT || this->positionType == FROM_BOTTOMRIGHT) |
|
| 77 |
- newPosition.y = other.position.y + other.size.height + this->relativePosition.y; |
|
| 78 |
- } |
|
| 79 |
- if (this->relativePosition.x != -1) |
|
| 80 |
- {
|
|
| 81 |
- if (this->positionType == FROM_LEFT || this->positionType == FROM_TOPLEFT || this->positionType == FROM_BOTTOMLEFT) |
|
| 82 |
- newPosition.x = other.position.x + this->relativePosition.x; |
|
| 83 |
- if (this->positionType == FROM_RIGHT || this->positionType == FROM_TOPRIGHT || this->positionType == FROM_BOTTOMRIGHT) |
|
| 84 |
- newPosition.x = other.position.x + other.size.width + this->relativePosition.x; |
|
| 85 |
- } |
|
| 86 |
- return newPosition; |
|
| 87 |
- } |
|
| 88 |
-}; |
|
| 89 |
- |
|
| 90 |
-class RelativePositionToParent : public RelativePosition |
|
| 91 |
-{
|
|
| 92 |
-public: |
|
| 93 |
- RelativePositionToParent(Point<short> RelPosition, PositionType PosType) : RelativePosition(RelPosition, TO_PARENT, PosType) { }
|
|
| 94 |
- RelativePositionToParent *Clone() const { return new RelativePositionToParent(this->relativePosition, this->positionType); }
|
|
| 95 |
-}; |
|
| 96 |
- |
|
| 97 |
-class RelativePositionToSibling : public RelativePosition |
|
| 98 |
-{
|
|
| 99 |
-public: |
|
| 100 |
- short siblingsBack; |
|
| 101 |
- |
|
| 102 |
- RelativePositionToSibling(Point<short> RelPosition, PositionType PosType, short SiblingsBack = 1) : RelativePosition(RelPosition, TO_SIBLING, PosType), siblingsBack(SiblingsBack) { }
|
|
| 103 |
- RelativePositionToSibling *Clone() const { return new RelativePositionToSibling(this->relativePosition, this->positionType, this->siblingsBack); }
|
|
| 104 |
-}; |
|
| 105 |
- |
|
| 106 |
-enum DialogControlType |
|
| 107 |
-{
|
|
| 108 |
- NO_CONTROL, |
|
| 109 |
- GROUP_CONTROL, |
|
| 110 |
- EDITBOX_CONTROL, |
|
| 111 |
- LABEL_CONTROL, |
|
| 112 |
- CHECKBOX_CONTROL, |
|
| 113 |
- BUTTON_CONTROL, |
|
| 114 |
- LISTBOX_CONTROL, |
|
| 115 |
- COMBOBOX_CONTROL |
|
| 116 |
-}; |
|
| 117 |
- |
|
| 118 |
-class DialogTemplate; |
|
| 119 |
- |
|
| 120 |
-class DialogBuilder |
|
| 121 |
-{
|
|
| 122 |
-protected: |
|
| 123 |
- friend class DialogTemplate; |
|
| 124 |
- std::wstring title, fontName; |
|
| 125 |
- uint32_t style, exstyle; |
|
| 126 |
- uint16_t fontSizeInPts; |
|
| 127 |
- Size<short> size; |
|
| 128 |
- bool resetControls; |
|
| 129 |
-public: |
|
| 130 |
- DialogBuilder() : title(L""), fontName(L""), style(0), exstyle(0), fontSizeInPts(0), size(), resetControls(false) { }
|
|
| 131 |
- DialogBuilder &WithTitle(const std::wstring &Title) { this->title = Title; return *this; }
|
|
| 132 |
- DialogBuilder &WithFont(const std::wstring &FontName, uint16_t FontSizeInPts) { this->fontName = FontName; this->fontSizeInPts = FontSizeInPts; return *this; }
|
|
| 133 |
- DialogBuilder &WithSize(short Width, short Height) { this->size.width = Width; this->size.height = Height; return *this; }
|
|
| 134 |
- DialogBuilder &WithSize(Size<short> Sz) { this->size = Sz; return *this; }
|
|
| 135 |
- DialogBuilder &ResetControls(bool Reset = true) { this->resetControls = Reset; return *this; }
|
|
| 136 |
- DialogBuilder &IsOverlapped() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_OVERLAPPED; return *this; }
|
|
| 137 |
- DialogBuilder &IsPopup() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_POPUP; return *this; }
|
|
| 138 |
- DialogBuilder &IsChild() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_CHILD; return *this; }
|
|
| 139 |
- DialogBuilder &WithBorder(bool Border = true) { if (Border) this->style |= WS_BORDER; else this->style &= ~WS_BORDER; return *this; }
|
|
| 140 |
- DialogBuilder &WithDialogFrame(bool DialogFrame = true) { if (DialogFrame) this->style |= WS_DLGFRAME; else this->style &= ~WS_DLGFRAME; return *this; }
|
|
| 141 |
- DialogBuilder &WithVerticalScrollbar(bool VerticalScrollbar = true) { if (VerticalScrollbar) this->style |= WS_VSCROLL; else this->style &= ~WS_VSCROLL; return *this; }
|
|
| 142 |
- DialogBuilder &WithHorizontalScrollbar(bool HorizontalScrollbar = true) { if (HorizontalScrollbar) this->style |= WS_HSCROLL; else this->style &= ~WS_HSCROLL; return *this; }
|
|
| 143 |
- DialogBuilder &WithSystemMenu(bool SystemMenu = true) { if (SystemMenu) this->style |= WS_SYSMENU; else this->style &= ~WS_SYSMENU; return *this; }
|
|
| 144 |
- DialogBuilder &WithSizingBorder(bool SizingBorder = true) { if (SizingBorder) this->style |= WS_THICKFRAME; else this->style &= ~WS_THICKFRAME; return *this; }
|
|
| 145 |
- DialogBuilder &WithMinimizeBox(bool MinimizeBox = true) { if (MinimizeBox) this->style |= WS_MINIMIZEBOX; else this->style &= ~WS_MINIMIZEBOX; return *this; }
|
|
| 146 |
- DialogBuilder &WithMaximizeBox(bool MaximizeBox = true) { if (MaximizeBox) this->style |= WS_MAXIMIZEBOX; else this->style &= ~WS_MAXIMIZEBOX; return *this; }
|
|
| 147 |
- DialogBuilder &WithDialogModalFrame(bool DialogModalFrame = true) { if (DialogModalFrame) this->exstyle |= WS_EX_DLGMODALFRAME; else this->exstyle &= ~WS_EX_DLGMODALFRAME; return *this; }
|
|
| 148 |
-#if WINVER >= 0x0400 |
|
| 149 |
- DialogBuilder &WithRaisedEdge(bool RaisedEdge = true) { if (RaisedEdge) this->exstyle |= WS_EX_WINDOWEDGE; else this->exstyle &= ~WS_EX_WINDOWEDGE; return *this; }
|
|
| 150 |
- DialogBuilder &WithSunkenEdge(bool SunkenEdge = true) { if (SunkenEdge) this->exstyle |= WS_EX_CLIENTEDGE; else this->exstyle &= ~WS_EX_CLIENTEDGE; return *this; }
|
|
| 151 |
- DialogBuilder &WithContextHelp(bool ContextHelp = true) { if (ContextHelp) this->exstyle |= WS_EX_CONTEXTHELP; else this->exstyle &= ~WS_EX_CONTEXTHELP; return *this; }
|
|
| 152 |
- DialogBuilder &IsControlWindow(bool ControlWindow = true) { if (ControlWindow) this->style |= DS_CONTROL; else this->style &= ~DS_CONTROL; return *this; }
|
|
| 153 |
- DialogBuilder &IsCentered(bool Centered = true) { if (Centered) this->style |= DS_CENTER; else this->style &= ~DS_CENTER; return *this; }
|
|
| 154 |
-#endif |
|
| 155 |
-}; |
|
| 156 |
- |
|
| 157 |
-template<class T> class DialogControlBuilder |
|
| 158 |
-{
|
|
| 159 |
-protected: |
|
| 160 |
- friend class DialogTemplate; |
|
| 161 |
- DialogControlType controlType; |
|
| 162 |
- uint32_t style, exstyle; |
|
| 163 |
- Rect<short> rect; |
|
| 164 |
- short id; |
|
| 165 |
- int index; |
|
| 166 |
- std::unique_ptr<RelativePosition> relativePosition; |
|
| 167 |
- |
|
| 168 |
- T &me() { return dynamic_cast<T &>(*this); }
|
|
| 169 |
-public: |
|
| 170 |
- DialogControlBuilder(DialogControlType Type = NO_CONTROL) : controlType(Type), style(0), exstyle(0), rect(), id(-1), index(-1), relativePosition() { }
|
|
| 171 |
- virtual ~DialogControlBuilder() { }
|
|
| 172 |
- T &WithPosition(short X, short Y) { this->rect.position.x = X; this->rect.position.y = Y; return this->me(); }
|
|
| 173 |
- T &WithPosition(Point<short> Position) { this->rect.position = Position; return this->me(); }
|
|
| 174 |
- T &WithRelativePositionToParent(RelativePosition::PositionType PosType, Point<short> RelativePosition) |
|
| 175 |
- {
|
|
| 176 |
- this->relativePosition.reset(new RelativePositionToParent(RelativePosition, PosType)); |
|
| 177 |
- return this->me(); |
|
| 178 |
- } |
|
| 179 |
- T &WithRelativePositionToSibling(RelativePosition::PositionType PosType, Point<short> RelativePosition, short SiblingsBack = 1) |
|
| 180 |
- {
|
|
| 181 |
- this->relativePosition.reset(new RelativePositionToSibling(RelativePosition, PosType, SiblingsBack)); |
|
| 182 |
- return this->me(); |
|
| 183 |
- } |
|
| 184 |
- T &WithSize(short Width, short Height) { this->rect.size.width = Width; this->rect.size.height = Height; return this->me(); }
|
|
| 185 |
- T &WithSize(Size<short> Sz) { this->rect.size = Sz; return this->me(); }
|
|
| 186 |
- T &WithID(short ID) { this->id = ID; return this->me(); }
|
|
| 187 |
- T &AtIndex(int Index) { this->index = Index; return this->me(); }
|
|
| 188 |
- T &IsDisabled(bool Disabled = true) { if (Disabled) this->style |= WS_DISABLED; else this->style &= ~WS_DISABLED; return this->me(); }
|
|
| 189 |
- T &WithBorder(bool ThinBorder = true) { if (ThinBorder) this->style |= WS_BORDER; else this->style &= ~WS_BORDER; return this->me(); }
|
|
| 190 |
- T &WithVerticalScrollbar(bool VerticalScrollbar = true) { if (VerticalScrollbar) this->style |= WS_VSCROLL; else this->style &= ~WS_VSCROLL; return this->me(); }
|
|
| 191 |
- T &WithHorizontalScrollbar(bool HorizontalScrollbar = true) { if (HorizontalScrollbar) this->style |= WS_HSCROLL; else this->style &= ~WS_HSCROLL; return this->me(); }
|
|
| 192 |
- T &WithTabStop(bool TabStop = true) { if (TabStop) this->style |= WS_TABSTOP; else this->style &= ~WS_TABSTOP; return this->me(); }
|
|
| 193 |
-#if WINVER >= 0x0400 |
|
| 194 |
- T &WithRaisedEdge(bool RaisedEdge = true) { if (RaisedEdge) this->exstyle |= WS_EX_WINDOWEDGE; else this->exstyle &= ~WS_EX_WINDOWEDGE; return this->me(); }
|
|
| 195 |
- T &WithSunkenEdge(bool SunkenEdge = true) { if (SunkenEdge) this->exstyle |= WS_EX_CLIENTEDGE; else this->exstyle &= ~WS_EX_CLIENTEDGE; return this->me(); }
|
|
| 196 |
-#endif |
|
| 197 |
-}; |
|
| 198 |
- |
|
| 199 |
-class DialogGroupBuilder : public DialogControlBuilder<DialogGroupBuilder> |
|
| 200 |
-{
|
|
| 201 |
-protected: |
|
| 202 |
- friend class DialogTemplate; |
|
| 203 |
- std::wstring groupName; |
|
| 204 |
-public: |
|
| 205 |
- DialogGroupBuilder(const std::wstring &newGroupName) : DialogControlBuilder(GROUP_CONTROL), groupName(newGroupName) { }
|
|
| 206 |
-}; |
|
| 207 |
- |
|
| 208 |
-template<class T> class DialogInGroupBuilder : public DialogControlBuilder<T> |
|
| 209 |
-{
|
|
| 210 |
-protected: |
|
| 211 |
- friend class DialogTemplate; |
|
| 212 |
- std::wstring groupName; |
|
| 213 |
-public: |
|
| 214 |
- DialogInGroupBuilder(DialogControlType Type) : DialogControlBuilder<T>(Type), groupName(L"") { }
|
|
| 215 |
- T &InGroup(const std::wstring &GroupName) { this->groupName = GroupName; return this->me(); }
|
|
| 216 |
-}; |
|
| 217 |
- |
|
| 218 |
-class DialogEditBoxBuilder : public DialogInGroupBuilder<DialogEditBoxBuilder> |
|
| 219 |
-{
|
|
| 220 |
-protected: |
|
| 221 |
- friend class DialogTemplate; |
|
| 222 |
-public: |
|
| 223 |
- DialogEditBoxBuilder() : DialogInGroupBuilder(EDITBOX_CONTROL) { }
|
|
| 224 |
- DialogEditBoxBuilder &IsLeftJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_LEFT; return this->me(); }
|
|
| 225 |
- DialogEditBoxBuilder &IsCenterJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_CENTER; return this->me(); }
|
|
| 226 |
- DialogEditBoxBuilder &IsRightJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_RIGHT; return this->me(); }
|
|
| 227 |
- DialogEditBoxBuilder &IsMultiline(bool Multiline = true) { if (Multiline) this->style |= ES_MULTILINE; else this->style &= ~ES_MULTILINE; return this->me(); }
|
|
| 228 |
- DialogEditBoxBuilder &WithAllUppercase(bool AllUppercase = true) { if (AllUppercase) this->style |= ES_UPPERCASE; else this->style &= ~ES_UPPERCASE; return this->me(); }
|
|
| 229 |
- DialogEditBoxBuilder &WithAllLowercase(bool AllLowercase = true) { if (AllLowercase) this->style |= ES_LOWERCASE; else this->style &= ~ES_LOWERCASE; return this->me(); }
|
|
| 230 |
- DialogEditBoxBuilder &IsPasswordInput(bool PasswordInput = true) { if (PasswordInput) this->style |= ES_PASSWORD; else this->style &= ~ES_PASSWORD; return this->me(); }
|
|
| 231 |
- DialogEditBoxBuilder &WithAutoVScroll(bool AutoVScroll = true) { if (AutoVScroll) this->style |= ES_AUTOVSCROLL; else this->style &= ~ES_AUTOVSCROLL; return this->me(); }
|
|
| 232 |
- DialogEditBoxBuilder &WithAutoHScroll(bool AutoHScroll = true) { if (AutoHScroll) this->style |= ES_AUTOHSCROLL; else this->style &= ~ES_AUTOHSCROLL; return this->me(); }
|
|
| 233 |
- DialogEditBoxBuilder &WithDontHideSelection(bool DontHideSelection = true) { if (DontHideSelection) this->style |= ES_NOHIDESEL; else this->style &= ~ES_NOHIDESEL; return this->me(); }
|
|
| 234 |
- DialogEditBoxBuilder &IsReadOnly(bool ReadOnly = true) { if (ReadOnly) this->style |= ES_READONLY; else this->style &= ~ES_READONLY; return this->me(); }
|
|
| 235 |
- DialogEditBoxBuilder &WithWantReturn(bool WantReturn = true) { if (WantReturn) this->style |= ES_WANTRETURN; else this->style &= ~ES_WANTRETURN; return this->me(); }
|
|
| 236 |
-}; |
|
| 237 |
- |
|
| 238 |
-template<class T> class DialogControlWithLabelBuilder : public DialogInGroupBuilder<T> |
|
| 239 |
-{
|
|
| 240 |
-protected: |
|
| 241 |
- friend class DialogTemplate; |
|
| 242 |
- std::wstring label; |
|
| 243 |
-public: |
|
| 244 |
- DialogControlWithLabelBuilder(DialogControlType Type, const std::wstring &Label) : DialogInGroupBuilder<T>(Type), label(Label) { }
|
|
| 245 |
-}; |
|
| 246 |
- |
|
| 247 |
-class DialogLabelBuilder : public DialogControlWithLabelBuilder<DialogLabelBuilder> |
|
| 248 |
-{
|
|
| 249 |
-protected: |
|
| 250 |
- friend class DialogTemplate; |
|
| 251 |
-public: |
|
| 252 |
- DialogLabelBuilder(const std::wstring &Label) : DialogControlWithLabelBuilder(LABEL_CONTROL, Label) { }
|
|
| 253 |
- DialogLabelBuilder &IsLeftJustified(bool WithWordWrap = false) |
|
| 254 |
- {
|
|
| 255 |
- this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); |
|
| 256 |
- if (WithWordWrap) |
|
| 257 |
- this->style |= SS_LEFTNOWORDWRAP; |
|
| 258 |
- else |
|
| 259 |
- this->style |= SS_LEFT; |
|
| 260 |
- return this->me(); |
|
| 261 |
- } |
|
| 262 |
- DialogLabelBuilder &IsCenterJustified() { this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); this->style |= SS_CENTER; return this->me(); }
|
|
| 263 |
- DialogLabelBuilder &IsRightJustified() { this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); this->style |= SS_RIGHT; return this->me(); }
|
|
| 264 |
- DialogLabelBuilder &WithAmpsNotTranslated(bool AmpsNotTranslated = true) { if (AmpsNotTranslated) this->style |= SS_NOPREFIX; else this->style &= ~SS_NOPREFIX; return this->me(); }
|
|
| 265 |
-#if WINVER >= 0x0400 |
|
| 266 |
- DialogLabelBuilder &WithNotify(bool Notify = true) { if (Notify) this->style |= SS_NOTIFY; else this->style &= ~SS_NOTIFY; return this->me(); }
|
|
| 267 |
-#endif |
|
| 268 |
-}; |
|
| 269 |
- |
|
| 270 |
-template<class T> class DialogButtonBaseBuilder : public DialogControlWithLabelBuilder<T> |
|
| 271 |
-{
|
|
| 272 |
-protected: |
|
| 273 |
- friend class DialogTemplate; |
|
| 274 |
-public: |
|
| 275 |
- DialogButtonBaseBuilder(DialogControlType Type, const std::wstring &Label) : DialogControlWithLabelBuilder<T>(Type, Label) { }
|
|
| 276 |
-#if WINVER >= 0x0400 |
|
| 277 |
- T &IsLeftJustified(bool LeftJustified = true) |
|
| 278 |
- {
|
|
| 279 |
- if (LeftJustified) |
|
| 280 |
- {
|
|
| 281 |
- this->style |= BS_LEFT; |
|
| 282 |
- this->style &= ~BS_RIGHT; |
|
| 283 |
- } |
|
| 284 |
- else |
|
| 285 |
- this->style &= ~BS_LEFT; |
|
| 286 |
- return this->me(); |
|
| 287 |
- } |
|
| 288 |
- T &IsRightJustified(bool RightJustified = true) |
|
| 289 |
- {
|
|
| 290 |
- if (RightJustified) |
|
| 291 |
- {
|
|
| 292 |
- this->style |= BS_RIGHT; |
|
| 293 |
- this->style &= ~BS_LEFT; |
|
| 294 |
- } |
|
| 295 |
- else |
|
| 296 |
- this->style &= ~BS_RIGHT; |
|
| 297 |
- return this->me(); |
|
| 298 |
- } |
|
| 299 |
- T &IsCenterJustified(bool CenterJustified = true) { if (CenterJustified) this->style |= BS_CENTER; else this->style &= ~BS_CENTER; return this->me(); }
|
|
| 300 |
- T &WithVerticalTop(bool VerticalTop = true) |
|
| 301 |
- {
|
|
| 302 |
- if (VerticalTop) |
|
| 303 |
- {
|
|
| 304 |
- this->style |= BS_TOP; |
|
| 305 |
- this->style &= ~BS_BOTTOM; |
|
| 306 |
- } |
|
| 307 |
- else |
|
| 308 |
- this->style &= ~BS_TOP; |
|
| 309 |
- return this->me(); |
|
| 310 |
- } |
|
| 311 |
- T &WithVerticalBottom(bool VerticalBottom = true) |
|
| 312 |
- {
|
|
| 313 |
- if (VerticalBottom) |
|
| 314 |
- {
|
|
| 315 |
- this->style |= BS_BOTTOM; |
|
| 316 |
- this->style &= ~BS_TOP; |
|
| 317 |
- } |
|
| 318 |
- else |
|
| 319 |
- this->style &= ~BS_BOTTOM; |
|
| 320 |
- return this->me(); |
|
| 321 |
- } |
|
| 322 |
- T &WithVerticalCenter(bool VerticalCenter = true) { if (VerticalCenter) this->style |= BS_VCENTER; else this->style &= ~BS_VCENTER; return this->me(); }
|
|
| 323 |
- T &IsMultiline(bool Multiline = true) { if (Multiline) this->style |= BS_MULTILINE; else this->style &= ~BS_MULTILINE; return this->me(); }
|
|
| 324 |
- T &WithNotify(bool Notify = true) { if (Notify) this->style |= BS_NOTIFY; else this->style &= ~BS_NOTIFY; return this->me(); }
|
|
| 325 |
- T &IsFlat(bool Flat = true) { if (Flat) this->style |= BS_FLAT; else this->style &= ~BS_FLAT; return this->me(); }
|
|
| 326 |
-#endif |
|
| 327 |
-}; |
|
| 328 |
- |
|
| 329 |
-class DialogButtonBuilder : public DialogButtonBaseBuilder<DialogButtonBuilder> |
|
| 330 |
-{
|
|
| 331 |
-protected: |
|
| 332 |
- friend class DialogTemplate; |
|
| 333 |
-public: |
|
| 334 |
- DialogButtonBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(BUTTON_CONTROL, Label) { }
|
|
| 335 |
- DialogButtonBuilder &IsDefault(bool Default = true) { if (Default) this->style |= BS_DEFPUSHBUTTON; else this->style &= ~BS_DEFPUSHBUTTON; return this->me(); }
|
|
| 336 |
-}; |
|
| 337 |
- |
|
| 338 |
-class DialogCheckBoxBuilder : public DialogButtonBaseBuilder<DialogCheckBoxBuilder> |
|
| 339 |
-{
|
|
| 340 |
-protected: |
|
| 341 |
- friend class DialogTemplate; |
|
| 342 |
-public: |
|
| 343 |
- DialogCheckBoxBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(CHECKBOX_CONTROL, Label) { this->style |= BS_AUTOCHECKBOX; }
|
|
| 344 |
- DialogCheckBoxBuilder &WithTextOnLeft(bool TextOnLeft = true) { if (TextOnLeft) this->style |= BS_LEFTTEXT; else this->style &= ~BS_LEFTTEXT; return this->me(); }
|
|
| 345 |
- DialogCheckBoxBuilder &LikePushButton(bool PushButton = true) { if (PushButton) this->style |= BS_PUSHLIKE; else this->style &= ~BS_PUSHLIKE; return this->me(); }
|
|
| 346 |
-}; |
|
| 347 |
- |
|
| 348 |
-class DialogListBoxBuilder : public DialogInGroupBuilder<DialogListBoxBuilder> |
|
| 349 |
-{
|
|
| 350 |
-protected: |
|
| 351 |
- friend class DialogTemplate; |
|
| 352 |
-public: |
|
| 353 |
- DialogListBoxBuilder() : DialogInGroupBuilder(LISTBOX_CONTROL) { }
|
|
| 354 |
- DialogListBoxBuilder &WithNotify(bool Notify = true) { if (Notify) this->style |= LBS_NOTIFY; else this->style &= ~LBS_NOTIFY; return this->me(); }
|
|
| 355 |
- DialogListBoxBuilder &WithSort(bool Sort = true) { if (Sort) this->style |= LBS_SORT; else this->style &= ~LBS_SORT; return this->me(); }
|
|
| 356 |
- DialogListBoxBuilder &WithMultipleSelect(bool MultipleSelect = true) { if (MultipleSelect) this->style |= LBS_MULTIPLESEL; else this->style &= ~LBS_MULTIPLESEL; return this->me(); }
|
|
| 357 |
- DialogListBoxBuilder &WithExactHeight(bool ExactHeight = true) { if (ExactHeight) this->style |= LBS_NOINTEGRALHEIGHT; else this->style &= ~LBS_NOINTEGRALHEIGHT; return this->me(); }
|
|
| 358 |
- DialogListBoxBuilder &WithMultipleColumns(bool MultipleColumns = true) { if (MultipleColumns) this->style |= LBS_MULTICOLUMN; else this->style &= ~LBS_MULTICOLUMN; return this->me(); }
|
|
| 359 |
- DialogListBoxBuilder &WithExtendedSelect(bool ExtendedSelect = true) { if (ExtendedSelect) this->style |= LBS_EXTENDEDSEL; else this->style &= ~LBS_EXTENDEDSEL; return this->me(); }
|
|
| 360 |
- DialogListBoxBuilder &WithDisabledNoScroll(bool DisabledNoScroll = true) { if (DisabledNoScroll) this->style |= LBS_DISABLENOSCROLL; else this->style &= ~LBS_DISABLENOSCROLL; return this->me(); }
|
|
| 361 |
-#if WINVER >= 0x0400 |
|
| 362 |
- DialogListBoxBuilder &WithNoSelect(bool NoSelect = true) { if (NoSelect) this->style |= LBS_NOSEL; else this->style &= ~LBS_NOSEL; return this->me(); }
|
|
| 363 |
-#endif |
|
| 364 |
-}; |
|
| 365 |
- |
|
| 366 |
-class DialogComboBoxBuilder : public DialogInGroupBuilder<DialogComboBoxBuilder> |
|
| 367 |
-{
|
|
| 368 |
-protected: |
|
| 369 |
- friend class DialogTemplate; |
|
| 370 |
-public: |
|
| 371 |
- DialogComboBoxBuilder() : DialogInGroupBuilder(COMBOBOX_CONTROL) { }
|
|
| 372 |
- DialogComboBoxBuilder &IsSimple() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_SIMPLE; return this->me(); }
|
|
| 373 |
- DialogComboBoxBuilder &IsDropDown() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_DROPDOWN; return this->me(); }
|
|
| 374 |
- DialogComboBoxBuilder &IsDropDownList() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_DROPDOWNLIST; return this->me(); }
|
|
| 375 |
- DialogComboBoxBuilder &WithAutoHScroll(bool AutoHScroll = true) { if (AutoHScroll) this->style |= CBS_AUTOHSCROLL; else this->style &= ~CBS_AUTOHSCROLL; return this->me(); }
|
|
| 376 |
- DialogComboBoxBuilder &WithSort(bool Sort = true) { if (Sort) this->style |= CBS_SORT; else this->style &= ~CBS_SORT; return this->me(); }
|
|
| 377 |
- DialogComboBoxBuilder &WithExactHeight(bool ExactHeight = true) { if (ExactHeight) this->style |= CBS_NOINTEGRALHEIGHT; else this->style &= ~CBS_NOINTEGRALHEIGHT; return this->me(); }
|
|
| 378 |
- DialogComboBoxBuilder &WithDisabledNoScroll(bool DisabledNoScroll = true) { if (DisabledNoScroll) this->style |= CBS_DISABLENOSCROLL; else this->style &= ~CBS_DISABLENOSCROLL; return this->me(); }
|
|
| 379 |
-#if WINVER >= 0x0400 |
|
| 380 |
- DialogComboBoxBuilder &WithAllLowercase(bool AllLowercase = true) { if (AllLowercase) this->style |= CBS_LOWERCASE; else this->style &= ~CBS_LOWERCASE; return this->me(); }
|
|
| 381 |
- DialogComboBoxBuilder &WithAllUppercase(bool AllUppercase = true) { if (AllUppercase) this->style |= CBS_UPPERCASE; else this->style &= ~CBS_UPPERCASE; return this->me(); }
|
|
| 382 |
-#endif |
|
| 383 |
-}; |
|
| 384 |
- |
|
| 385 |
-class DialogTemplate |
|
| 386 |
-{
|
|
| 387 |
- class DialogControl; |
|
| 388 |
- |
|
| 389 |
- typedef std::vector<std::unique_ptr<DialogControl>> Controls; |
|
| 390 |
- |
|
| 391 |
- class DialogControl |
|
| 392 |
- {
|
|
| 393 |
- protected: |
|
| 394 |
- DialogControlType controlType; |
|
| 395 |
- uint32_t style, exstyle; |
|
| 396 |
- Rect<short> rect; |
|
| 397 |
- short id; |
|
| 398 |
- std::unique_ptr<RelativePosition> relativePosition; |
|
| 399 |
- |
|
| 400 |
- friend class DialogTemplate; |
|
| 401 |
- DialogControl() : controlType(NO_CONTROL), style(0), exstyle(0), rect(), id(-1), relativePosition() { }
|
|
| 402 |
- DialogControl(const DialogControl &control) : controlType(control.controlType), style(control.style), exstyle(control.exstyle), rect(control.rect), id(control.id), |
|
| 403 |
- relativePosition(control.relativePosition.get() ? control.relativePosition->Clone() : nullptr) { }
|
|
| 404 |
- DialogControl &operator=(const DialogControl &control) |
|
| 405 |
- {
|
|
| 406 |
- this->controlType = control.controlType; |
|
| 407 |
- this->style = control.style; |
|
| 408 |
- this->exstyle = control.exstyle; |
|
| 409 |
- this->rect = control.rect; |
|
| 410 |
- this->id = control.id; |
|
| 411 |
- if (control.relativePosition.get()) |
|
| 412 |
- this->relativePosition.reset(control.relativePosition->Clone()); |
|
| 413 |
- else |
|
| 414 |
- this->relativePosition.reset(); |
|
| 415 |
- |
|
| 416 |
- return *this; |
|
| 417 |
- } |
|
| 418 |
- public: |
|
| 419 |
- virtual ~DialogControl() { }
|
|
| 420 |
- template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder) |
|
| 421 |
- {
|
|
| 422 |
- auto control = std::unique_ptr<Control>(new Control()); |
|
| 423 |
- |
|
| 424 |
- control->controlType = builder.controlType; |
|
| 425 |
- control->style = builder.style; |
|
| 426 |
- control->exstyle = builder.exstyle; |
|
| 427 |
- control->rect = builder.rect; |
|
| 428 |
- control->id = builder.id; |
|
| 429 |
- if (builder.relativePosition.get()) |
|
| 430 |
- control->relativePosition.reset(builder.relativePosition->Clone()); |
|
| 431 |
- |
|
| 432 |
- return control; |
|
| 433 |
- } |
|
| 434 |
- virtual uint16_t GetControlCount() const { return 1; }
|
|
| 435 |
- virtual short GetControlHeight() const { return this->rect.size.height; }
|
|
| 436 |
- virtual std::vector<uint8_t> GenerateControlTemplate() const = 0; |
|
| 437 |
- virtual DialogControl *Clone() const = 0; |
|
| 438 |
- }; |
|
| 439 |
- |
|
| 440 |
- class DialogGroup : public DialogControl |
|
| 441 |
- {
|
|
| 442 |
- protected: |
|
| 443 |
- DialogTemplate::Controls controls; |
|
| 444 |
- std::wstring groupName; |
|
| 445 |
- |
|
| 446 |
- friend class DialogTemplate; |
|
| 447 |
- friend class DialogControl; |
|
| 448 |
- DialogGroup() : DialogControl(), controls(), groupName(L"") { }
|
|
| 449 |
- DialogGroup(const DialogGroup &control) : DialogControl(control), controls(), groupName(control.groupName) |
|
| 450 |
- {
|
|
| 451 |
- 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())); });
|
|
| 452 |
- } |
|
| 453 |
- DialogGroup &operator=(const DialogGroup &control) |
|
| 454 |
- {
|
|
| 455 |
- DialogControl::operator=(control); |
|
| 456 |
- |
|
| 457 |
- this->controls.clear(); |
|
| 458 |
- 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())); });
|
|
| 459 |
- |
|
| 460 |
- this->groupName = control.groupName; |
|
| 461 |
- |
|
| 462 |
- return *this; |
|
| 463 |
- } |
|
| 464 |
- public: |
|
| 465 |
- static std::unique_ptr<DialogGroup> CreateControl(const DialogControlBuilder<DialogGroupBuilder> &builder) |
|
| 466 |
- {
|
|
| 467 |
- auto control = DialogControl::CreateControl<DialogGroup>(builder); |
|
| 468 |
- |
|
| 469 |
- control->groupName = dynamic_cast<const DialogGroupBuilder &>(builder).groupName; |
|
| 470 |
- |
|
| 471 |
- return control; |
|
| 472 |
- } |
|
| 473 |
- void CalculatePositions(bool doRightAndBottom = false); |
|
| 474 |
- void CalculateSize(); |
|
| 475 |
- uint16_t GetControlCount() const; |
|
| 476 |
- std::vector<uint8_t> GenerateControlTemplate() const; |
|
| 477 |
- DialogGroup *Clone() const { return new DialogGroup(*this); }
|
|
| 478 |
- }; |
|
| 479 |
- |
|
| 480 |
- class DialogControlWithoutLabel : public DialogControl |
|
| 481 |
- {
|
|
| 482 |
- protected: |
|
| 483 |
- uint16_t type; |
|
| 484 |
- |
|
| 485 |
- friend class DialogTemplate; |
|
| 486 |
- friend class DialogControl; |
|
| 487 |
- DialogControlWithoutLabel() : DialogControl(), type(0) { }
|
|
| 488 |
- DialogControlWithoutLabel(const DialogControlWithoutLabel &control) : DialogControl(control), type(control.type) { }
|
|
| 489 |
- DialogControlWithoutLabel &operator=(const DialogControlWithoutLabel &control) |
|
| 490 |
- {
|
|
| 491 |
- DialogControl::operator=(control); |
|
| 492 |
- |
|
| 493 |
- this->type = control.type; |
|
| 494 |
- |
|
| 495 |
- return *this; |
|
| 496 |
- } |
|
| 497 |
- public: |
|
| 498 |
- template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type) |
|
| 499 |
- {
|
|
| 500 |
- auto control = DialogControl::CreateControl<Control>(builder); |
|
| 501 |
- |
|
| 502 |
- control->type = Type; |
|
| 503 |
- |
|
| 504 |
- return control; |
|
| 505 |
- } |
|
| 506 |
- virtual std::vector<uint8_t> GenerateControlTemplate() const; |
|
| 507 |
- virtual DialogControlWithoutLabel *Clone() const { return new DialogControlWithoutLabel(*this); }
|
|
| 508 |
- }; |
|
| 509 |
- |
|
| 510 |
- class DialogControlWithLabel : public DialogControl |
|
| 511 |
- {
|
|
| 512 |
- protected: |
|
| 513 |
- uint16_t type; |
|
| 514 |
- std::wstring label; |
|
| 515 |
- |
|
| 516 |
- friend class DialogTemplate; |
|
| 517 |
- friend class DialogControl; |
|
| 518 |
- DialogControlWithLabel() : DialogControl(), type(0), label(L"") { }
|
|
| 519 |
- DialogControlWithLabel(const DialogControlWithLabel &control) : DialogControl(control), type(control.type), label(control.label) { }
|
|
| 520 |
- DialogControlWithLabel &operator=(const DialogControlWithLabel &control) |
|
| 521 |
- {
|
|
| 522 |
- DialogControl::operator=(control); |
|
| 523 |
- |
|
| 524 |
- this->type = control.type; |
|
| 525 |
- this->label = control.label; |
|
| 526 |
- |
|
| 527 |
- return *this; |
|
| 528 |
- } |
|
| 529 |
- public: |
|
| 530 |
- template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type) |
|
| 531 |
- {
|
|
| 532 |
- auto control = DialogControl::CreateControl<Control>(builder); |
|
| 533 |
- |
|
| 534 |
- control->type = Type; |
|
| 535 |
- control->label = dynamic_cast<const DialogControlWithLabelBuilder<Builder> &>(builder).label; |
|
| 536 |
- |
|
| 537 |
- return control; |
|
| 538 |
- } |
|
| 539 |
- virtual std::vector<uint8_t> GenerateControlTemplate() const; |
|
| 540 |
- virtual DialogControlWithLabel *Clone() const { return new DialogControlWithLabel(*this); }
|
|
| 541 |
- }; |
|
| 542 |
- |
|
| 543 |
- class DialogEditBox : public DialogControlWithoutLabel |
|
| 544 |
- {
|
|
| 545 |
- protected: |
|
| 546 |
- friend class DialogTemplate; |
|
| 547 |
- friend class DialogControl; |
|
| 548 |
- DialogEditBox() : DialogControlWithoutLabel() { }
|
|
| 549 |
- public: |
|
| 550 |
- static std::unique_ptr<DialogEditBox> CreateControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder) |
|
| 551 |
- {
|
|
| 552 |
- return DialogControlWithoutLabel::CreateControl<DialogEditBox>(builder, 0x0081); |
|
| 553 |
- } |
|
| 554 |
- }; |
|
| 555 |
- |
|
| 556 |
- class DialogLabel : public DialogControlWithLabel |
|
| 557 |
- {
|
|
| 558 |
- protected: |
|
| 559 |
- friend class DialogTemplate; |
|
| 560 |
- friend class DialogControl; |
|
| 561 |
- DialogLabel() : DialogControlWithLabel() { }
|
|
| 562 |
- public: |
|
| 563 |
- static std::unique_ptr<DialogLabel> CreateControl(const DialogControlBuilder<DialogLabelBuilder> &builder) |
|
| 564 |
- {
|
|
| 565 |
- return DialogControlWithLabel::CreateControl<DialogLabel>(builder, 0x0082); |
|
| 566 |
- } |
|
| 567 |
- }; |
|
| 568 |
- |
|
| 569 |
- class DialogButton : public DialogControlWithLabel |
|
| 570 |
- {
|
|
| 571 |
- protected: |
|
| 572 |
- friend class DialogTemplate; |
|
| 573 |
- friend class DialogControl; |
|
| 574 |
- DialogButton() : DialogControlWithLabel() { }
|
|
| 575 |
- public: |
|
| 576 |
- template<typename Builder> static std::unique_ptr<DialogButton> CreateControl(const DialogControlBuilder<Builder> &builder) |
|
| 577 |
- {
|
|
| 578 |
- return DialogControlWithLabel::CreateControl<DialogButton>(builder, 0x0080); |
|
| 579 |
- } |
|
| 580 |
- }; |
|
| 581 |
- |
|
| 582 |
- class DialogListBox : public DialogControlWithoutLabel |
|
| 583 |
- {
|
|
| 584 |
- protected: |
|
| 585 |
- friend class DialogTemplate; |
|
| 586 |
- friend class DialogControl; |
|
| 587 |
- DialogListBox() : DialogControlWithoutLabel() { }
|
|
| 588 |
- public: |
|
| 589 |
- static std::unique_ptr<DialogListBox> CreateControl(const DialogControlBuilder<DialogListBoxBuilder> &builder) |
|
| 590 |
- {
|
|
| 591 |
- return DialogControlWithoutLabel::CreateControl<DialogListBox>(builder, 0x0083); |
|
| 592 |
- } |
|
| 593 |
- }; |
|
| 594 |
- |
|
| 595 |
- class DialogComboBox : public DialogControlWithoutLabel |
|
| 596 |
- {
|
|
| 597 |
- protected: |
|
| 598 |
- friend class DialogTemplate; |
|
| 599 |
- friend class DialogControl; |
|
| 600 |
- DialogComboBox() : DialogControlWithoutLabel() { }
|
|
| 601 |
- public: |
|
| 602 |
- static std::unique_ptr<DialogComboBox> CreateControl(const DialogControlBuilder<DialogComboBoxBuilder> &builder) |
|
| 603 |
- {
|
|
| 604 |
- return DialogControlWithoutLabel::CreateControl<DialogComboBox>(builder, 0x0085); |
|
| 605 |
- } |
|
| 606 |
- short GetControlHeight() const { return (this->style & CBS_SIMPLE && !(this->style & CBS_DROPDOWNLIST)) ? this->rect.size.height : 14; }
|
|
| 607 |
- }; |
|
| 608 |
- |
|
| 609 |
- std::wstring title; |
|
| 610 |
- uint32_t style, exstyle; |
|
| 611 |
- std::wstring fontName; |
|
| 612 |
- uint16_t fontSizeInPts; |
|
| 613 |
- Size<short> size; |
|
| 614 |
- DialogTemplate::Controls controls; |
|
| 615 |
- std::vector<uint8_t> templateData; |
|
| 616 |
- |
|
| 617 |
- template<typename Builder> void AddControlToGroup(std::unique_ptr<DialogControl> &&control, const DialogControlBuilder<Builder> &builder) |
|
| 618 |
- {
|
|
| 619 |
- const DialogInGroupBuilder<Builder> &groupBuilder = dynamic_cast<const DialogInGroupBuilder<Builder> &>(builder); |
|
| 620 |
- if (groupBuilder.groupName.empty()) |
|
| 621 |
- {
|
|
| 622 |
- if (builder.index == -1) |
|
| 623 |
- this->controls.push_back(std::move(control)); |
|
| 624 |
- else |
|
| 625 |
- this->controls.insert(this->controls.begin() + builder.index, std::move(control)); |
|
| 626 |
- } |
|
| 627 |
- else |
|
| 628 |
- {
|
|
| 629 |
- for (auto curr = this->controls.begin(), end = this->controls.end(); curr != end; ++curr) |
|
| 630 |
- {
|
|
| 631 |
- if ((*curr)->controlType != GROUP_CONTROL) |
|
| 632 |
- continue; |
|
| 633 |
- DialogGroup *group = dynamic_cast<DialogGroup *>(curr->get()); |
|
| 634 |
- if (group->groupName == groupBuilder.groupName) |
|
| 635 |
- {
|
|
| 636 |
- if (builder.index == -1) |
|
| 637 |
- group->controls.push_back(std::move(control)); |
|
| 638 |
- else |
|
| 639 |
- group->controls.insert(group->controls.begin() + builder.index, std::move(control)); |
|
| 640 |
- return; |
|
| 641 |
- } |
|
| 642 |
- } |
|
| 643 |
- throw std::runtime_error("Group " + UtfConverter::ToUtf8(groupBuilder.groupName) + " was not found.");
|
|
| 644 |
- } |
|
| 645 |
- } |
|
| 646 |
- uint16_t GetTotalControlCount() const; |
|
| 647 |
- bool CalculateControlPosition(short index, bool doRightAndBottom = false); |
|
| 648 |
- void CalculateSize(); |
|
| 649 |
-public: |
|
| 650 |
- DialogTemplate() : title(L""), style(0), exstyle(0), fontName(L""), fontSizeInPts(0), size(), controls(), templateData() { }
|
|
| 651 |
- DialogTemplate(const DialogBuilder &builder) : title(builder.title), style(builder.style), exstyle(builder.exstyle), fontName(builder.fontName), fontSizeInPts(builder.fontSizeInPts), |
|
| 652 |
- size(builder.size), controls(), templateData() { }
|
|
| 653 |
- DialogTemplate(const DialogTemplate &dlg) : title(dlg.title), style(dlg.style), exstyle(dlg.style), fontName(dlg.fontName), fontSizeInPts(dlg.fontSizeInPts), size(dlg.size), |
|
| 654 |
- controls(), templateData() |
|
| 655 |
- {
|
|
| 656 |
- 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())); });
|
|
| 657 |
- } |
|
| 658 |
- DialogTemplate &operator=(const DialogBuilder &builder) |
|
| 659 |
- {
|
|
| 660 |
- this->title = builder.title; |
|
| 661 |
- this->style = builder.style; |
|
| 662 |
- this->exstyle = builder.exstyle; |
|
| 663 |
- this->fontName = builder.fontName; |
|
| 664 |
- this->fontSizeInPts = builder.fontSizeInPts; |
|
| 665 |
- this->size = builder.size; |
|
| 666 |
- if (builder.resetControls) |
|
| 667 |
- this->controls.clear(); |
|
| 668 |
- |
|
| 669 |
- return *this; |
|
| 670 |
- } |
|
| 671 |
- DialogTemplate &operator=(const DialogTemplate &dlg) |
|
| 672 |
- {
|
|
| 673 |
- this->title = dlg.title; |
|
| 674 |
- this->style = dlg.style; |
|
| 675 |
- this->exstyle = dlg.exstyle; |
|
| 676 |
- this->fontName = dlg.fontName; |
|
| 677 |
- this->fontSizeInPts = dlg.fontSizeInPts; |
|
| 678 |
- this->size = dlg.size; |
|
| 679 |
- this->controls.clear(); |
|
| 680 |
- 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())); });
|
|
| 681 |
- |
|
| 682 |
- return *this; |
|
| 683 |
- } |
|
| 684 |
- void AddGroupControl(const DialogControlBuilder<DialogGroupBuilder> &builder); |
|
| 685 |
- void AddEditBoxControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder); |
|
| 686 |
- void AddLabelControl(const DialogControlBuilder<DialogLabelBuilder> &builder); |
|
| 687 |
- void AddCheckBoxControl(const DialogControlBuilder<DialogCheckBoxBuilder> &builder); |
|
| 688 |
- void AddButtonControl(const DialogControlBuilder<DialogButtonBuilder> &builder); |
|
| 689 |
- void AddListBoxControl(const DialogControlBuilder<DialogListBoxBuilder> &builder); |
|
| 690 |
- void AddComboBoxControl(const DialogControlBuilder<DialogComboBoxBuilder> &builder); |
|
| 691 |
- void AutoSize(); |
|
| 692 |
- const DLGTEMPLATE *GenerateTemplate(); |
|
| 693 |
-}; |
|
| 694 |
- |
|
| 695 |
-#endif |
| ... | ... |
@@ -1,7 +1,7 @@ |
| 1 | 1 |
/* |
| 2 | 2 |
* Windows Dynamic Dialog Builder framework |
| 3 | 3 |
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com] |
| 4 |
- * Last modification on 2013-03-25 |
|
| 4 |
+ * Last modification on 2013-03-30 |
|
| 5 | 5 |
*/ |
| 6 | 6 |
|
| 7 | 7 |
#ifndef DIALOG_BUILDER_H |
| ... | ... |
@@ -400,7 +400,7 @@ class DialogTemplate |
| 400 | 400 |
friend class DialogTemplate; |
| 401 | 401 |
DialogControl() : controlType(NO_CONTROL), style(0), exstyle(0), rect(), id(-1), relativePosition() { }
|
| 402 | 402 |
DialogControl(const DialogControl &control) : controlType(control.controlType), style(control.style), exstyle(control.exstyle), rect(control.rect), id(control.id), |
| 403 |
- relativePosition(control.relativePosition.get() ? control.relativePosition->Clone() : NULL) { }
|
|
| 403 |
+ relativePosition(control.relativePosition.get() ? control.relativePosition->Clone() : nullptr) { }
|
|
| 404 | 404 |
DialogControl &operator=(const DialogControl &control) |
| 405 | 405 |
{
|
| 406 | 406 |
this->controlType = control.controlType; |
| ... | ... |
@@ -10,6 +10,7 @@ |
| 10 | 10 |
#include <string> |
| 11 | 11 |
#include <memory> |
| 12 | 12 |
#include <vector> |
| 13 |
+#include <algorithm> |
|
| 13 | 14 |
#include <stdexcept> |
| 14 | 15 |
#include "pstdint.h" |
| 15 | 16 |
#include "windowsh_wrapper.h" |
| ... | ... |
@@ -162,7 +163,7 @@ protected: |
| 162 | 163 |
Rect<short> rect; |
| 163 | 164 |
short id; |
| 164 | 165 |
int index; |
| 165 |
- std::auto_ptr<RelativePosition> relativePosition; |
|
| 166 |
+ std::unique_ptr<RelativePosition> relativePosition; |
|
| 166 | 167 |
|
| 167 | 168 |
T &me() { return dynamic_cast<T &>(*this); }
|
| 168 | 169 |
public: |
| ... | ... |
@@ -385,7 +386,7 @@ class DialogTemplate |
| 385 | 386 |
{
|
| 386 | 387 |
class DialogControl; |
| 387 | 388 |
|
| 388 |
- typedef std::vector<DialogControl *> Controls; |
|
| 389 |
+ typedef std::vector<std::unique_ptr<DialogControl>> Controls; |
|
| 389 | 390 |
|
| 390 | 391 |
class DialogControl |
| 391 | 392 |
{
|
| ... | ... |
@@ -394,7 +395,7 @@ class DialogTemplate |
| 394 | 395 |
uint32_t style, exstyle; |
| 395 | 396 |
Rect<short> rect; |
| 396 | 397 |
short id; |
| 397 |
- std::auto_ptr<RelativePosition> relativePosition; |
|
| 398 |
+ std::unique_ptr<RelativePosition> relativePosition; |
|
| 398 | 399 |
|
| 399 | 400 |
friend class DialogTemplate; |
| 400 | 401 |
DialogControl() : controlType(NO_CONTROL), style(0), exstyle(0), rect(), id(-1), relativePosition() { }
|
| ... | ... |
@@ -416,9 +417,9 @@ class DialogTemplate |
| 416 | 417 |
} |
| 417 | 418 |
public: |
| 418 | 419 |
virtual ~DialogControl() { }
|
| 419 |
- template<typename Control, typename Builder> static Control *CreateControl(const DialogControlBuilder<Builder> &builder) |
|
| 420 |
+ template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder) |
|
| 420 | 421 |
{
|
| 421 |
- Control *control = new Control(); |
|
| 422 |
+ auto control = std::unique_ptr<Control>(new Control()); |
|
| 422 | 423 |
|
| 423 | 424 |
control->controlType = builder.controlType; |
| 424 | 425 |
control->style = builder.style; |
| ... | ... |
@@ -447,30 +448,23 @@ class DialogTemplate |
| 447 | 448 |
DialogGroup() : DialogControl(), controls(), groupName(L"") { }
|
| 448 | 449 |
DialogGroup(const DialogGroup &control) : DialogControl(control), controls(), groupName(control.groupName) |
| 449 | 450 |
{
|
| 450 |
- for (auto curr = control.controls.begin(), end = control.controls.end(); curr != end; ++curr) |
|
| 451 |
- this->controls.push_back((*curr)->Clone()); |
|
| 451 |
+ 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())); });
|
|
| 452 | 452 |
} |
| 453 | 453 |
DialogGroup &operator=(const DialogGroup &control) |
| 454 | 454 |
{
|
| 455 | 455 |
DialogControl::operator=(control); |
| 456 | 456 |
|
| 457 |
- if (!this->controls.empty()) |
|
| 458 |
- this->ClearControls(); |
|
| 459 |
- for (auto curr = control.controls.begin(), end = control.controls.end(); curr != end; ++curr) |
|
| 460 |
- this->controls.push_back((*curr)->Clone()); |
|
| 457 |
+ this->controls.clear(); |
|
| 458 |
+ 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())); });
|
|
| 459 |
+ |
|
| 460 |
+ this->groupName = control.groupName; |
|
| 461 | 461 |
|
| 462 | 462 |
return *this; |
| 463 | 463 |
} |
| 464 |
- void ClearControls() |
|
| 465 |
- {
|
|
| 466 |
- for (auto curr = this->controls.begin(), end = this->controls.end(); curr != end; ++curr) |
|
| 467 |
- delete *curr; |
|
| 468 |
- } |
|
| 469 | 464 |
public: |
| 470 |
- ~DialogGroup() { this->ClearControls(); }
|
|
| 471 |
- static DialogGroup *CreateControl(const DialogControlBuilder<DialogGroupBuilder> &builder) |
|
| 465 |
+ static std::unique_ptr<DialogGroup> CreateControl(const DialogControlBuilder<DialogGroupBuilder> &builder) |
|
| 472 | 466 |
{
|
| 473 |
- DialogGroup *control = DialogControl::CreateControl<DialogGroup>(builder); |
|
| 467 |
+ auto control = DialogControl::CreateControl<DialogGroup>(builder); |
|
| 474 | 468 |
|
| 475 | 469 |
control->groupName = dynamic_cast<const DialogGroupBuilder &>(builder).groupName; |
| 476 | 470 |
|
| ... | ... |
@@ -501,9 +495,9 @@ class DialogTemplate |
| 501 | 495 |
return *this; |
| 502 | 496 |
} |
| 503 | 497 |
public: |
| 504 |
- template<typename Control, typename Builder> static Control *CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type) |
|
| 498 |
+ template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type) |
|
| 505 | 499 |
{
|
| 506 |
- Control *control = DialogControl::CreateControl<Control>(builder); |
|
| 500 |
+ auto control = DialogControl::CreateControl<Control>(builder); |
|
| 507 | 501 |
|
| 508 | 502 |
control->type = Type; |
| 509 | 503 |
|
| ... | ... |
@@ -533,9 +527,9 @@ class DialogTemplate |
| 533 | 527 |
return *this; |
| 534 | 528 |
} |
| 535 | 529 |
public: |
| 536 |
- template<typename Control, typename Builder> static Control *CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type) |
|
| 530 |
+ template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type) |
|
| 537 | 531 |
{
|
| 538 |
- Control *control = DialogControl::CreateControl<Control>(builder); |
|
| 532 |
+ auto control = DialogControl::CreateControl<Control>(builder); |
|
| 539 | 533 |
|
| 540 | 534 |
control->type = Type; |
| 541 | 535 |
control->label = dynamic_cast<const DialogControlWithLabelBuilder<Builder> &>(builder).label; |
| ... | ... |
@@ -553,7 +547,7 @@ class DialogTemplate |
| 553 | 547 |
friend class DialogControl; |
| 554 | 548 |
DialogEditBox() : DialogControlWithoutLabel() { }
|
| 555 | 549 |
public: |
| 556 |
- static DialogEditBox *CreateControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder) |
|
| 550 |
+ static std::unique_ptr<DialogEditBox> CreateControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder) |
|
| 557 | 551 |
{
|
| 558 | 552 |
return DialogControlWithoutLabel::CreateControl<DialogEditBox>(builder, 0x0081); |
| 559 | 553 |
} |
| ... | ... |
@@ -566,7 +560,7 @@ class DialogTemplate |
| 566 | 560 |
friend class DialogControl; |
| 567 | 561 |
DialogLabel() : DialogControlWithLabel() { }
|
| 568 | 562 |
public: |
| 569 |
- static DialogLabel *CreateControl(const DialogControlBuilder<DialogLabelBuilder> &builder) |
|
| 563 |
+ static std::unique_ptr<DialogLabel> CreateControl(const DialogControlBuilder<DialogLabelBuilder> &builder) |
|
| 570 | 564 |
{
|
| 571 | 565 |
return DialogControlWithLabel::CreateControl<DialogLabel>(builder, 0x0082); |
| 572 | 566 |
} |
| ... | ... |
@@ -579,7 +573,7 @@ class DialogTemplate |
| 579 | 573 |
friend class DialogControl; |
| 580 | 574 |
DialogButton() : DialogControlWithLabel() { }
|
| 581 | 575 |
public: |
| 582 |
- template<typename Builder> static DialogButton *CreateControl(const DialogControlBuilder<Builder> &builder) |
|
| 576 |
+ template<typename Builder> static std::unique_ptr<DialogButton> CreateControl(const DialogControlBuilder<Builder> &builder) |
|
| 583 | 577 |
{
|
| 584 | 578 |
return DialogControlWithLabel::CreateControl<DialogButton>(builder, 0x0080); |
| 585 | 579 |
} |
| ... | ... |
@@ -592,7 +586,7 @@ class DialogTemplate |
| 592 | 586 |
friend class DialogControl; |
| 593 | 587 |
DialogListBox() : DialogControlWithoutLabel() { }
|
| 594 | 588 |
public: |
| 595 |
- static DialogListBox *CreateControl(const DialogControlBuilder<DialogListBoxBuilder> &builder) |
|
| 589 |
+ static std::unique_ptr<DialogListBox> CreateControl(const DialogControlBuilder<DialogListBoxBuilder> &builder) |
|
| 596 | 590 |
{
|
| 597 | 591 |
return DialogControlWithoutLabel::CreateControl<DialogListBox>(builder, 0x0083); |
| 598 | 592 |
} |
| ... | ... |
@@ -605,7 +599,7 @@ class DialogTemplate |
| 605 | 599 |
friend class DialogControl; |
| 606 | 600 |
DialogComboBox() : DialogControlWithoutLabel() { }
|
| 607 | 601 |
public: |
| 608 |
- static DialogComboBox *CreateControl(const DialogControlBuilder<DialogComboBoxBuilder> &builder) |
|
| 602 |
+ static std::unique_ptr<DialogComboBox> CreateControl(const DialogControlBuilder<DialogComboBoxBuilder> &builder) |
|
| 609 | 603 |
{
|
| 610 | 604 |
return DialogControlWithoutLabel::CreateControl<DialogComboBox>(builder, 0x0085); |
| 611 | 605 |
} |
| ... | ... |
@@ -617,32 +611,32 @@ class DialogTemplate |
| 617 | 611 |
std::wstring fontName; |
| 618 | 612 |
uint16_t fontSizeInPts; |
| 619 | 613 |
Size<short> size; |
| 620 |
- Controls controls; |
|
| 614 |
+ DialogTemplate::Controls controls; |
|
| 621 | 615 |
std::vector<uint8_t> templateData; |
| 622 | 616 |
|
| 623 |
- template<typename Builder> void AddControlToGroup(DialogControl *control, const DialogControlBuilder<Builder> &builder) |
|
| 617 |
+ template<typename Builder> void AddControlToGroup(std::unique_ptr<DialogControl> &&control, const DialogControlBuilder<Builder> &builder) |
|
| 624 | 618 |
{
|
| 625 | 619 |
const DialogInGroupBuilder<Builder> &groupBuilder = dynamic_cast<const DialogInGroupBuilder<Builder> &>(builder); |
| 626 | 620 |
if (groupBuilder.groupName.empty()) |
| 627 | 621 |
{
|
| 628 | 622 |
if (builder.index == -1) |
| 629 |
- this->controls.push_back(control); |
|
| 623 |
+ this->controls.push_back(std::move(control)); |
|
| 630 | 624 |
else |
| 631 |
- this->controls.insert(this->controls.begin() + builder.index, control); |
|
| 625 |
+ this->controls.insert(this->controls.begin() + builder.index, std::move(control)); |
|
| 632 | 626 |
} |
| 633 | 627 |
else |
| 634 | 628 |
{
|
| 635 |
- for (DialogTemplate::Controls::iterator curr = this->controls.begin(), end = this->controls.end(); curr != end; ++curr) |
|
| 629 |
+ for (auto curr = this->controls.begin(), end = this->controls.end(); curr != end; ++curr) |
|
| 636 | 630 |
{
|
| 637 | 631 |
if ((*curr)->controlType != GROUP_CONTROL) |
| 638 | 632 |
continue; |
| 639 |
- DialogGroup *group = dynamic_cast<DialogGroup *>(*curr); |
|
| 633 |
+ DialogGroup *group = dynamic_cast<DialogGroup *>(curr->get()); |
|
| 640 | 634 |
if (group->groupName == groupBuilder.groupName) |
| 641 | 635 |
{
|
| 642 | 636 |
if (builder.index == -1) |
| 643 |
- group->controls.push_back(control); |
|
| 637 |
+ group->controls.push_back(std::move(control)); |
|
| 644 | 638 |
else |
| 645 |
- group->controls.insert(group->controls.begin() + builder.index, control); |
|
| 639 |
+ group->controls.insert(group->controls.begin() + builder.index, std::move(control)); |
|
| 646 | 640 |
return; |
| 647 | 641 |
} |
| 648 | 642 |
} |
| ... | ... |
@@ -652,11 +646,6 @@ class DialogTemplate |
| 652 | 646 |
uint16_t GetTotalControlCount() const; |
| 653 | 647 |
bool CalculateControlPosition(short index, bool doRightAndBottom = false); |
| 654 | 648 |
void CalculateSize(); |
| 655 |
- void ClearControls() |
|
| 656 |
- {
|
|
| 657 |
- for (auto curr = this->controls.begin(), end = this->controls.end(); curr != end; ++curr) |
|
| 658 |
- delete *curr; |
|
| 659 |
- } |
|
| 660 | 649 |
public: |
| 661 | 650 |
DialogTemplate() : title(L""), style(0), exstyle(0), fontName(L""), fontSizeInPts(0), size(), controls(), templateData() { }
|
| 662 | 651 |
DialogTemplate(const DialogBuilder &builder) : title(builder.title), style(builder.style), exstyle(builder.exstyle), fontName(builder.fontName), fontSizeInPts(builder.fontSizeInPts), |
| ... | ... |
@@ -664,8 +653,7 @@ public: |
| 664 | 653 |
DialogTemplate(const DialogTemplate &dlg) : title(dlg.title), style(dlg.style), exstyle(dlg.style), fontName(dlg.fontName), fontSizeInPts(dlg.fontSizeInPts), size(dlg.size), |
| 665 | 654 |
controls(), templateData() |
| 666 | 655 |
{
|
| 667 |
- for (auto curr = dlg.controls.begin(), end = dlg.controls.end(); curr != end; ++curr) |
|
| 668 |
- this->controls.push_back((*curr)->Clone()); |
|
| 656 |
+ 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())); });
|
|
| 669 | 657 |
} |
| 670 | 658 |
DialogTemplate &operator=(const DialogBuilder &builder) |
| 671 | 659 |
{
|
| ... | ... |
@@ -675,8 +663,8 @@ public: |
| 675 | 663 |
this->fontName = builder.fontName; |
| 676 | 664 |
this->fontSizeInPts = builder.fontSizeInPts; |
| 677 | 665 |
this->size = builder.size; |
| 678 |
- if (builder.resetControls && !this->controls.empty()) |
|
| 679 |
- this->ClearControls(); |
|
| 666 |
+ if (builder.resetControls) |
|
| 667 |
+ this->controls.clear(); |
|
| 680 | 668 |
|
| 681 | 669 |
return *this; |
| 682 | 670 |
} |
| ... | ... |
@@ -688,14 +676,11 @@ public: |
| 688 | 676 |
this->fontName = dlg.fontName; |
| 689 | 677 |
this->fontSizeInPts = dlg.fontSizeInPts; |
| 690 | 678 |
this->size = dlg.size; |
| 691 |
- if (!this->controls.empty()) |
|
| 692 |
- this->ClearControls(); |
|
| 693 |
- for (auto curr = dlg.controls.begin(), end = dlg.controls.end(); curr != end; ++curr) |
|
| 694 |
- this->controls.push_back((*curr)->Clone()); |
|
| 679 |
+ this->controls.clear(); |
|
| 680 |
+ 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())); });
|
|
| 695 | 681 |
|
| 696 | 682 |
return *this; |
| 697 | 683 |
} |
| 698 |
- ~DialogTemplate() { this->ClearControls(); }
|
|
| 699 | 684 |
void AddGroupControl(const DialogControlBuilder<DialogGroupBuilder> &builder); |
| 700 | 685 |
void AddEditBoxControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder); |
| 701 | 686 |
void AddLabelControl(const DialogControlBuilder<DialogLabelBuilder> &builder); |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,710 @@ |
| 1 |
+/* |
|
| 2 |
+ * Windows Dynamic Dialog Builder framework |
|
| 3 |
+ * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com] |
|
| 4 |
+ * Last modification on 2013-03-25 |
|
| 5 |
+ */ |
|
| 6 |
+ |
|
| 7 |
+#ifndef DIALOG_BUILDER_H |
|
| 8 |
+#define DIALOG_BUILDER_H |
|
| 9 |
+ |
|
| 10 |
+#include <string> |
|
| 11 |
+#include <memory> |
|
| 12 |
+#include <vector> |
|
| 13 |
+#include <stdexcept> |
|
| 14 |
+#include "pstdint.h" |
|
| 15 |
+#include "windowsh_wrapper.h" |
|
| 16 |
+#include "UtfConverter.h" |
|
| 17 |
+ |
|
| 18 |
+template<typename T> struct Point |
|
| 19 |
+{
|
|
| 20 |
+ T x, y; |
|
| 21 |
+ |
|
| 22 |
+ Point() : x(), y() { }
|
|
| 23 |
+ Point(T X, T Y) : x(X), y(Y) { }
|
|
| 24 |
+}; |
|
| 25 |
+ |
|
| 26 |
+template<typename T> struct Size |
|
| 27 |
+{
|
|
| 28 |
+ T width, height; |
|
| 29 |
+ |
|
| 30 |
+ Size() : width(), height() { }
|
|
| 31 |
+ Size(T Width, T Height) : width(Width), height(Height) { }
|
|
| 32 |
+}; |
|
| 33 |
+ |
|
| 34 |
+template<typename T> struct Rect |
|
| 35 |
+{
|
|
| 36 |
+ Point<T> position; |
|
| 37 |
+ Size<T> size; |
|
| 38 |
+ |
|
| 39 |
+ Rect() : position(), size() { }
|
|
| 40 |
+ Rect(Point<T> Position, Size<T> Sz) : position(Position), size(Sz) { }
|
|
| 41 |
+ Rect(T X, T Y, T Width, T Height) : position(X, Y), size(Width, Height) { }
|
|
| 42 |
+}; |
|
| 43 |
+ |
|
| 44 |
+class RelativePosition |
|
| 45 |
+{
|
|
| 46 |
+public: |
|
| 47 |
+ Point<short> relativePosition; |
|
| 48 |
+ enum BaseType |
|
| 49 |
+ {
|
|
| 50 |
+ TO_PARENT, |
|
| 51 |
+ TO_SIBLING |
|
| 52 |
+ } type; |
|
| 53 |
+ enum PositionType |
|
| 54 |
+ {
|
|
| 55 |
+ FROM_TOP, |
|
| 56 |
+ FROM_BOTTOM, |
|
| 57 |
+ FROM_LEFT, |
|
| 58 |
+ FROM_RIGHT, |
|
| 59 |
+ FROM_TOPLEFT, |
|
| 60 |
+ FROM_BOTTOMLEFT, |
|
| 61 |
+ FROM_TOPRIGHT, |
|
| 62 |
+ FROM_BOTTOMRIGHT |
|
| 63 |
+ } positionType; |
|
| 64 |
+ |
|
| 65 |
+ RelativePosition(Point<short> RelPosition, BaseType Type, PositionType PosType) : relativePosition(RelPosition), type(Type), positionType(PosType) { }
|
|
| 66 |
+ virtual ~RelativePosition() { }
|
|
| 67 |
+ virtual RelativePosition *Clone() const = 0; |
|
| 68 |
+ Point<short> CalculatePosition(Rect<short> child, Rect<short> other) |
|
| 69 |
+ {
|
|
| 70 |
+ Point<short> newPosition = child.position; |
|
| 71 |
+ if (this->relativePosition.y != -1) |
|
| 72 |
+ {
|
|
| 73 |
+ if (this->positionType == FROM_TOP || this->positionType == FROM_TOPLEFT || this->positionType == FROM_TOPRIGHT) |
|
| 74 |
+ newPosition.y = other.position.y + this->relativePosition.y; |
|
| 75 |
+ if (this->positionType == FROM_BOTTOM || this->positionType == FROM_BOTTOMLEFT || this->positionType == FROM_BOTTOMRIGHT) |
|
| 76 |
+ newPosition.y = other.position.y + other.size.height + this->relativePosition.y; |
|
| 77 |
+ } |
|
| 78 |
+ if (this->relativePosition.x != -1) |
|
| 79 |
+ {
|
|
| 80 |
+ if (this->positionType == FROM_LEFT || this->positionType == FROM_TOPLEFT || this->positionType == FROM_BOTTOMLEFT) |
|
| 81 |
+ newPosition.x = other.position.x + this->relativePosition.x; |
|
| 82 |
+ if (this->positionType == FROM_RIGHT || this->positionType == FROM_TOPRIGHT || this->positionType == FROM_BOTTOMRIGHT) |
|
| 83 |
+ newPosition.x = other.position.x + other.size.width + this->relativePosition.x; |
|
| 84 |
+ } |
|
| 85 |
+ return newPosition; |
|
| 86 |
+ } |
|
| 87 |
+}; |
|
| 88 |
+ |
|
| 89 |
+class RelativePositionToParent : public RelativePosition |
|
| 90 |
+{
|
|
| 91 |
+public: |
|
| 92 |
+ RelativePositionToParent(Point<short> RelPosition, PositionType PosType) : RelativePosition(RelPosition, TO_PARENT, PosType) { }
|
|
| 93 |
+ RelativePositionToParent *Clone() const { return new RelativePositionToParent(this->relativePosition, this->positionType); }
|
|
| 94 |
+}; |
|
| 95 |
+ |
|
| 96 |
+class RelativePositionToSibling : public RelativePosition |
|
| 97 |
+{
|
|
| 98 |
+public: |
|
| 99 |
+ short siblingsBack; |
|
| 100 |
+ |
|
| 101 |
+ RelativePositionToSibling(Point<short> RelPosition, PositionType PosType, short SiblingsBack = 1) : RelativePosition(RelPosition, TO_SIBLING, PosType), siblingsBack(SiblingsBack) { }
|
|
| 102 |
+ RelativePositionToSibling *Clone() const { return new RelativePositionToSibling(this->relativePosition, this->positionType, this->siblingsBack); }
|
|
| 103 |
+}; |
|
| 104 |
+ |
|
| 105 |
+enum DialogControlType |
|
| 106 |
+{
|
|
| 107 |
+ NO_CONTROL, |
|
| 108 |
+ GROUP_CONTROL, |
|
| 109 |
+ EDITBOX_CONTROL, |
|
| 110 |
+ LABEL_CONTROL, |
|
| 111 |
+ CHECKBOX_CONTROL, |
|
| 112 |
+ BUTTON_CONTROL, |
|
| 113 |
+ LISTBOX_CONTROL, |
|
| 114 |
+ COMBOBOX_CONTROL |
|
| 115 |
+}; |
|
| 116 |
+ |
|
| 117 |
+class DialogTemplate; |
|
| 118 |
+ |
|
| 119 |
+class DialogBuilder |
|
| 120 |
+{
|
|
| 121 |
+protected: |
|
| 122 |
+ friend class DialogTemplate; |
|
| 123 |
+ std::wstring title, fontName; |
|
| 124 |
+ uint32_t style, exstyle; |
|
| 125 |
+ uint16_t fontSizeInPts; |
|
| 126 |
+ Size<short> size; |
|
| 127 |
+ bool resetControls; |
|
| 128 |
+public: |
|
| 129 |
+ DialogBuilder() : title(L""), fontName(L""), style(0), exstyle(0), fontSizeInPts(0), size(), resetControls(false) { }
|
|
| 130 |
+ DialogBuilder &WithTitle(const std::wstring &Title) { this->title = Title; return *this; }
|
|
| 131 |
+ DialogBuilder &WithFont(const std::wstring &FontName, uint16_t FontSizeInPts) { this->fontName = FontName; this->fontSizeInPts = FontSizeInPts; return *this; }
|
|
| 132 |
+ DialogBuilder &WithSize(short Width, short Height) { this->size.width = Width; this->size.height = Height; return *this; }
|
|
| 133 |
+ DialogBuilder &WithSize(Size<short> Sz) { this->size = Sz; return *this; }
|
|
| 134 |
+ DialogBuilder &ResetControls(bool Reset = true) { this->resetControls = Reset; return *this; }
|
|
| 135 |
+ DialogBuilder &IsOverlapped() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_OVERLAPPED; return *this; }
|
|
| 136 |
+ DialogBuilder &IsPopup() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_POPUP; return *this; }
|
|
| 137 |
+ DialogBuilder &IsChild() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_CHILD; return *this; }
|
|
| 138 |
+ DialogBuilder &WithBorder(bool Border = true) { if (Border) this->style |= WS_BORDER; else this->style &= ~WS_BORDER; return *this; }
|
|
| 139 |
+ DialogBuilder &WithDialogFrame(bool DialogFrame = true) { if (DialogFrame) this->style |= WS_DLGFRAME; else this->style &= ~WS_DLGFRAME; return *this; }
|
|
| 140 |
+ DialogBuilder &WithVerticalScrollbar(bool VerticalScrollbar = true) { if (VerticalScrollbar) this->style |= WS_VSCROLL; else this->style &= ~WS_VSCROLL; return *this; }
|
|
| 141 |
+ DialogBuilder &WithHorizontalScrollbar(bool HorizontalScrollbar = true) { if (HorizontalScrollbar) this->style |= WS_HSCROLL; else this->style &= ~WS_HSCROLL; return *this; }
|
|
| 142 |
+ DialogBuilder &WithSystemMenu(bool SystemMenu = true) { if (SystemMenu) this->style |= WS_SYSMENU; else this->style &= ~WS_SYSMENU; return *this; }
|
|
| 143 |
+ DialogBuilder &WithSizingBorder(bool SizingBorder = true) { if (SizingBorder) this->style |= WS_THICKFRAME; else this->style &= ~WS_THICKFRAME; return *this; }
|
|
| 144 |
+ DialogBuilder &WithMinimizeBox(bool MinimizeBox = true) { if (MinimizeBox) this->style |= WS_MINIMIZEBOX; else this->style &= ~WS_MINIMIZEBOX; return *this; }
|
|
| 145 |
+ DialogBuilder &WithMaximizeBox(bool MaximizeBox = true) { if (MaximizeBox) this->style |= WS_MAXIMIZEBOX; else this->style &= ~WS_MAXIMIZEBOX; return *this; }
|
|
| 146 |
+ DialogBuilder &WithDialogModalFrame(bool DialogModalFrame = true) { if (DialogModalFrame) this->exstyle |= WS_EX_DLGMODALFRAME; else this->exstyle &= ~WS_EX_DLGMODALFRAME; return *this; }
|
|
| 147 |
+#if WINVER >= 0x0400 |
|
| 148 |
+ DialogBuilder &WithRaisedEdge(bool RaisedEdge = true) { if (RaisedEdge) this->exstyle |= WS_EX_WINDOWEDGE; else this->exstyle &= ~WS_EX_WINDOWEDGE; return *this; }
|
|
| 149 |
+ DialogBuilder &WithSunkenEdge(bool SunkenEdge = true) { if (SunkenEdge) this->exstyle |= WS_EX_CLIENTEDGE; else this->exstyle &= ~WS_EX_CLIENTEDGE; return *this; }
|
|
| 150 |
+ DialogBuilder &WithContextHelp(bool ContextHelp = true) { if (ContextHelp) this->exstyle |= WS_EX_CONTEXTHELP; else this->exstyle &= ~WS_EX_CONTEXTHELP; return *this; }
|
|
| 151 |
+ DialogBuilder &IsControlWindow(bool ControlWindow = true) { if (ControlWindow) this->style |= DS_CONTROL; else this->style &= ~DS_CONTROL; return *this; }
|
|
| 152 |
+ DialogBuilder &IsCentered(bool Centered = true) { if (Centered) this->style |= DS_CENTER; else this->style &= ~DS_CENTER; return *this; }
|
|
| 153 |
+#endif |
|
| 154 |
+}; |
|
| 155 |
+ |
|
| 156 |
+template<class T> class DialogControlBuilder |
|
| 157 |
+{
|
|
| 158 |
+protected: |
|
| 159 |
+ friend class DialogTemplate; |
|
| 160 |
+ DialogControlType controlType; |
|
| 161 |
+ uint32_t style, exstyle; |
|
| 162 |
+ Rect<short> rect; |
|
| 163 |
+ short id; |
|
| 164 |
+ int index; |
|
| 165 |
+ std::auto_ptr<RelativePosition> relativePosition; |
|
| 166 |
+ |
|
| 167 |
+ T &me() { return dynamic_cast<T &>(*this); }
|
|
| 168 |
+public: |
|
| 169 |
+ DialogControlBuilder(DialogControlType Type = NO_CONTROL) : controlType(Type), style(0), exstyle(0), rect(), id(-1), index(-1), relativePosition() { }
|
|
| 170 |
+ virtual ~DialogControlBuilder() { }
|
|
| 171 |
+ T &WithPosition(short X, short Y) { this->rect.position.x = X; this->rect.position.y = Y; return this->me(); }
|
|
| 172 |
+ T &WithPosition(Point<short> Position) { this->rect.position = Position; return this->me(); }
|
|
| 173 |
+ T &WithRelativePositionToParent(RelativePosition::PositionType PosType, Point<short> RelativePosition) |
|
| 174 |
+ {
|
|
| 175 |
+ this->relativePosition.reset(new RelativePositionToParent(RelativePosition, PosType)); |
|
| 176 |
+ return this->me(); |
|
| 177 |
+ } |
|
| 178 |
+ T &WithRelativePositionToSibling(RelativePosition::PositionType PosType, Point<short> RelativePosition, short SiblingsBack = 1) |
|
| 179 |
+ {
|
|
| 180 |
+ this->relativePosition.reset(new RelativePositionToSibling(RelativePosition, PosType, SiblingsBack)); |
|
| 181 |
+ return this->me(); |
|
| 182 |
+ } |
|
| 183 |
+ T &WithSize(short Width, short Height) { this->rect.size.width = Width; this->rect.size.height = Height; return this->me(); }
|
|
| 184 |
+ T &WithSize(Size<short> Sz) { this->rect.size = Sz; return this->me(); }
|
|
| 185 |
+ T &WithID(short ID) { this->id = ID; return this->me(); }
|
|
| 186 |
+ T &AtIndex(int Index) { this->index = Index; return this->me(); }
|
|
| 187 |
+ T &IsDisabled(bool Disabled = true) { if (Disabled) this->style |= WS_DISABLED; else this->style &= ~WS_DISABLED; return this->me(); }
|
|
| 188 |
+ T &WithBorder(bool ThinBorder = true) { if (ThinBorder) this->style |= WS_BORDER; else this->style &= ~WS_BORDER; return this->me(); }
|
|
| 189 |
+ T &WithVerticalScrollbar(bool VerticalScrollbar = true) { if (VerticalScrollbar) this->style |= WS_VSCROLL; else this->style &= ~WS_VSCROLL; return this->me(); }
|
|
| 190 |
+ T &WithHorizontalScrollbar(bool HorizontalScrollbar = true) { if (HorizontalScrollbar) this->style |= WS_HSCROLL; else this->style &= ~WS_HSCROLL; return this->me(); }
|
|
| 191 |
+ T &WithTabStop(bool TabStop = true) { if (TabStop) this->style |= WS_TABSTOP; else this->style &= ~WS_TABSTOP; return this->me(); }
|
|
| 192 |
+#if WINVER >= 0x0400 |
|
| 193 |
+ T &WithRaisedEdge(bool RaisedEdge = true) { if (RaisedEdge) this->exstyle |= WS_EX_WINDOWEDGE; else this->exstyle &= ~WS_EX_WINDOWEDGE; return this->me(); }
|
|
| 194 |
+ T &WithSunkenEdge(bool SunkenEdge = true) { if (SunkenEdge) this->exstyle |= WS_EX_CLIENTEDGE; else this->exstyle &= ~WS_EX_CLIENTEDGE; return this->me(); }
|
|
| 195 |
+#endif |
|
| 196 |
+}; |
|
| 197 |
+ |
|
| 198 |
+class DialogGroupBuilder : public DialogControlBuilder<DialogGroupBuilder> |
|
| 199 |
+{
|
|
| 200 |
+protected: |
|
| 201 |
+ friend class DialogTemplate; |
|
| 202 |
+ std::wstring groupName; |
|
| 203 |
+public: |
|
| 204 |
+ DialogGroupBuilder(const std::wstring &newGroupName) : DialogControlBuilder(GROUP_CONTROL), groupName(newGroupName) { }
|
|
| 205 |
+}; |
|
| 206 |
+ |
|
| 207 |
+template<class T> class DialogInGroupBuilder : public DialogControlBuilder<T> |
|
| 208 |
+{
|
|
| 209 |
+protected: |
|
| 210 |
+ friend class DialogTemplate; |
|
| 211 |
+ std::wstring groupName; |
|
| 212 |
+public: |
|
| 213 |
+ DialogInGroupBuilder(DialogControlType Type) : DialogControlBuilder<T>(Type), groupName(L"") { }
|
|
| 214 |
+ T &InGroup(const std::wstring &GroupName) { this->groupName = GroupName; return this->me(); }
|
|
| 215 |
+}; |
|
| 216 |
+ |
|
| 217 |
+class DialogEditBoxBuilder : public DialogInGroupBuilder<DialogEditBoxBuilder> |
|
| 218 |
+{
|
|
| 219 |
+protected: |
|
| 220 |
+ friend class DialogTemplate; |
|
| 221 |
+public: |
|
| 222 |
+ DialogEditBoxBuilder() : DialogInGroupBuilder(EDITBOX_CONTROL) { }
|
|
| 223 |
+ DialogEditBoxBuilder &IsLeftJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_LEFT; return this->me(); }
|
|
| 224 |
+ DialogEditBoxBuilder &IsCenterJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_CENTER; return this->me(); }
|
|
| 225 |
+ DialogEditBoxBuilder &IsRightJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_RIGHT; return this->me(); }
|
|
| 226 |
+ DialogEditBoxBuilder &IsMultiline(bool Multiline = true) { if (Multiline) this->style |= ES_MULTILINE; else this->style &= ~ES_MULTILINE; return this->me(); }
|
|
| 227 |
+ DialogEditBoxBuilder &WithAllUppercase(bool AllUppercase = true) { if (AllUppercase) this->style |= ES_UPPERCASE; else this->style &= ~ES_UPPERCASE; return this->me(); }
|
|
| 228 |
+ DialogEditBoxBuilder &WithAllLowercase(bool AllLowercase = true) { if (AllLowercase) this->style |= ES_LOWERCASE; else this->style &= ~ES_LOWERCASE; return this->me(); }
|
|
| 229 |
+ DialogEditBoxBuilder &IsPasswordInput(bool PasswordInput = true) { if (PasswordInput) this->style |= ES_PASSWORD; else this->style &= ~ES_PASSWORD; return this->me(); }
|
|
| 230 |
+ DialogEditBoxBuilder &WithAutoVScroll(bool AutoVScroll = true) { if (AutoVScroll) this->style |= ES_AUTOVSCROLL; else this->style &= ~ES_AUTOVSCROLL; return this->me(); }
|
|
| 231 |
+ DialogEditBoxBuilder &WithAutoHScroll(bool AutoHScroll = true) { if (AutoHScroll) this->style |= ES_AUTOHSCROLL; else this->style &= ~ES_AUTOHSCROLL; return this->me(); }
|
|
| 232 |
+ DialogEditBoxBuilder &WithDontHideSelection(bool DontHideSelection = true) { if (DontHideSelection) this->style |= ES_NOHIDESEL; else this->style &= ~ES_NOHIDESEL; return this->me(); }
|
|
| 233 |
+ DialogEditBoxBuilder &IsReadOnly(bool ReadOnly = true) { if (ReadOnly) this->style |= ES_READONLY; else this->style &= ~ES_READONLY; return this->me(); }
|
|
| 234 |
+ DialogEditBoxBuilder &WithWantReturn(bool WantReturn = true) { if (WantReturn) this->style |= ES_WANTRETURN; else this->style &= ~ES_WANTRETURN; return this->me(); }
|
|
| 235 |
+}; |
|
| 236 |
+ |
|
| 237 |
+template<class T> class DialogControlWithLabelBuilder : public DialogInGroupBuilder<T> |
|
| 238 |
+{
|
|
| 239 |
+protected: |
|
| 240 |
+ friend class DialogTemplate; |
|
| 241 |
+ std::wstring label; |
|
| 242 |
+public: |
|
| 243 |
+ DialogControlWithLabelBuilder(DialogControlType Type, const std::wstring &Label) : DialogInGroupBuilder<T>(Type), label(Label) { }
|
|
| 244 |
+}; |
|
| 245 |
+ |
|
| 246 |
+class DialogLabelBuilder : public DialogControlWithLabelBuilder<DialogLabelBuilder> |
|
| 247 |
+{
|
|
| 248 |
+protected: |
|
| 249 |
+ friend class DialogTemplate; |
|
| 250 |
+public: |
|
| 251 |
+ DialogLabelBuilder(const std::wstring &Label) : DialogControlWithLabelBuilder(LABEL_CONTROL, Label) { }
|
|
| 252 |
+ DialogLabelBuilder &IsLeftJustified(bool WithWordWrap = false) |
|
| 253 |
+ {
|
|
| 254 |
+ this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); |
|
| 255 |
+ if (WithWordWrap) |
|
| 256 |
+ this->style |= SS_LEFTNOWORDWRAP; |
|
| 257 |
+ else |
|
| 258 |
+ this->style |= SS_LEFT; |
|
| 259 |
+ return this->me(); |
|
| 260 |
+ } |
|
| 261 |
+ DialogLabelBuilder &IsCenterJustified() { this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); this->style |= SS_CENTER; return this->me(); }
|
|
| 262 |
+ DialogLabelBuilder &IsRightJustified() { this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); this->style |= SS_RIGHT; return this->me(); }
|
|
| 263 |
+ DialogLabelBuilder &WithAmpsNotTranslated(bool AmpsNotTranslated = true) { if (AmpsNotTranslated) this->style |= SS_NOPREFIX; else this->style &= ~SS_NOPREFIX; return this->me(); }
|
|
| 264 |
+#if WINVER >= 0x0400 |
|
| 265 |
+ DialogLabelBuilder &WithNotify(bool Notify = true) { if (Notify) this->style |= SS_NOTIFY; else this->style &= ~SS_NOTIFY; return this->me(); }
|
|
| 266 |
+#endif |
|
| 267 |
+}; |
|
| 268 |
+ |
|
| 269 |
+template<class T> class DialogButtonBaseBuilder : public DialogControlWithLabelBuilder<T> |
|
| 270 |
+{
|
|
| 271 |
+protected: |
|
| 272 |
+ friend class DialogTemplate; |
|
| 273 |
+public: |
|
| 274 |
+ DialogButtonBaseBuilder(DialogControlType Type, const std::wstring &Label) : DialogControlWithLabelBuilder<T>(Type, Label) { }
|
|
| 275 |
+#if WINVER >= 0x0400 |
|
| 276 |
+ T &IsLeftJustified(bool LeftJustified = true) |
|
| 277 |
+ {
|
|
| 278 |
+ if (LeftJustified) |
|
| 279 |
+ {
|
|
| 280 |
+ this->style |= BS_LEFT; |
|
| 281 |
+ this->style &= ~BS_RIGHT; |
|
| 282 |
+ } |
|
| 283 |
+ else |
|
| 284 |
+ this->style &= ~BS_LEFT; |
|
| 285 |
+ return this->me(); |
|
| 286 |
+ } |
|
| 287 |
+ T &IsRightJustified(bool RightJustified = true) |
|
| 288 |
+ {
|
|
| 289 |
+ if (RightJustified) |
|
| 290 |
+ {
|
|
| 291 |
+ this->style |= BS_RIGHT; |
|
| 292 |
+ this->style &= ~BS_LEFT; |
|
| 293 |
+ } |
|
| 294 |
+ else |
|
| 295 |
+ this->style &= ~BS_RIGHT; |
|
| 296 |
+ return this->me(); |
|
| 297 |
+ } |
|
| 298 |
+ T &IsCenterJustified(bool CenterJustified = true) { if (CenterJustified) this->style |= BS_CENTER; else this->style &= ~BS_CENTER; return this->me(); }
|
|
| 299 |
+ T &WithVerticalTop(bool VerticalTop = true) |
|
| 300 |
+ {
|
|
| 301 |
+ if (VerticalTop) |
|
| 302 |
+ {
|
|
| 303 |
+ this->style |= BS_TOP; |
|
| 304 |
+ this->style &= ~BS_BOTTOM; |
|
| 305 |
+ } |
|
| 306 |
+ else |
|
| 307 |
+ this->style &= ~BS_TOP; |
|
| 308 |
+ return this->me(); |
|
| 309 |
+ } |
|
| 310 |
+ T &WithVerticalBottom(bool VerticalBottom = true) |
|
| 311 |
+ {
|
|
| 312 |
+ if (VerticalBottom) |
|
| 313 |
+ {
|
|
| 314 |
+ this->style |= BS_BOTTOM; |
|
| 315 |
+ this->style &= ~BS_TOP; |
|
| 316 |
+ } |
|
| 317 |
+ else |
|
| 318 |
+ this->style &= ~BS_BOTTOM; |
|
| 319 |
+ return this->me(); |
|
| 320 |
+ } |
|
| 321 |
+ T &WithVerticalCenter(bool VerticalCenter = true) { if (VerticalCenter) this->style |= BS_VCENTER; else this->style &= ~BS_VCENTER; return this->me(); }
|
|
| 322 |
+ T &IsMultiline(bool Multiline = true) { if (Multiline) this->style |= BS_MULTILINE; else this->style &= ~BS_MULTILINE; return this->me(); }
|
|
| 323 |
+ T &WithNotify(bool Notify = true) { if (Notify) this->style |= BS_NOTIFY; else this->style &= ~BS_NOTIFY; return this->me(); }
|
|
| 324 |
+ T &IsFlat(bool Flat = true) { if (Flat) this->style |= BS_FLAT; else this->style &= ~BS_FLAT; return this->me(); }
|
|
| 325 |
+#endif |
|
| 326 |
+}; |
|
| 327 |
+ |
|
| 328 |
+class DialogButtonBuilder : public DialogButtonBaseBuilder<DialogButtonBuilder> |
|
| 329 |
+{
|
|
| 330 |
+protected: |
|
| 331 |
+ friend class DialogTemplate; |
|
| 332 |
+public: |
|
| 333 |
+ DialogButtonBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(BUTTON_CONTROL, Label) { }
|
|
| 334 |
+ DialogButtonBuilder &IsDefault(bool Default = true) { if (Default) this->style |= BS_DEFPUSHBUTTON; else this->style &= ~BS_DEFPUSHBUTTON; return this->me(); }
|
|
| 335 |
+}; |
|
| 336 |
+ |
|
| 337 |
+class DialogCheckBoxBuilder : public DialogButtonBaseBuilder<DialogCheckBoxBuilder> |
|
| 338 |
+{
|
|
| 339 |
+protected: |
|
| 340 |
+ friend class DialogTemplate; |
|
| 341 |
+public: |
|
| 342 |
+ DialogCheckBoxBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(CHECKBOX_CONTROL, Label) { this->style |= BS_AUTOCHECKBOX; }
|
|
| 343 |
+ DialogCheckBoxBuilder &WithTextOnLeft(bool TextOnLeft = true) { if (TextOnLeft) this->style |= BS_LEFTTEXT; else this->style &= ~BS_LEFTTEXT; return this->me(); }
|
|
| 344 |
+ DialogCheckBoxBuilder &LikePushButton(bool PushButton = true) { if (PushButton) this->style |= BS_PUSHLIKE; else this->style &= ~BS_PUSHLIKE; return this->me(); }
|
|
| 345 |
+}; |
|
| 346 |
+ |
|
| 347 |
+class DialogListBoxBuilder : public DialogInGroupBuilder<DialogListBoxBuilder> |
|
| 348 |
+{
|
|
| 349 |
+protected: |
|
| 350 |
+ friend class DialogTemplate; |
|
| 351 |
+public: |
|
| 352 |
+ DialogListBoxBuilder() : DialogInGroupBuilder(LISTBOX_CONTROL) { }
|
|
| 353 |
+ DialogListBoxBuilder &WithNotify(bool Notify = true) { if (Notify) this->style |= LBS_NOTIFY; else this->style &= ~LBS_NOTIFY; return this->me(); }
|
|
| 354 |
+ DialogListBoxBuilder &WithSort(bool Sort = true) { if (Sort) this->style |= LBS_SORT; else this->style &= ~LBS_SORT; return this->me(); }
|
|
| 355 |
+ DialogListBoxBuilder &WithMultipleSelect(bool MultipleSelect = true) { if (MultipleSelect) this->style |= LBS_MULTIPLESEL; else this->style &= ~LBS_MULTIPLESEL; return this->me(); }
|
|
| 356 |
+ DialogListBoxBuilder &WithExactHeight(bool ExactHeight = true) { if (ExactHeight) this->style |= LBS_NOINTEGRALHEIGHT; else this->style &= ~LBS_NOINTEGRALHEIGHT; return this->me(); }
|
|
| 357 |
+ DialogListBoxBuilder &WithMultipleColumns(bool MultipleColumns = true) { if (MultipleColumns) this->style |= LBS_MULTICOLUMN; else this->style &= ~LBS_MULTICOLUMN; return this->me(); }
|
|
| 358 |
+ DialogListBoxBuilder &WithExtendedSelect(bool ExtendedSelect = true) { if (ExtendedSelect) this->style |= LBS_EXTENDEDSEL; else this->style &= ~LBS_EXTENDEDSEL; return this->me(); }
|
|
| 359 |
+ DialogListBoxBuilder &WithDisabledNoScroll(bool DisabledNoScroll = true) { if (DisabledNoScroll) this->style |= LBS_DISABLENOSCROLL; else this->style &= ~LBS_DISABLENOSCROLL; return this->me(); }
|
|
| 360 |
+#if WINVER >= 0x0400 |
|
| 361 |
+ DialogListBoxBuilder &WithNoSelect(bool NoSelect = true) { if (NoSelect) this->style |= LBS_NOSEL; else this->style &= ~LBS_NOSEL; return this->me(); }
|
|
| 362 |
+#endif |
|
| 363 |
+}; |
|
| 364 |
+ |
|
| 365 |
+class DialogComboBoxBuilder : public DialogInGroupBuilder<DialogComboBoxBuilder> |
|
| 366 |
+{
|
|
| 367 |
+protected: |
|
| 368 |
+ friend class DialogTemplate; |
|
| 369 |
+public: |
|
| 370 |
+ DialogComboBoxBuilder() : DialogInGroupBuilder(COMBOBOX_CONTROL) { }
|
|
| 371 |
+ DialogComboBoxBuilder &IsSimple() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_SIMPLE; return this->me(); }
|
|
| 372 |
+ DialogComboBoxBuilder &IsDropDown() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_DROPDOWN; return this->me(); }
|
|
| 373 |
+ DialogComboBoxBuilder &IsDropDownList() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_DROPDOWNLIST; return this->me(); }
|
|
| 374 |
+ DialogComboBoxBuilder &WithAutoHScroll(bool AutoHScroll = true) { if (AutoHScroll) this->style |= CBS_AUTOHSCROLL; else this->style &= ~CBS_AUTOHSCROLL; return this->me(); }
|
|
| 375 |
+ DialogComboBoxBuilder &WithSort(bool Sort = true) { if (Sort) this->style |= CBS_SORT; else this->style &= ~CBS_SORT; return this->me(); }
|
|
| 376 |
+ DialogComboBoxBuilder &WithExactHeight(bool ExactHeight = true) { if (ExactHeight) this->style |= CBS_NOINTEGRALHEIGHT; else this->style &= ~CBS_NOINTEGRALHEIGHT; return this->me(); }
|
|
| 377 |
+ DialogComboBoxBuilder &WithDisabledNoScroll(bool DisabledNoScroll = true) { if (DisabledNoScroll) this->style |= CBS_DISABLENOSCROLL; else this->style &= ~CBS_DISABLENOSCROLL; return this->me(); }
|
|
| 378 |
+#if WINVER >= 0x0400 |
|
| 379 |
+ DialogComboBoxBuilder &WithAllLowercase(bool AllLowercase = true) { if (AllLowercase) this->style |= CBS_LOWERCASE; else this->style &= ~CBS_LOWERCASE; return this->me(); }
|
|
| 380 |
+ DialogComboBoxBuilder &WithAllUppercase(bool AllUppercase = true) { if (AllUppercase) this->style |= CBS_UPPERCASE; else this->style &= ~CBS_UPPERCASE; return this->me(); }
|
|
| 381 |
+#endif |
|
| 382 |
+}; |
|
| 383 |
+ |
|
| 384 |
+class DialogTemplate |
|
| 385 |
+{
|
|
| 386 |
+ class DialogControl; |
|
| 387 |
+ |
|
| 388 |
+ typedef std::vector<DialogControl *> Controls; |
|
| 389 |
+ |
|
| 390 |
+ class DialogControl |
|
| 391 |
+ {
|
|
| 392 |
+ protected: |
|
| 393 |
+ DialogControlType controlType; |
|
| 394 |
+ uint32_t style, exstyle; |
|
| 395 |
+ Rect<short> rect; |
|
| 396 |
+ short id; |
|
| 397 |
+ std::auto_ptr<RelativePosition> relativePosition; |
|
| 398 |
+ |
|
| 399 |
+ friend class DialogTemplate; |
|
| 400 |
+ DialogControl() : controlType(NO_CONTROL), style(0), exstyle(0), rect(), id(-1), relativePosition() { }
|
|
| 401 |
+ DialogControl(const DialogControl &control) : controlType(control.controlType), style(control.style), exstyle(control.exstyle), rect(control.rect), id(control.id), |
|
| 402 |
+ relativePosition(control.relativePosition.get() ? control.relativePosition->Clone() : NULL) { }
|
|
| 403 |
+ DialogControl &operator=(const DialogControl &control) |
|
| 404 |
+ {
|
|
| 405 |
+ this->controlType = control.controlType; |
|
| 406 |
+ this->style = control.style; |
|
| 407 |
+ this->exstyle = control.exstyle; |
|
| 408 |
+ this->rect = control.rect; |
|
| 409 |
+ this->id = control.id; |
|
| 410 |
+ if (control.relativePosition.get()) |
|
| 411 |
+ this->relativePosition.reset(control.relativePosition->Clone()); |
|
| 412 |
+ else |
|
| 413 |
+ this->relativePosition.reset(); |
|
| 414 |
+ |
|
| 415 |
+ return *this; |
|
| 416 |
+ } |
|
| 417 |
+ public: |
|
| 418 |
+ virtual ~DialogControl() { }
|
|
| 419 |
+ template<typename Control, typename Builder> static Control *CreateControl(const DialogControlBuilder<Builder> &builder) |
|
| 420 |
+ {
|
|
| 421 |
+ Control *control = new Control(); |
|
| 422 |
+ |
|
| 423 |
+ control->controlType = builder.controlType; |
|
| 424 |
+ control->style = builder.style; |
|
| 425 |
+ control->exstyle = builder.exstyle; |
|
| 426 |
+ control->rect = builder.rect; |
|
| 427 |
+ control->id = builder.id; |
|
| 428 |
+ if (builder.relativePosition.get()) |
|
| 429 |
+ control->relativePosition.reset(builder.relativePosition->Clone()); |
|
| 430 |
+ |
|
| 431 |
+ return control; |
|
| 432 |
+ } |
|
| 433 |
+ virtual uint16_t GetControlCount() const { return 1; }
|
|
| 434 |
+ virtual short GetControlHeight() const { return this->rect.size.height; }
|
|
| 435 |
+ virtual std::vector<uint8_t> GenerateControlTemplate() const = 0; |
|
| 436 |
+ virtual DialogControl *Clone() const = 0; |
|
| 437 |
+ }; |
|
| 438 |
+ |
|
| 439 |
+ class DialogGroup : public DialogControl |
|
| 440 |
+ {
|
|
| 441 |
+ protected: |
|
| 442 |
+ DialogTemplate::Controls controls; |
|
| 443 |
+ std::wstring groupName; |
|
| 444 |
+ |
|
| 445 |
+ friend class DialogTemplate; |
|
| 446 |
+ friend class DialogControl; |
|
| 447 |
+ DialogGroup() : DialogControl(), controls(), groupName(L"") { }
|
|
| 448 |
+ DialogGroup(const DialogGroup &control) : DialogControl(control), controls(), groupName(control.groupName) |
|
| 449 |
+ {
|
|
| 450 |
+ for (auto curr = control.controls.begin(), end = control.controls.end(); curr != end; ++curr) |
|
| 451 |
+ this->controls.push_back((*curr)->Clone()); |
|
| 452 |
+ } |
|
| 453 |
+ DialogGroup &operator=(const DialogGroup &control) |
|
| 454 |
+ {
|
|
| 455 |
+ DialogControl::operator=(control); |
|
| 456 |
+ |
|
| 457 |
+ if (!this->controls.empty()) |
|
| 458 |
+ this->ClearControls(); |
|
| 459 |
+ for (auto curr = control.controls.begin(), end = control.controls.end(); curr != end; ++curr) |
|
| 460 |
+ this->controls.push_back((*curr)->Clone()); |
|
| 461 |
+ |
|
| 462 |
+ return *this; |
|
| 463 |
+ } |
|
| 464 |
+ void ClearControls() |
|
| 465 |
+ {
|
|
| 466 |
+ for (auto curr = this->controls.begin(), end = this->controls.end(); curr != end; ++curr) |
|
| 467 |
+ delete *curr; |
|
| 468 |
+ } |
|
| 469 |
+ public: |
|
| 470 |
+ ~DialogGroup() { this->ClearControls(); }
|
|
| 471 |
+ static DialogGroup *CreateControl(const DialogControlBuilder<DialogGroupBuilder> &builder) |
|
| 472 |
+ {
|
|
| 473 |
+ DialogGroup *control = DialogControl::CreateControl<DialogGroup>(builder); |
|
| 474 |
+ |
|
| 475 |
+ control->groupName = dynamic_cast<const DialogGroupBuilder &>(builder).groupName; |
|
| 476 |
+ |
|
| 477 |
+ return control; |
|
| 478 |
+ } |
|
| 479 |
+ void CalculatePositions(bool doRightAndBottom = false); |
|
| 480 |
+ void CalculateSize(); |
|
| 481 |
+ uint16_t GetControlCount() const; |
|
| 482 |
+ std::vector<uint8_t> GenerateControlTemplate() const; |
|
| 483 |
+ DialogGroup *Clone() const { return new DialogGroup(*this); }
|
|
| 484 |
+ }; |
|
| 485 |
+ |
|
| 486 |
+ class DialogControlWithoutLabel : public DialogControl |
|
| 487 |
+ {
|
|
| 488 |
+ protected: |
|
| 489 |
+ uint16_t type; |
|
| 490 |
+ |
|
| 491 |
+ friend class DialogTemplate; |
|
| 492 |
+ friend class DialogControl; |
|
| 493 |
+ DialogControlWithoutLabel() : DialogControl(), type(0) { }
|
|
| 494 |
+ DialogControlWithoutLabel(const DialogControlWithoutLabel &control) : DialogControl(control), type(control.type) { }
|
|
| 495 |
+ DialogControlWithoutLabel &operator=(const DialogControlWithoutLabel &control) |
|
| 496 |
+ {
|
|
| 497 |
+ DialogControl::operator=(control); |
|
| 498 |
+ |
|
| 499 |
+ this->type = control.type; |
|
| 500 |
+ |
|
| 501 |
+ return *this; |
|
| 502 |
+ } |
|
| 503 |
+ public: |
|
| 504 |
+ template<typename Control, typename Builder> static Control *CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type) |
|
| 505 |
+ {
|
|
| 506 |
+ Control *control = DialogControl::CreateControl<Control>(builder); |
|
| 507 |
+ |
|
| 508 |
+ control->type = Type; |
|
| 509 |
+ |
|
| 510 |
+ return control; |
|
| 511 |
+ } |
|
| 512 |
+ virtual std::vector<uint8_t> GenerateControlTemplate() const; |
|
| 513 |
+ virtual DialogControlWithoutLabel *Clone() const { return new DialogControlWithoutLabel(*this); }
|
|
| 514 |
+ }; |
|
| 515 |
+ |
|
| 516 |
+ class DialogControlWithLabel : public DialogControl |
|
| 517 |
+ {
|
|
| 518 |
+ protected: |
|
| 519 |
+ uint16_t type; |
|
| 520 |
+ std::wstring label; |
|
| 521 |
+ |
|
| 522 |
+ friend class DialogTemplate; |
|
| 523 |
+ friend class DialogControl; |
|
| 524 |
+ DialogControlWithLabel() : DialogControl(), type(0), label(L"") { }
|
|
| 525 |
+ DialogControlWithLabel(const DialogControlWithLabel &control) : DialogControl(control), type(control.type), label(control.label) { }
|
|
| 526 |
+ DialogControlWithLabel &operator=(const DialogControlWithLabel &control) |
|
| 527 |
+ {
|
|
| 528 |
+ DialogControl::operator=(control); |
|
| 529 |
+ |
|
| 530 |
+ this->type = control.type; |
|
| 531 |
+ this->label = control.label; |
|
| 532 |
+ |
|
| 533 |
+ return *this; |
|
| 534 |
+ } |
|
| 535 |
+ public: |
|
| 536 |
+ template<typename Control, typename Builder> static Control *CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type) |
|
| 537 |
+ {
|
|
| 538 |
+ Control *control = DialogControl::CreateControl<Control>(builder); |
|
| 539 |
+ |
|
| 540 |
+ control->type = Type; |
|
| 541 |
+ control->label = dynamic_cast<const DialogControlWithLabelBuilder<Builder> &>(builder).label; |
|
| 542 |
+ |
|
| 543 |
+ return control; |
|
| 544 |
+ } |
|
| 545 |
+ virtual std::vector<uint8_t> GenerateControlTemplate() const; |
|
| 546 |
+ virtual DialogControlWithLabel *Clone() const { return new DialogControlWithLabel(*this); }
|
|
| 547 |
+ }; |
|
| 548 |
+ |
|
| 549 |
+ class DialogEditBox : public DialogControlWithoutLabel |
|
| 550 |
+ {
|
|
| 551 |
+ protected: |
|
| 552 |
+ friend class DialogTemplate; |
|
| 553 |
+ friend class DialogControl; |
|
| 554 |
+ DialogEditBox() : DialogControlWithoutLabel() { }
|
|
| 555 |
+ public: |
|
| 556 |
+ static DialogEditBox *CreateControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder) |
|
| 557 |
+ {
|
|
| 558 |
+ return DialogControlWithoutLabel::CreateControl<DialogEditBox>(builder, 0x0081); |
|
| 559 |
+ } |
|
| 560 |
+ }; |
|
| 561 |
+ |
|
| 562 |
+ class DialogLabel : public DialogControlWithLabel |
|
| 563 |
+ {
|
|
| 564 |
+ protected: |
|
| 565 |
+ friend class DialogTemplate; |
|
| 566 |
+ friend class DialogControl; |
|
| 567 |
+ DialogLabel() : DialogControlWithLabel() { }
|
|
| 568 |
+ public: |
|
| 569 |
+ static DialogLabel *CreateControl(const DialogControlBuilder<DialogLabelBuilder> &builder) |
|
| 570 |
+ {
|
|
| 571 |
+ return DialogControlWithLabel::CreateControl<DialogLabel>(builder, 0x0082); |
|
| 572 |
+ } |
|
| 573 |
+ }; |
|
| 574 |
+ |
|
| 575 |
+ class DialogButton : public DialogControlWithLabel |
|
| 576 |
+ {
|
|
| 577 |
+ protected: |
|
| 578 |
+ friend class DialogTemplate; |
|
| 579 |
+ friend class DialogControl; |
|
| 580 |
+ DialogButton() : DialogControlWithLabel() { }
|
|
| 581 |
+ public: |
|
| 582 |
+ template<typename Builder> static DialogButton *CreateControl(const DialogControlBuilder<Builder> &builder) |
|
| 583 |
+ {
|
|
| 584 |
+ return DialogControlWithLabel::CreateControl<DialogButton>(builder, 0x0080); |
|
| 585 |
+ } |
|
| 586 |
+ }; |
|
| 587 |
+ |
|
| 588 |
+ class DialogListBox : public DialogControlWithoutLabel |
|
| 589 |
+ {
|
|
| 590 |
+ protected: |
|
| 591 |
+ friend class DialogTemplate; |
|
| 592 |
+ friend class DialogControl; |
|
| 593 |
+ DialogListBox() : DialogControlWithoutLabel() { }
|
|
| 594 |
+ public: |
|
| 595 |
+ static DialogListBox *CreateControl(const DialogControlBuilder<DialogListBoxBuilder> &builder) |
|
| 596 |
+ {
|
|
| 597 |
+ return DialogControlWithoutLabel::CreateControl<DialogListBox>(builder, 0x0083); |
|
| 598 |
+ } |
|
| 599 |
+ }; |
|
| 600 |
+ |
|
| 601 |
+ class DialogComboBox : public DialogControlWithoutLabel |
|
| 602 |
+ {
|
|
| 603 |
+ protected: |
|
| 604 |
+ friend class DialogTemplate; |
|
| 605 |
+ friend class DialogControl; |
|
| 606 |
+ DialogComboBox() : DialogControlWithoutLabel() { }
|
|
| 607 |
+ public: |
|
| 608 |
+ static DialogComboBox *CreateControl(const DialogControlBuilder<DialogComboBoxBuilder> &builder) |
|
| 609 |
+ {
|
|
| 610 |
+ return DialogControlWithoutLabel::CreateControl<DialogComboBox>(builder, 0x0085); |
|
| 611 |
+ } |
|
| 612 |
+ short GetControlHeight() const { return (this->style & CBS_SIMPLE && !(this->style & CBS_DROPDOWNLIST)) ? this->rect.size.height : 14; }
|
|
| 613 |
+ }; |
|
| 614 |
+ |
|
| 615 |
+ std::wstring title; |
|
| 616 |
+ uint32_t style, exstyle; |
|
| 617 |
+ std::wstring fontName; |
|
| 618 |
+ uint16_t fontSizeInPts; |
|
| 619 |
+ Size<short> size; |
|
| 620 |
+ Controls controls; |
|
| 621 |
+ std::vector<uint8_t> templateData; |
|
| 622 |
+ |
|
| 623 |
+ template<typename Builder> void AddControlToGroup(DialogControl *control, const DialogControlBuilder<Builder> &builder) |
|
| 624 |
+ {
|
|
| 625 |
+ const DialogInGroupBuilder<Builder> &groupBuilder = dynamic_cast<const DialogInGroupBuilder<Builder> &>(builder); |
|
| 626 |
+ if (groupBuilder.groupName.empty()) |
|
| 627 |
+ {
|
|
| 628 |
+ if (builder.index == -1) |
|
| 629 |
+ this->controls.push_back(control); |
|
| 630 |
+ else |
|
| 631 |
+ this->controls.insert(this->controls.begin() + builder.index, control); |
|
| 632 |
+ } |
|
| 633 |
+ else |
|
| 634 |
+ {
|
|
| 635 |
+ for (DialogTemplate::Controls::iterator curr = this->controls.begin(), end = this->controls.end(); curr != end; ++curr) |
|
| 636 |
+ {
|
|
| 637 |
+ if ((*curr)->controlType != GROUP_CONTROL) |
|
| 638 |
+ continue; |
|
| 639 |
+ DialogGroup *group = dynamic_cast<DialogGroup *>(*curr); |
|
| 640 |
+ if (group->groupName == groupBuilder.groupName) |
|
| 641 |
+ {
|
|
| 642 |
+ if (builder.index == -1) |
|
| 643 |
+ group->controls.push_back(control); |
|
| 644 |
+ else |
|
| 645 |
+ group->controls.insert(group->controls.begin() + builder.index, control); |
|
| 646 |
+ return; |
|
| 647 |
+ } |
|
| 648 |
+ } |
|
| 649 |
+ throw std::runtime_error("Group " + UtfConverter::ToUtf8(groupBuilder.groupName) + " was not found.");
|
|
| 650 |
+ } |
|
| 651 |
+ } |
|
| 652 |
+ uint16_t GetTotalControlCount() const; |
|
| 653 |
+ bool CalculateControlPosition(short index, bool doRightAndBottom = false); |
|
| 654 |
+ void CalculateSize(); |
|
| 655 |
+ void ClearControls() |
|
| 656 |
+ {
|
|
| 657 |
+ for (auto curr = this->controls.begin(), end = this->controls.end(); curr != end; ++curr) |
|
| 658 |
+ delete *curr; |
|
| 659 |
+ } |
|
| 660 |
+public: |
|
| 661 |
+ DialogTemplate() : title(L""), style(0), exstyle(0), fontName(L""), fontSizeInPts(0), size(), controls(), templateData() { }
|
|
| 662 |
+ DialogTemplate(const DialogBuilder &builder) : title(builder.title), style(builder.style), exstyle(builder.exstyle), fontName(builder.fontName), fontSizeInPts(builder.fontSizeInPts), |
|
| 663 |
+ size(builder.size), controls(), templateData() { }
|
|
| 664 |
+ DialogTemplate(const DialogTemplate &dlg) : title(dlg.title), style(dlg.style), exstyle(dlg.style), fontName(dlg.fontName), fontSizeInPts(dlg.fontSizeInPts), size(dlg.size), |
|
| 665 |
+ controls(), templateData() |
|
| 666 |
+ {
|
|
| 667 |
+ for (auto curr = dlg.controls.begin(), end = dlg.controls.end(); curr != end; ++curr) |
|
| 668 |
+ this->controls.push_back((*curr)->Clone()); |
|
| 669 |
+ } |
|
| 670 |
+ DialogTemplate &operator=(const DialogBuilder &builder) |
|
| 671 |
+ {
|
|
| 672 |
+ this->title = builder.title; |
|
| 673 |
+ this->style = builder.style; |
|
| 674 |
+ this->exstyle = builder.exstyle; |
|
| 675 |
+ this->fontName = builder.fontName; |
|
| 676 |
+ this->fontSizeInPts = builder.fontSizeInPts; |
|
| 677 |
+ this->size = builder.size; |
|
| 678 |
+ if (builder.resetControls && !this->controls.empty()) |
|
| 679 |
+ this->ClearControls(); |
|
| 680 |
+ |
|
| 681 |
+ return *this; |
|
| 682 |
+ } |
|
| 683 |
+ DialogTemplate &operator=(const DialogTemplate &dlg) |
|
| 684 |
+ {
|
|
| 685 |
+ this->title = dlg.title; |
|
| 686 |
+ this->style = dlg.style; |
|
| 687 |
+ this->exstyle = dlg.exstyle; |
|
| 688 |
+ this->fontName = dlg.fontName; |
|
| 689 |
+ this->fontSizeInPts = dlg.fontSizeInPts; |
|
| 690 |
+ this->size = dlg.size; |
|
| 691 |
+ if (!this->controls.empty()) |
|
| 692 |
+ this->ClearControls(); |
|
| 693 |
+ for (auto curr = dlg.controls.begin(), end = dlg.controls.end(); curr != end; ++curr) |
|
| 694 |
+ this->controls.push_back((*curr)->Clone()); |
|
| 695 |
+ |
|
| 696 |
+ return *this; |
|
| 697 |
+ } |
|
| 698 |
+ ~DialogTemplate() { this->ClearControls(); }
|
|
| 699 |
+ void AddGroupControl(const DialogControlBuilder<DialogGroupBuilder> &builder); |
|
| 700 |
+ void AddEditBoxControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder); |
|
| 701 |
+ void AddLabelControl(const DialogControlBuilder<DialogLabelBuilder> &builder); |
|
| 702 |
+ void AddCheckBoxControl(const DialogControlBuilder<DialogCheckBoxBuilder> &builder); |
|
| 703 |
+ void AddButtonControl(const DialogControlBuilder<DialogButtonBuilder> &builder); |
|
| 704 |
+ void AddListBoxControl(const DialogControlBuilder<DialogListBoxBuilder> &builder); |
|
| 705 |
+ void AddComboBoxControl(const DialogControlBuilder<DialogComboBoxBuilder> &builder); |
|
| 706 |
+ void AutoSize(); |
|
| 707 |
+ const DLGTEMPLATE *GenerateTemplate(); |
|
| 708 |
+}; |
|
| 709 |
+ |
|
| 710 |
+#endif |