Удобное управление Enabled/Disabled (Builder)
Надоело писать:
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)
Здравствуйте, 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, Вы писали:
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)
Здравствуйте, 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)
Иногда все же удобнее и логичнее писать без перегрузки
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, Вы писали:
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)
Здравствуйте, 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.
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить