mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 14:16:09 -06:00
440 lines
11 KiB
C++
440 lines
11 KiB
C++
#include "Form.hpp"
|
|
#include "IniConfig.hpp"
|
|
|
|
static int tempFormsCount = 0;
|
|
|
|
Form:: Form() : _Current(-1) {}
|
|
Form::~Form() { Clear(); }
|
|
|
|
bool Form::Load(const String& file)
|
|
{
|
|
Clear();
|
|
|
|
if (!FileExists(file))
|
|
return false;
|
|
|
|
if (GetFileExt(file) == ".fz")
|
|
{
|
|
String s = ZDecompress(LoadFile(file));
|
|
if (!LoadFromXML(*this, s))
|
|
return false;
|
|
_File = file;
|
|
return true;
|
|
}
|
|
|
|
if (!LoadFromXMLFile(*this, file))
|
|
return false;
|
|
_File = file;
|
|
return true;
|
|
}
|
|
|
|
bool Form::Layout(const String& layout, Font font)
|
|
{
|
|
_Current = -1;
|
|
for (int i = 0; i < _Layouts.GetCount(); ++i)
|
|
if (_Layouts[i].Get("Form.Name") == layout)
|
|
{
|
|
_Current = i;
|
|
return Generate(font);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Form::Generate(Font font)
|
|
{
|
|
if (!IsLayout())
|
|
return false;
|
|
|
|
Clear(false);
|
|
|
|
Size sz = _Layouts[_Current].GetFormSize();
|
|
SetRect( Rect(Point(0, 0), Size(HorzLayoutZoom(sz.cx), VertLayoutZoom(sz.cy))) );
|
|
|
|
Vector<FormObject>* p = &_Layouts[_Current].GetObjects();
|
|
|
|
if (_Layouts[_Current].GetBool("Form.MinimizeBox", false)) MinimizeBox();
|
|
if (_Layouts[_Current].GetBool("Form.MaximizeBox", false)) MaximizeBox();
|
|
|
|
#ifdef PLATFORM_WIN32
|
|
if (_Layouts[_Current].GetBool("Form.ToolWindow", false)) ToolWindow();
|
|
#endif
|
|
|
|
if (_Layouts[_Current].GetBool("Form.Sizeable", false)) Sizeable();
|
|
|
|
Title(_Layouts[_Current].Get("Form.Title"));
|
|
|
|
for (int i = 0; i < p->GetCount(); ++i)
|
|
{
|
|
Font objFont = font;
|
|
int h = (*p)[i].GetNumber("Font.Height", 0);
|
|
if (h != 0) objFont.Height( VertLayoutZoom(h) );
|
|
if (font.GetHeight() == 0) objFont.Height( StdFont().GetHeight() );
|
|
Ctrl *c = NULL;
|
|
|
|
if ((*p)[i].Get("Type") == "Button")
|
|
{
|
|
Button *b = &_Ctrls.Create<Button>((*p)[i].Get("Variable"));
|
|
b->SetFont(objFont);
|
|
b->SetLabel((*p)[i].Get("Label"));
|
|
b->Tip((*p)[i].Get("Tip"));
|
|
*b <<= THISBACK1(OnAction, (*p)[i].Get("Action"));
|
|
c = b;
|
|
}
|
|
|
|
if ((*p)[i].Get("Type") == "EditField")
|
|
{
|
|
EditField *e = &_Ctrls.Create<EditField>((*p)[i].Get("Variable"));
|
|
e->SetFont(objFont);
|
|
if ((*p)[i].Get("Style") == "Password")
|
|
e->Password();
|
|
e->Tip((*p)[i].Get("Tip"));
|
|
if ((*p)[i].Get("TextAlign") == "Right")
|
|
e->AlignRight();
|
|
|
|
c = e;
|
|
}
|
|
|
|
if ((*p)[i].Get("Type") == "Label")
|
|
{
|
|
Label *e = &_Ctrls.Create<Label>((*p)[i].Get("Variable"));
|
|
e->SetFont(objFont);
|
|
Color fontColor = Black();
|
|
LoadFromString(fontColor, Decode64((*p)[i].Get("Font.Color",
|
|
StoreAsString(fontColor))));
|
|
e->SetInk(fontColor);
|
|
String align = (*p)[i].Get("Text.Align");
|
|
if (align == "Center") e->SetAlign(ALIGN_CENTER);
|
|
if (align == "Right") e->SetAlign(ALIGN_RIGHT);
|
|
if (align == "Left") e->SetAlign(ALIGN_LEFT);
|
|
e->SetLabel((*p)[i].Get("Label"));
|
|
c = e;
|
|
}
|
|
|
|
if ((*p)[i].Get("Type") == "DropDate")
|
|
{
|
|
DropDate *e = &_Ctrls.Create<DropDate>((*p)[i].Get("Variable"));
|
|
e->SetFont(objFont);
|
|
c = e;
|
|
}
|
|
|
|
if ((*p)[i].Get("Type") == "ProgressBar")
|
|
{
|
|
ProgressIndicator *e = &_Ctrls.Create<ProgressIndicator>((*p)[i].Get("Variable"));
|
|
e->Set(
|
|
(*p)[i].GetNumber("ProgressBar.Initial", 0),
|
|
(*p)[i].GetNumber("ProgressBar.Total", 100));
|
|
c = e;
|
|
}
|
|
|
|
if ((*p)[i].Get("Type") == "EditInt")
|
|
{
|
|
EditInt *e = &_Ctrls.Create<EditInt>((*p)[i].Get("Variable"));
|
|
e->SetFont(objFont);
|
|
e->Min((*p)[i].GetNumber("Min", INT_MIN, INT_MAX, INT_MIN));
|
|
e->Max((*p)[i].GetNumber("Max", INT_MIN, INT_MAX, INT_MAX));
|
|
c = e;
|
|
}
|
|
|
|
if ((*p)[i].Get("Type") == "GridCtrl")
|
|
{
|
|
GridCtrl *e = &_Ctrls.Create<GridCtrl>((*p)[i].Get("Variable"));
|
|
e->Chameleon();
|
|
c = e;
|
|
|
|
String src = (*p)[i].Get("Grid.Columns");
|
|
ReplaceString(src, ";", "\r\n");
|
|
StringStream s;
|
|
s.Open(src);
|
|
IniFile f;
|
|
f.Load(s);
|
|
|
|
Vector<String> names = f.EnumNames("Columns");
|
|
|
|
for (int j = 0; j < names.GetCount(); ++j)
|
|
{
|
|
int n = ScanInt(names[j]);
|
|
|
|
if (AsString(n) != names[j])
|
|
continue;
|
|
|
|
Vector<String> values = f.GetArray("Columns", names[j]);
|
|
if (values.GetCount() != 3)
|
|
continue;
|
|
if (values[1] == "Left") e->AddColumn(values[0]).HeaderAlignCenterLeft();
|
|
else if (values[1] == "Right") e->AddColumn(values[0]).HeaderAlignCenterRight();
|
|
else e->AddColumn(values[0]).HeaderAlignCenter();
|
|
}
|
|
}
|
|
|
|
if ((*p)[i].Get("Type") == "TabCtrl")
|
|
{
|
|
TabCtrl *e = &_Ctrls.Create<TabCtrl>((*p)[i].Get("Variable"));
|
|
TabCtrl::Style& style = e->StyleDefault().Write();
|
|
style.font = objFont;
|
|
style.tabheight = objFont.GetHeight() + VertLayoutZoom(10);
|
|
e->SetStyle(style);
|
|
|
|
String src = (*p)[i].Get("Tab.Content");
|
|
ReplaceString(src, ";", "\r\n");
|
|
StringStream s;
|
|
s.Open(src);
|
|
IniFile f;
|
|
f.Load(s);
|
|
|
|
Vector<String> names = f.EnumNames("Tabs");
|
|
VectorMap<int, Vector<String> > cache;
|
|
|
|
for (int j = 0; j < names.GetCount(); ++j)
|
|
{
|
|
int n = ScanInt(names[j]);
|
|
|
|
if (AsString(n) != names[j])
|
|
continue;
|
|
|
|
Vector<String> values = f.GetArray("Tabs", names[j]);
|
|
if (values.GetCount() != 3)
|
|
continue;
|
|
|
|
if (values[0] == t_("Current form"))
|
|
values[0] = _File;
|
|
|
|
Container *cont = &_Ctrls.Create<Container>("TemporaryContainer"
|
|
+ AsString(tempFormsCount));
|
|
|
|
Form *f = &_Ctrls.Create<Form>("TemporaryForm" + AsString(tempFormsCount++));
|
|
|
|
if (values[0] != _File)
|
|
{
|
|
if (!f->Load(GetFileDirectory(_File) + "\\" + values[0]))
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
int lay = HasLayout(values[1]);
|
|
if (lay < 0)
|
|
continue;
|
|
f->GetLayouts().Add(_Layouts[lay]);
|
|
}
|
|
|
|
if (!f->Layout(values[1], objFont))
|
|
continue;
|
|
|
|
cont->Set(*f, f->GetSize());
|
|
cont->SizePos();
|
|
e->Add(*cont, values[2]);
|
|
}
|
|
|
|
if (e->GetCount())
|
|
{
|
|
int active = (*p)[i].GetNumber("Tab.Active", -1, -1);
|
|
|
|
if (active < 0)
|
|
active = 0;
|
|
|
|
if (active >= e->GetCount())
|
|
active = e->GetCount() - 1;
|
|
|
|
e->Set(active);
|
|
}
|
|
|
|
c = e;
|
|
}
|
|
|
|
if ((*p)[i].Get("Type") == "Form")
|
|
{
|
|
Form *f = &_Ctrls.Create<Form>((*p)[i].Get("Variable"));
|
|
f->SignalHandler = SignalHandler;
|
|
String path = (*p)[i].Get("Form.Path");
|
|
(*p)[i].Get("Form.PathType") == "Relative"
|
|
? f->Load(::GetFileDirectory(_File) + "\\" + path)
|
|
: f->Load(path);
|
|
f->Layout((*p)[i].Get("Form.Layout"), objFont);
|
|
f->Script = Script;
|
|
c = f;
|
|
}
|
|
|
|
if (!c) continue;
|
|
|
|
switch((*p)[i].GetHAlign())
|
|
{
|
|
case Ctrl::LEFT:
|
|
c->LeftPosZ((*p)[i].GetRect().left, (*p)[i].GetRect().Width());
|
|
break;
|
|
case Ctrl::RIGHT:
|
|
c->RightPosZ(sz.cx - (*p)[i].GetRect().left - (*p)[i].GetRect().Width(), (*p)[i].GetRect().Width());
|
|
break;
|
|
case Ctrl::SIZE:
|
|
c->HSizePosZ((*p)[i].GetRect().left, sz.cx - (*p)[i].GetRect().left - (*p)[i].GetRect().Width());
|
|
break;
|
|
case Ctrl::CENTER:
|
|
c->HCenterPosZ((*p)[i].GetRect().Width());
|
|
}
|
|
|
|
switch((*p)[i].GetVAlign())
|
|
{
|
|
case Ctrl::TOP:
|
|
c->TopPosZ((*p)[i].GetRect().top, (*p)[i].GetRect().Height());
|
|
break;
|
|
case Ctrl::BOTTOM:
|
|
c->BottomPosZ(sz.cy - (*p)[i].GetRect().top - (*p)[i].GetRect().Height(), (*p)[i].GetRect().Height());
|
|
break;
|
|
case Ctrl::SIZE:
|
|
c->VSizePosZ((*p)[i].GetRect().top, sz.cy - (*p)[i].GetRect().top - (*p)[i].GetRect().Height());
|
|
break;
|
|
case Ctrl::CENTER:
|
|
c->VCenterPosZ((*p)[i].GetRect().Height());
|
|
}
|
|
|
|
String frame = (*p)[i].Get("Frame");
|
|
|
|
if (frame == "Null frame") c->SetFrame(NullFrame());
|
|
if (frame == "Field frame") c->SetFrame(FieldFrame());
|
|
if (frame == "Inset frame") c->SetFrame(InsetFrame());
|
|
if (frame == "Outset frame") c->SetFrame(OutsetFrame());
|
|
if (frame == "Thin inset frame") c->SetFrame(ThinInsetFrame());
|
|
if (frame == "Thin outset frame") c->SetFrame(ThinOutsetFrame());
|
|
if (frame == "Black frame") c->SetFrame(BlackFrame());
|
|
if (frame == "Button frame") c->SetFrame(ButtonFrame());
|
|
if (frame == "Top separator frame") c->SetFrame(TopSeparatorFrame());
|
|
if (frame == "Left separator frame") c->SetFrame(LeftSeparatorFrame());
|
|
if (frame == "Right separator frame") c->SetFrame(RightSeparatorFrame());
|
|
if (frame == "Bottom separator frame") c->SetFrame(BottomSeparatorFrame());
|
|
|
|
AddChild(c);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
String Form::ExecuteForm()
|
|
{
|
|
if (!IsLayout())
|
|
return "Error";
|
|
|
|
WhenClose = TopWindow::Breaker(0);
|
|
int result;
|
|
|
|
for (;;)
|
|
{
|
|
result = TopWindow::Execute();
|
|
|
|
if (result == 0)
|
|
return "Close";
|
|
|
|
if (result < 0)
|
|
return _Rejectors[ abs(result) - 1 ];
|
|
|
|
Vector<FormObject>* p = &_Layouts[_Current].GetObjects();
|
|
bool null = false;
|
|
for (int i = 0; i < p->GetCount(); ++i)
|
|
{
|
|
if ((*p)[i].GetBool("NotNull"))
|
|
if (IsNull(~_Ctrls[i]))
|
|
{
|
|
PromptOK("Необходимо заполнить поле: " + (*p)[i].Get("Variable"));
|
|
null = true;
|
|
break;
|
|
}
|
|
}
|
|
if (null)
|
|
continue;
|
|
|
|
break;
|
|
}
|
|
|
|
return _Acceptors[ result - 1 ];
|
|
}
|
|
|
|
void Form::Clear(bool all)
|
|
{
|
|
if (all) _Layouts.Clear();
|
|
_Rejectors.Clear();
|
|
_Acceptors.Clear();
|
|
_Ctrls.Clear();
|
|
Script.Clear();
|
|
}
|
|
|
|
int Form::HasLayout(const String& layout)
|
|
{
|
|
for (int i = 0; i < _Layouts.GetCount(); ++i)
|
|
if (_Layouts[i].Get("Form.Name") == layout)
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
void Form::OnAction(const String& action)
|
|
{
|
|
SignalHandler(Script, "OnAction", action);
|
|
}
|
|
|
|
bool Form::Exit(const String& action)
|
|
{
|
|
return SetCallback(action, TopWindow::Rejector(0));
|
|
}
|
|
|
|
bool Form::Acceptor(const String& action)
|
|
{
|
|
if (SetCallback(action, TopWindow::Acceptor( _Acceptors.GetCount() + 1 )))
|
|
{
|
|
_Acceptors << action;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Form::Rejector(const String& action)
|
|
{
|
|
if (SetCallback(action, TopWindow::Rejector( -(_Rejectors.GetCount() + 1) )))
|
|
{
|
|
_Rejectors << action;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Form::SetCallback(const String& action, Callback c)
|
|
{
|
|
if (!IsLayout())
|
|
return false;
|
|
|
|
Vector<FormObject>* p = &_Layouts[_Current].GetObjects();
|
|
for (int i = 0; i < p->GetCount(); ++i)
|
|
{
|
|
if ((*p)[i].Get("Type") == "Button")
|
|
if ((*p)[i].Get("Action") == action)
|
|
{
|
|
_Ctrls[i] <<= c;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
Value Form::GetData(const String& var)
|
|
{
|
|
if (!IsLayout())
|
|
return false;
|
|
|
|
Vector<FormObject>* p = &_Layouts[_Current].GetObjects();
|
|
for (int i = 0; i < p->GetCount(); ++i)
|
|
{
|
|
if ((*p)[i].Get("Variable") == var)
|
|
return ~_Ctrls[i];
|
|
}
|
|
return Value();
|
|
}
|
|
|
|
Ctrl* Form::GetCtrl(const String& var)
|
|
{
|
|
if (!IsLayout())
|
|
return false;
|
|
|
|
Vector<FormObject>* p = &_Layouts[_Current].GetObjects();
|
|
for (int i = 0; i < p->GetCount(); ++i)
|
|
{
|
|
if ((*p)[i].Get("Variable") == var)
|
|
return &_Ctrls[i];
|
|
}
|
|
return NULL;
|
|
}
|