Guest User

Untitled

a guest
Mar 23rd, 2012
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.60 KB | None | 0 0
  1. #ifndef _COMMONWIDGETS_H_
  2. #define _COMMONWIDGETS_H_
  3.  
  4. #include <rbutton.h>
  5. #include <rcheckbox.h>
  6. #include <rcombobox.h>
  7. #include <reditbox.h>
  8. #include <rlabel.h>
  9. #include <ridentity.h>
  10. #include "options.h"
  11. #include "cardcodeeditbox.h"
  12. #include "DlgAction.h"
  13.  
  14. class CTimeEditBox;
  15. class CDateEditBox;
  16.  
  17. namespace CommonWidgets {
  18.     /*
  19.         декорируемые функции
  20.         реально ничего не создают, принимают указатель на базовый класс элемента
  21.         и устанавливают значения виджета по умолчанию.
  22.         напрямую никогда не вызываются
  23.     */
  24.     RButton *createButtonImpl(RButton *button, const char *text);
  25.     RCheckBox *createCheckBoxImpl(RCheckBox *checkBox, const char *text);
  26.     RComboBox *createComboBoxImpl(RComboBox *comboBox);
  27.     REditBox *createEditBoxImpl(REditBox *editBox);
  28.     RLabel *createLabelImpl(RLabel *label, const char *text);
  29.  
  30. /*
  31.     Пространство имен базовых виджетов
  32.     Если при вызове функции-конструктора не передается тип создаваемого виджета,
  33.     то используются как раз эти классы
  34. */
  35. namespace BaseWidgets {
  36.     namespace {
  37.         /*
  38.             Идиома проверки принадлежности типа заданному базовому классу
  39.         */
  40.         template <typename T, typename U>
  41.         class Conversion {
  42.             typedef char Small;
  43.             class Big { char dummy[2]; };
  44.             static Small Test(U);
  45.             static Big Test(...);
  46.             static T MakeT();  
  47.         public:
  48.             enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
  49.             enum { sameType = 0 };
  50.         };
  51.  
  52.         template <typename T>
  53.         class Conversion<T, T> {
  54.         public:
  55.             enum { exists = 1, sameType = 1 };
  56.         };
  57.  
  58.         #define SUPERSUBCLASS(T, U) \
  59.             (Conversion<const U *, const T *>::exists && \
  60.             !Conversion<const T *, const void *>::sameType)
  61.  
  62.         /*  Простая идиома отображения числа в тип.
  63.             Используется для реализации перегрузки
  64.         */
  65.         template <int v>
  66.         struct Int2Type {
  67.             enum { value = v };
  68.         };
  69.  
  70.         /*
  71.             Вспомогательный класс для получения виджета
  72.             Если тип наследуется от RWidget, то возвращаем на него указатель
  73.             Иначе это private класс, возвращаем указатель на q
  74.             каждый private класс должен содержать указатель на оконный виджет с именем q
  75.         */
  76.         template <typename T, bool isWidget>
  77.         class ParentWidgetHelper {
  78.             ParentWidgetHelper() {}
  79.            
  80.             static RWidget *getWidget(T *t, Int2Type<true>)
  81.             { return t; }
  82.  
  83.             static RWidget *getWidget(T *t, Int2Type<false>)
  84.             { return t->q; }
  85.  
  86.         public:
  87.             static RWidget *getWidget(T *t)
  88.             { return getWidget(t, Int2Type<isWidget>()); }
  89.         };
  90.  
  91.         template <typename T>
  92.         inline RWidget *getWidget(T *parent)
  93.         { return ParentWidgetHelper<T, SUPERSUBCLASS(RWidget, T)>::getWidget(parent); }
  94.     }
  95.  
  96.     /*
  97.         Вспомогательный класс для хранения указателя на класс-обработчик сообщений
  98.     */
  99.     //--------------------------------------------------------------------------------------------
  100.     template <typename MessageHolder>
  101.     class Holder {
  102.     public:
  103.         Holder(MessageHolder *holder) :
  104.             m_holder(holder)
  105.         {}
  106.  
  107.         MessageHolder *holder() const
  108.         { return m_holder; }
  109.  
  110.     private:
  111.         MessageHolder *m_holder;
  112.     };
  113.  
  114.     /* Button с возможностью уведомления о нажатии */
  115.     //--------------------------------------------------------------------------------------------
  116.     template <typename MessageHolder>
  117.     class Button :  public  RButton,
  118.                     private RIdentity,
  119.                     private Holder<MessageHolder> {
  120.     public:
  121.         Button(int id, MessageHolder *holder, RWFlags flags) :
  122.             RButton(getWidget(holder), flags),
  123.             RIdentity(id),
  124.             Holder<MessageHolder>(holder)
  125.         {}
  126.  
  127.     protected:
  128.         virtual void click()
  129.         {
  130.             RButton::click();
  131.             holder()->itemClicked(id());
  132.         }
  133.     };
  134.  
  135.     /* CheckBox с возможностью уведомления о нажатии */
  136.     //--------------------------------------------------------------------------------------------
  137.     template <typename MessageHolder>
  138.     class CheckBox :    public RCheckBox,
  139.                         private RIdentity,
  140.                         private Holder<MessageHolder> {
  141.     public:
  142.         CheckBox(int id, MessageHolder *holder, RWFlags flags) :
  143.             RCheckBox(getWidget(holder), flags),
  144.             RIdentity(id),
  145.             Holder<MessageHolder>(holder)
  146.         {}
  147.  
  148.     protected:
  149.         virtual void click()
  150.         {
  151.             RCheckBox::click();
  152.             holder()->itemClicked(id());
  153.         }
  154.     };
  155.  
  156.     /* ComboBox с возможностью уведомления о выборе элемента */
  157.     //--------------------------------------------------------------------------------------------
  158.     template <typename MessageHolder>
  159.     class ComboBox :    public RComboBox,
  160.                         private RIdentity,
  161.                         private Holder<MessageHolder> {
  162.     public:
  163.         ComboBox(int id, MessageHolder *holder, RWFlags flags)  :
  164.             RComboBox(getWidget(holder), flags),
  165.             RIdentity(id),
  166.             Holder<MessageHolder>(holder)
  167.         {}
  168.  
  169.     protected:
  170.         virtual void activated(Sint32 row)
  171.         {
  172.             RComboBox::activated(row);
  173.             holder()->activated(id(), row);
  174.         }
  175.     };
  176.  
  177.     /* EditBox с возможностью ввода данных с тулбара */
  178.     //--------------------------------------------------------------------------------------------
  179.     class EditBoxCommonToolBar : public REditBox {
  180.     public:
  181.         EditBoxCommonToolBar(CDlgAction *act, RWidget *parent, RWFlags flags);
  182.     protected:
  183.         virtual void eventFocusLost();
  184.     private:
  185.         CDlgAction *m_act;
  186.     };
  187.  
  188.     /* EditBox с ограниченным вводом по времени */
  189.     //--------------------------------------------------------------------------------------------
  190.     class EditBoxTimeInput : public CCardCodeEditBox {
  191.     public:
  192.         EditBoxTimeInput(const Options::CardCodeInputOptions &opt, RWidget *parent, RWFlags flags);
  193.     protected:
  194.         virtual void timingFailed();
  195.     };
  196.  
  197.     /* EditBox с возможностью ввода данных с тулбара и ограниченным вводом по времени */
  198.     //--------------------------------------------------------------------------------------------
  199.     class EditBoxCommonToolBarTimeInput : public EditBoxTimeInput {
  200.     public:
  201.         EditBoxCommonToolBarTimeInput(CDlgAction *act, const Options::CardCodeInputOptions &opt, RWidget *parent, RWFlags flags);
  202.     protected:
  203.         virtual void eventFocusLost();
  204.     private:
  205.         CDlgAction *m_act;
  206.     };
  207.  
  208.     /* Функции для упрощенного создания полей даты/времени */
  209.     CTimeEditBox *createTimeEditBoxImpl(RWidget *parent, CDlgAction *act, RWFlags flags);
  210.     CDateEditBox *createDateEditBoxImpl(RWidget *parent, CDlgAction *act, RWFlags flags);
  211.  
  212.     /*
  213.         Пространство имен для создания EditBox-a по умолчанию
  214.         Статически определяет тип базового класса и создает требуемый виджет
  215.     */
  216.     namespace {
  217.         /*
  218.             Вспомогательный класс для создания EditBox-a в зависимости от родительского типа.
  219.             Если родительский тип наследуется от CDlgAction, то EditBox поддерживает ввод с цифрового тулбара
  220.         */
  221.  
  222.         template <typename U, bool isCommon>
  223.         class EditBoxHelperCreator {
  224.             EditBoxHelperCreator() {}
  225.  
  226.             static REditBox *create(U *parent, RWFlags flags, Int2Type<true>)
  227.             {
  228.                 CDlgAction *act = static_cast<CDlgAction *>(parent);
  229.                 return createEditBoxImpl(new EditBoxCommonToolBar(act, parent, flags));
  230.             }
  231.  
  232.             static REditBox *create(U *parent, RWFlags flags, Int2Type<false>)
  233.             {
  234.                 return createEditBoxImpl(new REditBox(parent, flags));
  235.             }
  236.  
  237.             static CCardCodeEditBox *create(const Options::CardCodeInputOptions &opt, U *parent, RWFlags flags, Int2Type<true>)
  238.             {
  239.                 CDlgAction *act = static_cast<CDlgAction *>(parent);
  240.                 return static_cast<EditBoxCommonToolBarTimeInput *>(
  241.                     createEditBoxImpl(new EditBoxCommonToolBarTimeInput(act, opt, parent, flags)));
  242.             }
  243.  
  244.             static CCardCodeEditBox *create(const Options::CardCodeInputOptions &opt, U *parent, RWFlags flags, Int2Type<false>)
  245.             {
  246.                 return static_cast<EditBoxTimeInput *>(createEditBoxImpl(new EditBoxTimeInput(opt, parent, flags)));
  247.             }
  248.  
  249.         public:
  250.             static REditBox *create(U *parent, RWFlags flags)
  251.             { return create(parent, flags, Int2Type<isCommon>()); }
  252.  
  253.             static CCardCodeEditBox *create(const Options::CardCodeInputOptions &opt, U *parent, RWFlags flags)
  254.             { return create(opt, parent, flags, Int2Type<isCommon>()); }
  255.         };
  256.  
  257.         template <typename T>
  258.         inline REditBox *createEditBoxByParent(T *parent, RWFlags flags)
  259.         { return EditBoxHelperCreator<T, SUPERSUBCLASS(CDlgAction, T)>::create(parent, flags); }
  260.  
  261.         template <typename T>
  262.         CCardCodeEditBox *createEditBoxByParent(const Options::CardCodeInputOptions &opt, T *parent, RWFlags flags)
  263.         { return EditBoxHelperCreator<T, SUPERSUBCLASS(CDlgAction, T)>::create(opt, parent, flags); }
  264.  
  265.  
  266.         /* Вспомогательный класс для создания полей даты/времени в зависимости от типа родителя */
  267.         template <typename U, bool isCommon>
  268.         class DateTimeEditBoxHelperCreator {
  269.         private:
  270.             static CDateEditBox *createDateEdit(U *parent, RWFlags flags, Int2Type<true>)
  271.             { return createDateEditBoxImpl(parent, parent, flags); }
  272.  
  273.             static CDateEditBox *createDateEdit(U *parent, RWFlags flags, Int2Type<false>)
  274.             { return createDateEditBoxImpl(parent, 0, flags); }
  275.  
  276.             static CTimeEditBox *createTimeEdit(U *parent, RWFlags flags, Int2Type<true>)
  277.             { return createTimeEditBoxImpl(parent, parent, flags); }
  278.  
  279.             static CTimeEditBox *createTimeEdit(U *parent, RWFlags flags, Int2Type<false>)
  280.             { return createTimeEditBoxImpl(parent, 0, flags); }
  281.  
  282.         public:
  283.             static CDateEditBox *createDateEdit(U *parent, RWFlags flags)
  284.             { return createDateEdit(parent, flags, Int2Type<isCommon>()); }
  285.  
  286.             static CTimeEditBox *createTimeEdit(U *parent, RWFlags flags)
  287.             { return createTimeEdit(parent, flags, Int2Type<isCommon>()); }
  288.         };
  289.  
  290.         template <typename T>
  291.         inline CDateEditBox *createDateEditBoxByParent(T *parent, RWFlags flags)
  292.         { return DateTimeEditBoxHelperCreator<T, SUPERSUBCLASS(CDlgAction, T)>::createDateEdit(parent, flags); }
  293.  
  294.         template <typename T>
  295.         inline CTimeEditBox *createTimeEditBoxByParent(T *parent, RWFlags flags)
  296.         { return DateTimeEditBoxHelperCreator<T, SUPERSUBCLASS(CDlgAction, T)>::createTimeEdit(parent, flags); }
  297.     }
  298. }
  299.  
  300. /*
  301.     Основные функции для создания виджетов. Каждая группа содержит 3 типа функции:
  302.      - создание своего уникального виджета
  303.      - создание виджета из пространства BaseWidgets
  304.      - создание простого R-виджета (без переопределенного поведения)
  305. */
  306.  
  307. //--------------------------------------------------------------------------------------------
  308. // BUTTON
  309. //--------------------------------------------------------------------------------------------
  310. template <template <typename> class Widget, typename Holder>
  311. inline RButton *createButton(int id, const char *text, Holder *holder, RWFlags flags = RWF_DestructiveClose)
  312. { return createButtonImpl(new Widget<Holder>(id, holder, flags), text); }
  313.  
  314. //--------------------------------------------------------------------------------------------
  315. template <typename Holder>
  316. inline RButton *createButton(int id, const char *text, Holder *holder, RWFlags flags = RWF_DestructiveClose)
  317. { return createButtonImpl(new BaseWidgets::Button<Holder>(id, holder, flags), text); }
  318.  
  319. //--------------------------------------------------------------------------------------------
  320. inline RButton *createButton(const char *text, RWidget *parent, RWFlags flags = RWF_DestructiveClose)
  321. { return createButtonImpl(new RButton(parent, flags), text); }
  322.  
  323.  
  324.  
  325. //--------------------------------------------------------------------------------------------
  326. // CHECKBOX
  327. //--------------------------------------------------------------------------------------------
  328. template <template <typename> class Widget, typename Holder>
  329. inline RCheckBox *createCheckBox(int id, const char *text, Holder *holder, RWFlags flags = RWF_DestructiveClose)
  330. { return createCheckBoxImpl(new Widget<Holder>(id, holder, flags), text); }
  331.  
  332. //--------------------------------------------------------------------------------------------
  333. template <typename Holder>
  334. inline RCheckBox *createCheckBox(int id, const char *text, Holder *holder, RWFlags flags = RWF_DestructiveClose)
  335. { return createCheckBoxImpl(new BaseWidgets::CheckBox<Holder>(id, holder, flags), text); }
  336.  
  337. //--------------------------------------------------------------------------------------------
  338. inline RCheckBox *createCheckBox(const char *text, RWidget *parent, RWFlags flags = RWF_DestructiveClose)
  339. { return createCheckBoxImpl(new RCheckBox(parent, flags), text); }
  340.  
  341.  
  342.  
  343. //--------------------------------------------------------------------------------------------
  344. // COMBOBOX
  345. //--------------------------------------------------------------------------------------------
  346. template <template <typename> class Widget, typename Holder>
  347. inline RComboBox *createComboBox(int id, Holder *holder, RWFlags flags = RWF_DestructiveClose)
  348. { return createComboBoxImpl(new Widget<Holder>(id, holder, flags)); }
  349.  
  350. //--------------------------------------------------------------------------------------------
  351. template <typename Holder>
  352. inline RComboBox *createComboBox(int id, Holder *holder, RWFlags flags = RWF_DestructiveClose)
  353. { return createComboBoxImpl(new BaseWidgets::ComboBox<Holder>(id, holder, flags));; }
  354.  
  355. //--------------------------------------------------------------------------------------------
  356. inline RComboBox *createComboBox(RWidget *parent, RWFlags flags = RWF_DestructiveClose)
  357. { return createComboBoxImpl(new RComboBox(parent, flags)); }
  358.  
  359.  
  360.  
  361. //--------------------------------------------------------------------------------------------
  362. // EDITBOX
  363. //--------------------------------------------------------------------------------------------
  364. template <typename Widget, typename T>
  365. inline Widget *createEditBox(T *parent, RWFlags flags = RWF_DestructiveClose)
  366. { return static_cast<Widget *>(createEditBoxImpl(new Widget(parent, flags))); }
  367.  
  368. //--------------------------------------------------------------------------------------------
  369. template <typename T>
  370. inline REditBox *createEditBox(T *parent, RWFlags flags = RWF_DestructiveClose)
  371. { return BaseWidgets::createEditBoxByParent(parent, flags); }
  372.  
  373. //--------------------------------------------------------------------------------------------
  374. template <typename T>
  375. inline CCardCodeEditBox *createEditBox(const Options::CardCodeInputOptions &opt, T *parent, RWFlags flags = RWF_DestructiveClose)
  376. { return BaseWidgets::createEditBoxByParent(opt, parent, flags); }
  377.  
  378.  
  379.  
  380. //--------------------------------------------------------------------------------------------
  381. // LABEL
  382. //--------------------------------------------------------------------------------------------
  383. template <typename Widget>
  384. inline RLabel *createLabel(const char *text, RWidget *parent, RWFlags flags = RWF_DestructiveClose)
  385. { return createLabelImpl(new Widget(parent, flags), text); }
  386.  
  387. //--------------------------------------------------------------------------------------------
  388. inline RLabel *createLabel(const char *text, RWidget *parent, RWFlags flags = RWF_DestructiveClose)
  389. { return createLabelImpl(new RLabel(parent, flags), text); }
  390.  
  391.  
  392.  
  393. //--------------------------------------------------------------------------------------------
  394. // DATEEDITBOX
  395. //--------------------------------------------------------------------------------------------
  396. template <typename T>
  397. inline CDateEditBox *createDateEditBox(T *parent, RWFlags flags = RWF_DestructiveClose)
  398. { return BaseWidgets::createDateEditBoxByParent(parent, flags); }
  399.  
  400. //--------------------------------------------------------------------------------------------
  401. // TIMEEDITBOX
  402. //--------------------------------------------------------------------------------------------
  403. template <typename T>
  404. inline CTimeEditBox *createTimeEditBox(T *parent, RWFlags flags = RWF_DestructiveClose)
  405. { return BaseWidgets::createTimeEditBoxByParent(parent, flags); }
  406.  
  407. }
  408.  
  409. #endif
Advertisement
Add Comment
Please, Sign In to add comment