Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef _COMMONWIDGETS_H_
- #define _COMMONWIDGETS_H_
- #include <rbutton.h>
- #include <rcheckbox.h>
- #include <rcombobox.h>
- #include <reditbox.h>
- #include <rlabel.h>
- #include <ridentity.h>
- #include "options.h"
- #include "cardcodeeditbox.h"
- #include "DlgAction.h"
- class CTimeEditBox;
- class CDateEditBox;
- namespace CommonWidgets {
- /*
- декорируемые функции
- реально ничего не создают, принимают указатель на базовый класс элемента
- и устанавливают значения виджета по умолчанию.
- напрямую никогда не вызываются
- */
- RButton *createButtonImpl(RButton *button, const char *text);
- RCheckBox *createCheckBoxImpl(RCheckBox *checkBox, const char *text);
- RComboBox *createComboBoxImpl(RComboBox *comboBox);
- REditBox *createEditBoxImpl(REditBox *editBox);
- RLabel *createLabelImpl(RLabel *label, const char *text);
- /*
- Пространство имен базовых виджетов
- Если при вызове функции-конструктора не передается тип создаваемого виджета,
- то используются как раз эти классы
- */
- namespace BaseWidgets {
- namespace {
- /*
- Идиома проверки принадлежности типа заданному базовому классу
- */
- template <typename T, typename U>
- class Conversion {
- typedef char Small;
- class Big { char dummy[2]; };
- static Small Test(U);
- static Big Test(...);
- static T MakeT();
- public:
- enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
- enum { sameType = 0 };
- };
- template <typename T>
- class Conversion<T, T> {
- public:
- enum { exists = 1, sameType = 1 };
- };
- #define SUPERSUBCLASS(T, U) \
- (Conversion<const U *, const T *>::exists && \
- !Conversion<const T *, const void *>::sameType)
- /* Простая идиома отображения числа в тип.
- Используется для реализации перегрузки
- */
- template <int v>
- struct Int2Type {
- enum { value = v };
- };
- /*
- Вспомогательный класс для получения виджета
- Если тип наследуется от RWidget, то возвращаем на него указатель
- Иначе это private класс, возвращаем указатель на q
- каждый private класс должен содержать указатель на оконный виджет с именем q
- */
- template <typename T, bool isWidget>
- class ParentWidgetHelper {
- ParentWidgetHelper() {}
- static RWidget *getWidget(T *t, Int2Type<true>)
- { return t; }
- static RWidget *getWidget(T *t, Int2Type<false>)
- { return t->q; }
- public:
- static RWidget *getWidget(T *t)
- { return getWidget(t, Int2Type<isWidget>()); }
- };
- template <typename T>
- inline RWidget *getWidget(T *parent)
- { return ParentWidgetHelper<T, SUPERSUBCLASS(RWidget, T)>::getWidget(parent); }
- }
- /*
- Вспомогательный класс для хранения указателя на класс-обработчик сообщений
- */
- //--------------------------------------------------------------------------------------------
- template <typename MessageHolder>
- class Holder {
- public:
- Holder(MessageHolder *holder) :
- m_holder(holder)
- {}
- MessageHolder *holder() const
- { return m_holder; }
- private:
- MessageHolder *m_holder;
- };
- /* Button с возможностью уведомления о нажатии */
- //--------------------------------------------------------------------------------------------
- template <typename MessageHolder>
- class Button : public RButton,
- private RIdentity,
- private Holder<MessageHolder> {
- public:
- Button(int id, MessageHolder *holder, RWFlags flags) :
- RButton(getWidget(holder), flags),
- RIdentity(id),
- Holder<MessageHolder>(holder)
- {}
- protected:
- virtual void click()
- {
- RButton::click();
- holder()->itemClicked(id());
- }
- };
- /* CheckBox с возможностью уведомления о нажатии */
- //--------------------------------------------------------------------------------------------
- template <typename MessageHolder>
- class CheckBox : public RCheckBox,
- private RIdentity,
- private Holder<MessageHolder> {
- public:
- CheckBox(int id, MessageHolder *holder, RWFlags flags) :
- RCheckBox(getWidget(holder), flags),
- RIdentity(id),
- Holder<MessageHolder>(holder)
- {}
- protected:
- virtual void click()
- {
- RCheckBox::click();
- holder()->itemClicked(id());
- }
- };
- /* ComboBox с возможностью уведомления о выборе элемента */
- //--------------------------------------------------------------------------------------------
- template <typename MessageHolder>
- class ComboBox : public RComboBox,
- private RIdentity,
- private Holder<MessageHolder> {
- public:
- ComboBox(int id, MessageHolder *holder, RWFlags flags) :
- RComboBox(getWidget(holder), flags),
- RIdentity(id),
- Holder<MessageHolder>(holder)
- {}
- protected:
- virtual void activated(Sint32 row)
- {
- RComboBox::activated(row);
- holder()->activated(id(), row);
- }
- };
- /* EditBox с возможностью ввода данных с тулбара */
- //--------------------------------------------------------------------------------------------
- class EditBoxCommonToolBar : public REditBox {
- public:
- EditBoxCommonToolBar(CDlgAction *act, RWidget *parent, RWFlags flags);
- protected:
- virtual void eventFocusLost();
- private:
- CDlgAction *m_act;
- };
- /* EditBox с ограниченным вводом по времени */
- //--------------------------------------------------------------------------------------------
- class EditBoxTimeInput : public CCardCodeEditBox {
- public:
- EditBoxTimeInput(const Options::CardCodeInputOptions &opt, RWidget *parent, RWFlags flags);
- protected:
- virtual void timingFailed();
- };
- /* EditBox с возможностью ввода данных с тулбара и ограниченным вводом по времени */
- //--------------------------------------------------------------------------------------------
- class EditBoxCommonToolBarTimeInput : public EditBoxTimeInput {
- public:
- EditBoxCommonToolBarTimeInput(CDlgAction *act, const Options::CardCodeInputOptions &opt, RWidget *parent, RWFlags flags);
- protected:
- virtual void eventFocusLost();
- private:
- CDlgAction *m_act;
- };
- /* Функции для упрощенного создания полей даты/времени */
- CTimeEditBox *createTimeEditBoxImpl(RWidget *parent, CDlgAction *act, RWFlags flags);
- CDateEditBox *createDateEditBoxImpl(RWidget *parent, CDlgAction *act, RWFlags flags);
- /*
- Пространство имен для создания EditBox-a по умолчанию
- Статически определяет тип базового класса и создает требуемый виджет
- */
- namespace {
- /*
- Вспомогательный класс для создания EditBox-a в зависимости от родительского типа.
- Если родительский тип наследуется от CDlgAction, то EditBox поддерживает ввод с цифрового тулбара
- */
- template <typename U, bool isCommon>
- class EditBoxHelperCreator {
- EditBoxHelperCreator() {}
- static REditBox *create(U *parent, RWFlags flags, Int2Type<true>)
- {
- CDlgAction *act = static_cast<CDlgAction *>(parent);
- return createEditBoxImpl(new EditBoxCommonToolBar(act, parent, flags));
- }
- static REditBox *create(U *parent, RWFlags flags, Int2Type<false>)
- {
- return createEditBoxImpl(new REditBox(parent, flags));
- }
- static CCardCodeEditBox *create(const Options::CardCodeInputOptions &opt, U *parent, RWFlags flags, Int2Type<true>)
- {
- CDlgAction *act = static_cast<CDlgAction *>(parent);
- return static_cast<EditBoxCommonToolBarTimeInput *>(
- createEditBoxImpl(new EditBoxCommonToolBarTimeInput(act, opt, parent, flags)));
- }
- static CCardCodeEditBox *create(const Options::CardCodeInputOptions &opt, U *parent, RWFlags flags, Int2Type<false>)
- {
- return static_cast<EditBoxTimeInput *>(createEditBoxImpl(new EditBoxTimeInput(opt, parent, flags)));
- }
- public:
- static REditBox *create(U *parent, RWFlags flags)
- { return create(parent, flags, Int2Type<isCommon>()); }
- static CCardCodeEditBox *create(const Options::CardCodeInputOptions &opt, U *parent, RWFlags flags)
- { return create(opt, parent, flags, Int2Type<isCommon>()); }
- };
- template <typename T>
- inline REditBox *createEditBoxByParent(T *parent, RWFlags flags)
- { return EditBoxHelperCreator<T, SUPERSUBCLASS(CDlgAction, T)>::create(parent, flags); }
- template <typename T>
- CCardCodeEditBox *createEditBoxByParent(const Options::CardCodeInputOptions &opt, T *parent, RWFlags flags)
- { return EditBoxHelperCreator<T, SUPERSUBCLASS(CDlgAction, T)>::create(opt, parent, flags); }
- /* Вспомогательный класс для создания полей даты/времени в зависимости от типа родителя */
- template <typename U, bool isCommon>
- class DateTimeEditBoxHelperCreator {
- private:
- static CDateEditBox *createDateEdit(U *parent, RWFlags flags, Int2Type<true>)
- { return createDateEditBoxImpl(parent, parent, flags); }
- static CDateEditBox *createDateEdit(U *parent, RWFlags flags, Int2Type<false>)
- { return createDateEditBoxImpl(parent, 0, flags); }
- static CTimeEditBox *createTimeEdit(U *parent, RWFlags flags, Int2Type<true>)
- { return createTimeEditBoxImpl(parent, parent, flags); }
- static CTimeEditBox *createTimeEdit(U *parent, RWFlags flags, Int2Type<false>)
- { return createTimeEditBoxImpl(parent, 0, flags); }
- public:
- static CDateEditBox *createDateEdit(U *parent, RWFlags flags)
- { return createDateEdit(parent, flags, Int2Type<isCommon>()); }
- static CTimeEditBox *createTimeEdit(U *parent, RWFlags flags)
- { return createTimeEdit(parent, flags, Int2Type<isCommon>()); }
- };
- template <typename T>
- inline CDateEditBox *createDateEditBoxByParent(T *parent, RWFlags flags)
- { return DateTimeEditBoxHelperCreator<T, SUPERSUBCLASS(CDlgAction, T)>::createDateEdit(parent, flags); }
- template <typename T>
- inline CTimeEditBox *createTimeEditBoxByParent(T *parent, RWFlags flags)
- { return DateTimeEditBoxHelperCreator<T, SUPERSUBCLASS(CDlgAction, T)>::createTimeEdit(parent, flags); }
- }
- }
- /*
- Основные функции для создания виджетов. Каждая группа содержит 3 типа функции:
- - создание своего уникального виджета
- - создание виджета из пространства BaseWidgets
- - создание простого R-виджета (без переопределенного поведения)
- */
- //--------------------------------------------------------------------------------------------
- // BUTTON
- //--------------------------------------------------------------------------------------------
- template <template <typename> class Widget, typename Holder>
- inline RButton *createButton(int id, const char *text, Holder *holder, RWFlags flags = RWF_DestructiveClose)
- { return createButtonImpl(new Widget<Holder>(id, holder, flags), text); }
- //--------------------------------------------------------------------------------------------
- template <typename Holder>
- inline RButton *createButton(int id, const char *text, Holder *holder, RWFlags flags = RWF_DestructiveClose)
- { return createButtonImpl(new BaseWidgets::Button<Holder>(id, holder, flags), text); }
- //--------------------------------------------------------------------------------------------
- inline RButton *createButton(const char *text, RWidget *parent, RWFlags flags = RWF_DestructiveClose)
- { return createButtonImpl(new RButton(parent, flags), text); }
- //--------------------------------------------------------------------------------------------
- // CHECKBOX
- //--------------------------------------------------------------------------------------------
- template <template <typename> class Widget, typename Holder>
- inline RCheckBox *createCheckBox(int id, const char *text, Holder *holder, RWFlags flags = RWF_DestructiveClose)
- { return createCheckBoxImpl(new Widget<Holder>(id, holder, flags), text); }
- //--------------------------------------------------------------------------------------------
- template <typename Holder>
- inline RCheckBox *createCheckBox(int id, const char *text, Holder *holder, RWFlags flags = RWF_DestructiveClose)
- { return createCheckBoxImpl(new BaseWidgets::CheckBox<Holder>(id, holder, flags), text); }
- //--------------------------------------------------------------------------------------------
- inline RCheckBox *createCheckBox(const char *text, RWidget *parent, RWFlags flags = RWF_DestructiveClose)
- { return createCheckBoxImpl(new RCheckBox(parent, flags), text); }
- //--------------------------------------------------------------------------------------------
- // COMBOBOX
- //--------------------------------------------------------------------------------------------
- template <template <typename> class Widget, typename Holder>
- inline RComboBox *createComboBox(int id, Holder *holder, RWFlags flags = RWF_DestructiveClose)
- { return createComboBoxImpl(new Widget<Holder>(id, holder, flags)); }
- //--------------------------------------------------------------------------------------------
- template <typename Holder>
- inline RComboBox *createComboBox(int id, Holder *holder, RWFlags flags = RWF_DestructiveClose)
- { return createComboBoxImpl(new BaseWidgets::ComboBox<Holder>(id, holder, flags));; }
- //--------------------------------------------------------------------------------------------
- inline RComboBox *createComboBox(RWidget *parent, RWFlags flags = RWF_DestructiveClose)
- { return createComboBoxImpl(new RComboBox(parent, flags)); }
- //--------------------------------------------------------------------------------------------
- // EDITBOX
- //--------------------------------------------------------------------------------------------
- template <typename Widget, typename T>
- inline Widget *createEditBox(T *parent, RWFlags flags = RWF_DestructiveClose)
- { return static_cast<Widget *>(createEditBoxImpl(new Widget(parent, flags))); }
- //--------------------------------------------------------------------------------------------
- template <typename T>
- inline REditBox *createEditBox(T *parent, RWFlags flags = RWF_DestructiveClose)
- { return BaseWidgets::createEditBoxByParent(parent, flags); }
- //--------------------------------------------------------------------------------------------
- template <typename T>
- inline CCardCodeEditBox *createEditBox(const Options::CardCodeInputOptions &opt, T *parent, RWFlags flags = RWF_DestructiveClose)
- { return BaseWidgets::createEditBoxByParent(opt, parent, flags); }
- //--------------------------------------------------------------------------------------------
- // LABEL
- //--------------------------------------------------------------------------------------------
- template <typename Widget>
- inline RLabel *createLabel(const char *text, RWidget *parent, RWFlags flags = RWF_DestructiveClose)
- { return createLabelImpl(new Widget(parent, flags), text); }
- //--------------------------------------------------------------------------------------------
- inline RLabel *createLabel(const char *text, RWidget *parent, RWFlags flags = RWF_DestructiveClose)
- { return createLabelImpl(new RLabel(parent, flags), text); }
- //--------------------------------------------------------------------------------------------
- // DATEEDITBOX
- //--------------------------------------------------------------------------------------------
- template <typename T>
- inline CDateEditBox *createDateEditBox(T *parent, RWFlags flags = RWF_DestructiveClose)
- { return BaseWidgets::createDateEditBoxByParent(parent, flags); }
- //--------------------------------------------------------------------------------------------
- // TIMEEDITBOX
- //--------------------------------------------------------------------------------------------
- template <typename T>
- inline CTimeEditBox *createTimeEditBox(T *parent, RWFlags flags = RWF_DestructiveClose)
- { return BaseWidgets::createTimeEditBoxByParent(parent, flags); }
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment