+// ////////////////////////////////////////////////////////////////////////// //
+constructor TUIBox.Create (ahoriz: Boolean);
+begin
+ inherited Create();
+ mHoriz := ahoriz;
+end;
+
+
+procedure TUIBox.AfterConstruction ();
+begin
+ inherited AfterConstruction();
+ mCanFocus := false;
+ mCtl4Style := 'box';
+end;
+
+
+function TUIBox.parseProperty (const prname: AnsiString; par: TTextParser): Boolean;
+begin
+ if (parseOrientation(prname, par)) then begin result := true; exit; end;
+ if (strEquCI1251(prname, 'frame')) then
+ begin
+ mHasFrame := parseBool(par);
+ if (mHasFrame) then begin mFrameWidth := 8; mFrameHeight := 8; end else begin mFrameWidth := 0; mFrameHeight := 0; end;
+ result := true;
+ exit;
+ end;
+ if (strEquCI1251(prname, 'title')) or (strEquCI1251(prname, 'caption')) then
+ begin
+ mCaption := par.expectIdOrStr(true);
+ mDefSize := TLaySize.Create(Length(mCaption)*8+3, 8);
+ result := true;
+ exit;
+ end;
+ if (strEquCI1251(prname, 'children')) then
+ begin
+ parseChildren(par);
+ result := true;
+ exit;
+ end;
+ result := inherited parseProperty(prname, par);
+end;
+
+
+procedure TUIBox.drawControl (gx, gy: Integer);
+var
+ cidx: Integer;
+ tx: Integer;
+begin
+ cidx := getColorIndex;
+ fillRect(gx, gy, mWidth, mHeight, mBackColor[cidx]);
+ if mHasFrame then
+ begin
+ // draw frame
+ drawRectUI(gx+3, gy+3, mWidth-6, mHeight-6, mFrameColor[cidx]);
+ end;
+ // draw caption
+ if (Length(mCaption) > 0) then
+ begin
+ setScissor(mFrameWidth+1, 0, mWidth-mFrameWidth-2, 8);
+ tx := gx+((mWidth-Length(mCaption)*8) div 2);
+ if mHasFrame then fillRect(tx-2, gy, Length(mCaption)*8+3, 8, mBackColor[cidx]);
+ drawText8(tx, gy, mCaption, mFrameTextColor[cidx]);
+ end;
+end;
+
+
+function TUIBox.mouseEvent (var ev: THMouseEvent): Boolean;
+var
+ lx, ly: Integer;
+begin
+ result := inherited mouseEvent(ev);
+ if not result and toLocal(ev.x, ev.y, lx, ly) then
+ begin
+ result := true;
+ end;
+end;
+
+
+//TODO: navigation with arrow keys, according to box orientation
+function TUIBox.keyEvent (var ev: THKeyEvent): Boolean;
+begin
+ result := inherited keyEvent(ev);
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+procedure TUIHBox.AfterConstruction ();
+begin
+ inherited AfterConstruction();
+ mHoriz := true;
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+procedure TUIVBox.AfterConstruction ();
+begin
+ inherited AfterConstruction();
+ mHoriz := false;
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+procedure TUISpan.AfterConstruction ();
+begin
+ inherited AfterConstruction();
+ mExpand := true;
+ mCanFocus := false;
+ mCtl4Style := 'span';
+end;
+
+
+function TUISpan.parseProperty (const prname: AnsiString; par: TTextParser): Boolean;
+begin
+ if (parseOrientation(prname, par)) then begin result := true; exit; end;
+ result := inherited parseProperty(prname, par);
+end;
+
+
+procedure TUISpan.drawControl (gx, gy: Integer);
+begin
+end;
+
+
+// ////////////////////////////////////////////////////////////////////// //
+procedure TUILine.AfterConstruction ();
+begin
+ inherited AfterConstruction();
+ mExpand := true;
+ mCanFocus := false;
+ mCtl4Style := 'line';
+end;
+
+
+function TUILine.parseProperty (const prname: AnsiString; par: TTextParser): Boolean;
+begin
+ if (parseOrientation(prname, par)) then begin result := true; exit; end;
+ result := inherited parseProperty(prname, par);
+end;
+
+
+procedure TUILine.drawControl (gx, gy: Integer);
+var
+ cidx: Integer;
+begin
+ cidx := getColorIndex;
+ if mHoriz then
+ begin
+ drawHLine(gx, gy+(mHeight div 2), mWidth, mTextColor[cidx]);
+ end
+ else
+ begin
+ drawVLine(gx+(mWidth div 2), gy, mHeight, mTextColor[cidx]);
+ end;
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+procedure TUIHLine.AfterConstruction ();
+begin
+ inherited AfterConstruction();
+ mHoriz := true;
+ mDefSize.h := 1;
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+procedure TUIVLine.AfterConstruction ();
+begin
+ inherited AfterConstruction();
+ mHoriz := false;
+ mDefSize.w := 1;
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+constructor TUITextLabel.Create (const atext: AnsiString);
+begin
+ inherited Create();
+ mText := atext;
+ mDefSize := TLaySize.Create(Length(atext)*8, 8);
+end;
+
+
+procedure TUITextLabel.AfterConstruction ();
+begin
+ inherited AfterConstruction();
+ mHAlign := -1;
+ mVAlign := 0;
+ mCanFocus := false;
+ if (mDefSize.h <= 0) then mDefSize.h := 8;
+ mCtl4Style := 'label';
+end;
+
+
+function TUITextLabel.parseProperty (const prname: AnsiString; par: TTextParser): Boolean;
+begin
+ if (strEquCI1251(prname, 'title')) or (strEquCI1251(prname, 'caption')) then
+ begin
+ mText := par.expectIdOrStr(true);
+ mDefSize := TLaySize.Create(Length(mText)*8, 8);
+ result := true;
+ exit;
+ end;
+ if (strEquCI1251(prname, 'textalign')) then
+ begin
+ parseTextAlign(par, mHAlign, mVAlign);
+ result := true;
+ exit;
+ end;
+ result := inherited parseProperty(prname, par);
+end;
+
+
+procedure TUITextLabel.drawControl (gx, gy: Integer);
+var
+ xpos, ypos: Integer;
+ cidx: Integer;
+begin
+ cidx := getColorIndex;
+ fillRect(gx, gy, mWidth, mHeight, mBackColor[cidx]);
+ if (Length(mText) > 0) then
+ begin
+ if (mHAlign < 0) then xpos := 0
+ else if (mHAlign > 0) then xpos := mWidth-Length(mText)*8
+ else xpos := (mWidth-Length(mText)*8) div 2;
+
+ if (mVAlign < 0) then ypos := 0
+ else if (mVAlign > 0) then ypos := mHeight-8
+ else ypos := (mHeight-8) div 2;
+
+ drawText8(gx+xpos, gy+ypos, mText, mTextColor[cidx]);
+ end;
+end;
+
+
+function TUITextLabel.mouseEvent (var ev: THMouseEvent): Boolean;
+var
+ lx, ly: Integer;
+begin
+ result := inherited mouseEvent(ev);
+ if not result and toLocal(ev.x, ev.y, lx, ly) then
+ begin
+ result := true;
+ end;
+end;
+
+
+function TUITextLabel.keyEvent (var ev: THKeyEvent): Boolean;
+begin
+ result := inherited keyEvent(ev);
+end;
+
+
+initialization
+ registerCtlClass(TUIHBox, 'hbox');
+ registerCtlClass(TUIVBox, 'vbox');
+ registerCtlClass(TUISpan, 'span');
+ registerCtlClass(TUIHLine, 'hline');
+ registerCtlClass(TUIVLine, 'vline');
+ registerCtlClass(TUITextLabel, 'label');