ultimatepp/bazaar/Form/Form.cpp
koldo ac7821deb8 Form: Form core package, Editor and sample from Sc0rch
git-svn-id: svn://ultimatepp.org/upp/trunk@2412 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2010-05-19 18:38:45 +00:00

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 = DefaultInk();
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.Execute(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;
}