Удобное управление Enabled/Disabled (Builder)
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 25.01.03 18:48
Оценка: 43 (6)
Надоело писать:


Button1->Enabled = SomeCondition;
Button2->Enabled = SomeConsition;
...
ButtonXXX->Enabled = SomeConsition;


В общем, куча ненужного дублирования кода...



Набросал простенький классец, который вышеописанную проблему решает так:

TDisabler Disabler;

// можно задизаблить так:
Disabler << Button1 << Button2 << Label1 << Memo1 << ListView1;

// можно заэнаблить так
Disabler >> Button1 >> Button2 >> Label1 >> Memo1 >> ListView1;


// Можно просто менять состояние в зависимости от условия

// если true - то будет включать компоненты, false - выключать
Disabler.SetEnabled(SomeCondition); 
Disabler << Button1 << Button2 << Label1 << Memo1 << ListView1;


Сам класс:

//---------------------------------------------------------------------------
#ifndef EnablerHelperH
#define EnablerHelperH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <TypInfo.hpp>
//---------------------------------------------------------------------------
class TDisabler
{
private:

void SetComponentState(TComponent* Component)
 {
 if(Component)
   {
    PPropInfo PropInfo = GetPropInfo((PTypeInfo)Component->ClassInfo(), "Enabled");
    if (PropInfo)
      SetOrdProp(static_cast<TObject *>(Component), PropInfo, (int)FEnabled);
   }
 }
bool FEnabled;

public:

   void SetEnabled(bool Enabled) {FEnabled = Enabled;}

   TDisabler() : FEnabled(false) {}
  ~TDisabler() {}

   TDisabler& operator<<(TComponent* Component)
    {
      if(Component)
       {
        SetComponentState(Component);
       }
     return *this;
    }

   TDisabler& operator>>(TComponent* Component)
    {
      if(Component)
       {
        bool Temp = FEnabled;
        FEnabled = true;
        SetComponentState(Component);
        FEnabled = Temp;
       }
     return *this;
    }

};
//---------------------------------------------------------------------------
#endif
Re: Удобное управление Enabled/Disabled (Builder)
От: eaglus Россия  
Дата: 26.01.03 11:46
Оценка:
А почему не шаблоном?
... << RSDN@Home 1.0 beta 5 >>
Re: Удобное управление Enabled/Disabled (Builder)
От: ArtDenis Россия  
Дата: 26.01.03 14:24
Оценка: 3 (1)
Здравствуйте, Flamer, Вы писали:

F>Надоело писать:


F>

F>
Button1->>Enabled = SomeCondition;
Button2->>Enabled = SomeConsition;
F>...
ButtonXXX->>Enabled = SomeConsition;
F>


Мне тоже надоело так писать , но сделал я немножко по-другому :
// для меню
void set_enabled(bool value, TMenuItem *item1, ...)
{
  va_list pointer;
  TMenuItem *item;

  item1->Enabled = value;
  va_start(pointer, item1);
  for ( ; ; )
  {
    item = va_arg(pointer, TMenuItem*);
    if (item == NULL) break;
    item->Enabled = value;
  }
  va_end(pointer);
}

// для контролов
void set_enabled(bool value, TControl *control1, ...)
{
  va_list pointer;
  TControl *control;

  control1->Enabled = value;
  va_start(pointer, control1);
  for ( ; ; )
  {
    control = va_arg(pointer, TControl*);
    if (control == NULL) break;
    control->Enabled = value;
  }
  va_end(pointer);
}


Пользуемся так:
  set_enabled(false, Label1, Button2, Button1, NULL); 
  set_enabled(true, Label2, Label3, NULL);


Одна проблема — два подхода.
... << RSDN@Home 1.0 beta 5 >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re: Удобное управление Enabled/Disabled (Builder)
От: Кодт Россия  
Дата: 26.01.03 16:11
Оценка:
Здравствуйте, Flamer, Вы писали:

F>Надоело писать:


<>

Круто!

Но тогда можно обобщить.
Есть политики
— включить/выключить все
— включить n-ный, выключить остальные (режим "радиокнопка")

И вообще,
— применить некую операцию с булевским параметром (используя ту или иную политику).

А назвать инструмент все же лучше "Enabler" (меняю электропроигрыватель на электровыигрыватель)
Перекуём баги на фичи!
Re: Удобное управление Enabled/Disabled (Builder)
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 26.01.03 16:46
Оценка:
Здравствуйте, Flamer, Вы писали:

F>Надоело писать:


[]

В продолжение темы: в общем, и указанное выше усовершенствование мне не понравилось Ведь помимо свойства "Enabled" есть свойство "ShowHint", например... Ну и другие Boolean-свойства, состояние которых в программе может зависеть от какого-то условия. Итак, что получилось во второй версии:

TBooleanManager Manager;

// запрещаем всплывающие подсказки...
Manager << "ShowHint" << false << Button1 << ComboBox1 << Memo1 << ListView1;


// разрешаем всплывающие подсказки
Manager << "ShowHint" << true << Button1 << ComboBox1 << Memo1 << ListView1;

// Выключаем контролы
Manager << "Enabled" << false << Button1 << ComboBox1 << Memo1 << ListView1;


Удобнее, согласитесь? Итак, сорц:

//---------------------------------------------------------------------------
#ifndef BooleanManagerH
#define BooleanManagerH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <TypInfo.hpp>
//---------------------------------------------------------------------------
class TBooleanManager
{
private:

void SetComponentState(TComponent* Component)
 {
 if(Component && !FPropertyName.IsEmpty())
   {
    PPropInfo PropInfo = GetPropInfo((PTypeInfo)Component->ClassInfo(), FPropertyName);
    if (PropInfo)
      SetOrdProp(static_cast<TObject *>(Component), PropInfo, (int)FTrue);
   }
 }
bool FTrue;
String FPropertyName;

public:


   TBooleanManager() : FTrue(false),FPropertyName("Enabled") {}
  ~TBooleanManager() {}


    TBooleanManager& operator<<(char* PropName)
    {
     FPropertyName = PropName;
     return *this;
    }

    TBooleanManager& operator<<(bool IsTrue)
    {
     FTrue = IsTrue;
     return *this;
    }

   TBooleanManager& operator<<(TComponent* Component)
    {
      if(Component)
       {
        SetComponentState(Component);
       }
     return *this;
    }
    
};
//---------------------------------------------------------------------------
#endif
Re[2]: Удобное управление Enabled/Disabled (Builder)
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 26.01.03 16:46
Оценка:
Здравствуйте, eaglus, Вы писали:

E>А почему не шаблоном?



Лень
Re[2]: Удобное управление Enabled/Disabled (Builder)
От: scopr21  
Дата: 05.02.03 09:16
Оценка:
Здравствуйте, ArtDenis, Вы писали:

А не проще пользовать Update у Action?

void __fastcall TfrmFindingAid::actSomeActionUpdate(TObject *Sender)
{
  TAction* pAction = dynamic_cast<TAction*>(Sender);
  Assert(pAction != NULL);

  pAction->Enabled = AllowSomeAction();
}
//---------------------------------------------------------------------------


Написал один раз правильно и забыл про нее.
... << RSDN@Home 1.0 beta 6a >>
All we are is dust in the wind...
Re[2]: Удобное управление Enabled/Disabled (Builder)
От: Slicer [Mirkwood] Россия https://ru.linkedin.com/in/maksim-gumerov-039a701b
Дата: 13.07.04 08:13
Оценка:
Иногда все же удобнее и логичнее писать без перегрузки

PropertySetter("Enabled",true)<<Control1<<Control2

А можно, интересно, так?
PropertySetter<char* prop, bool value> : public PropertyChangeTool;
BoolPropertyInvertor<char* prop> : public PropertyChangeTool;

(или даже так: PropertySetter<char* prop, T value> или PropertySetter<char* prop, typename T, T value>)

и потом

PropertySetter<"Enabled",true> << Control1 << Control2;
BoolPropertyInvertor<"Enabled"> << Control1 << Control2;

Не силен я пока в шаблонах

Одно плохо, translate.ru упорно переводит setter как сеттер

Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re: Удобное управление Enabled/Disabled (Builder)
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 15.07.04 08:15
Оценка: 10 (2)
Здравствуйте, Flamer, Вы писали:

F>Надоело писать:


[]

Таки доизвратился ... Добавил поддержку рекурсивного включения/выключения булевых свойств у контролов. Теперь это выглядит так:

void __fastcall TForm1::Button3Click(TObject *Sender)
{
TBooleanManager Manager;

// Выключаем все дочерние контролы Panel1
Manager << "Enabled" << false << roRecursion << Panel1;

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
TBooleanManager Manager;

// Включаем все дочерние контролы Panel1
Manager << "Enabled" << true << roRecursion << Panel1;

}
//---------------------------------------------------------------------------


А вот, собственно, доделанный сырец (добавлено несколько конструкторов и пр. мишура):

//---------------------------------------------------------------------------
#ifndef BooleanManagerH
#define BooleanManagerH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <TypInfo.hpp>
//---------------------------------------------------------------------------
typedef enum
{
  roNoRecursion = 100,
  roRecursion
  
} TRecursionOptions;
//---------------------------------------------------------------------------
class TBooleanManager
{
private:

void SetComponentState(TComponent* Component)
 {
 if(Component && !FPropertyName.IsEmpty())
   {
    PPropInfo PropInfo = GetPropInfo((PTypeInfo)Component->ClassInfo(), FPropertyName);
    if (PropInfo)
      SetOrdProp(static_cast<TObject *>(Component), PropInfo, (int)FTrue);

      if(FOptions == roRecursion)
      {
      TWinControl* wc = dynamic_cast<TWinControl*>(Component);
          if(wc)
            for(int i=0;i<wc->ControlCount;i++)
            {
               SetComponentState(wc->Controls[i]);
            }
      }

   }
 }
bool FTrue;
String FPropertyName;
TRecursionOptions FOptions;

public:



   TBooleanManager() : FTrue(false),FPropertyName("Enabled") {}


   TBooleanManager(const char* PropName) : FPropertyName(PropName),
        FTrue(false),FOptions(roNoRecursion) {}

   TBooleanManager(const String& PropName) : FPropertyName(PropName),
        FTrue(false),FOptions(roNoRecursion) {}

   TBooleanManager(const char* PropName, bool IsTrue) : FPropertyName(PropName),
        FTrue(IsTrue),FOptions(roNoRecursion) {}

   TBooleanManager(const String& PropName, bool IsTrue) : FPropertyName(PropName),
        FTrue(IsTrue),FOptions(roNoRecursion) {}



  ~TBooleanManager() {}

    TBooleanManager& operator<<(const String& PropName)
    {
     FPropertyName = PropName;
     return *this;
    }

    TBooleanManager& operator<<(char* PropName)
    {
     FPropertyName = PropName;
     return *this;
    }

    TBooleanManager& operator<<(TRecursionOptions Options)
    {
     FOptions = Options;
     return *this;
    }

    TBooleanManager& operator<<(bool IsTrue)
    {
     FTrue = IsTrue;
     return *this;
    }

   TBooleanManager& operator<<(TComponent* Component)
    {
      if(Component)
       {
        SetComponentState(Component);
       }
     return *this;
    }



    
};
//---------------------------------------------------------------------------
#endif
Re[2]: Удобное управление Enabled/Disabled (Builder)
От: BkmzBIN Беларусь  
Дата: 28.04.05 07:32
Оценка:
Здравствуйте, Flamer, Вы писали:

F>Таки доизвратился ... Добавил поддержку рекурсивного включения/выключения булевых свойств у контролов. Теперь это выглядит так:


Было бы просто супер, если бы был вариант и для Delphi
Re[3]: Удобное управление Enabled/Disabled (Builder)
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 28.04.05 08:59
Оценка:
Здравствуйте, BkmzBIN, Вы писали:

[]

BBI>Было бы просто супер, если бы был вариант и для Delphi


Так в чем проблема — попробуйте Я в Дельфи не шарю.
Re[3]: Удобное управление Enabled/Disabled (Builder)
От: BkmzBIN Беларусь  
Дата: 28.04.05 09:01
Оценка:
BBI>Было бы просто супер, если бы был вариант и для Delphi
Оказалось всё очень просто:

procedure SetState(PropName: string; IsTrue: Integer; Components: array of const);
var
  i: Integer;
begin
  for i := Low(Components) to High(Components) do
    with TVarRec(Components[i]) do
      SetOrdProp(VObject, PropName, IsTrue);
end;


Спасибо, Flamer.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.