DEADSOFTWARE

HolmesUI: ui parser fixes; vbox layouter fixes (centering control); scissoring fixes
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Sun, 24 Sep 2017 21:18:39 +0000 (00:18 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Sun, 24 Sep 2017 21:19:37 +0000 (00:19 +0300)
src/gx/gh_flexlay.pas
src/gx/gh_ui.pas
src/gx/glgfx.pas
src/shared/xparser.pas

index f9487028524e56367082f0211caa8a5805af6d98..79c6a5c578b8fc3a858d34eb5cc966f8a4a691c7 100644 (file)
@@ -502,6 +502,7 @@ var
   grp: PLayGroup;
   maxsz: Integer;
   cidx: LayControlIdx;
+  ct: PLayControl;
   mr: TLayMargins;
 begin
   // reset all 'laywrap' flags for controls, set initial 'startsize'
@@ -527,15 +528,17 @@ begin
       for c := 0 to High(grp.ctls) do
       begin
         cidx := grp.ctls[c];
-        if (maxsz < ctlist[cidx].startsize[gtype]) then maxsz := ctlist[cidx].startsize[gtype];
+        ct := @ctlist[cidx];
+        if (maxsz < ct.startsize[gtype]) then maxsz := ct.startsize[gtype];
       end;
       for c := 0 to High(grp.ctls) do
       begin
         cidx := grp.ctls[c];
-        if (maxsz <> ctlist[cidx].startsize[gtype]) then
+        ct := @ctlist[cidx];
+        if (maxsz <> ct.startsize[gtype]) then
         begin
           needRecalcMaxSize := true;
-          ctlist[cidx].startsize[gtype] := maxsz;
+          ct.startsize[gtype] := maxsz;
         end;
       end;
     end;
@@ -731,7 +734,7 @@ begin
       // expand or align
            if (lc.expand) then lc.desiredsize.w := nmin(lc.maxsize.w, me.desiredsize.w-me.margins.vert) // expand
       else if (lc.aligndir > 0) then lc.desiredpos.x := me.desiredsize.w-me.margins.right-lc.desiredsize.w // right align
-      else if (lc.aligndir = 0) then lc.desiredpos.x := (me.desiredsize.w-me.margins.horiz-lc.desiredsize.w) div 2; // center
+      else if (lc.aligndir = 0) then lc.desiredpos.x := (me.desiredsize.w-lc.desiredsize.w) div 2; // center
       if (not osz.equals(lc.desiredsize)) then
       begin
         if (lc.inGroup) then groupElementChanged := true;
@@ -833,7 +836,7 @@ begin
         end;
         for c := 0 to 1 do
         begin
-          if (ct.maxsize[c] <= 0) then continue;
+          if (ct.maxsize[c] < 0) then continue;
           if (ct.desiredsize[c] > ct.maxsize[c]) then
           begin
             //writeln('ctl #', f, '; dimension #', c, ': desired=', ctlist[f].desiredsize[c], '; max=', ctlist[f].maxsize[c]);
index a8593adacd9a4111c9e29fe2d9ae5b162094f131..a467408ab04b93ff6da97e1f97f0e532a725c793 100644 (file)
@@ -37,6 +37,7 @@ type
 
   private
     mParent: THControl;
+    mId: AnsiString;
     mX, mY: Integer;
     mWidth, mHeight: Integer;
     mFrameWidth, mFrameHeight: Integer;
@@ -159,8 +160,7 @@ type
 
   public
     constructor Create ();
-    constructor Create (aparent: THControl);
-    constructor Create (ax, ay, aw, ah: Integer; aparent: THControl=nil);
+    constructor Create (ax, ay, aw, ah: Integer);
     destructor Destroy (); override;
 
     // `sx` and `sy` are screen coordinates
@@ -191,6 +191,7 @@ type
     procedure appendChild (ctl: THControl); virtual;
 
   public
+    property id: AnsiString read mId;
     property x0: Integer read mX;
     property y0: Integer read mY;
     property height: Integer read mHeight;
@@ -250,7 +251,7 @@ type
     mItems: array of TItem;
 
   public
-    constructor Create (ax, ay: Integer; aparent: THControl=nil);
+    constructor Create (ax, ay: Integer);
     destructor Destroy (); override;
 
     procedure appendItem (const atext: AnsiString; acentered: Boolean=false; ahline: Boolean=false);
@@ -276,7 +277,7 @@ type
     mCurIndex: Integer;
 
   public
-    constructor Create (ax, ay: Integer; aparent: THControl=nil);
+    constructor Create (ax, ay: Integer);
     destructor Destroy (); override;
 
     procedure appendItem (const atext: AnsiString; bv: PBoolean; aaction: TActionCB=nil);
@@ -294,8 +295,7 @@ type
     mCaption: AnsiString;
 
   public
-    constructor Create (ahoriz: Boolean; aparent: THControl=nil);
-    //destructor Destroy (); override;
+    constructor Create (ahoriz: Boolean);
 
     function parseProperty (const prname: AnsiString; par: TTextParser): Boolean; override;
 
@@ -307,12 +307,12 @@ type
 
   THCtlHBox = class(THCtlBox)
   public
-    constructor Create (aparent: THControl=nil);
+    procedure AfterConstruction (); override; // so it will be correctly initialized when created from parser
   end;
 
   THCtlVBox = class(THCtlBox)
   public
-    constructor Create (aparent: THControl=nil);
+    procedure AfterConstruction (); override; // so it will be correctly initialized when created from parser
   end;
 
 
@@ -323,7 +323,7 @@ type
     mVAlign: Integer; // -1: top; 0: center; 1: bottom; default: center
 
   public
-    constructor Create (const atext: AnsiString; aparent: THControl=nil);
+    constructor Create (const atext: AnsiString);
     //destructor Destroy (); override;
 
     function parseProperty (const prname: AnsiString; par: TTextParser): Boolean; override;
@@ -618,9 +618,9 @@ begin
 end;
 
 
-constructor THControl.Create (ax, ay, aw, ah: Integer; aparent: THControl=nil);
+constructor THControl.Create (ax, ay, aw, ah: Integer);
 begin
-  Create(aparent);
+  Create();
   mX := ax;
   mY := ay;
   mWidth := aw;
@@ -628,13 +628,6 @@ begin
 end;
 
 
-constructor THControl.Create (aparent: THControl);
-begin
-  Create();
-  mParent := aparent;
-end;
-
-
 destructor THControl.Destroy ();
 var
   f, c: Integer;
@@ -685,6 +678,7 @@ begin
 end;
 
 procedure THControl.setActualSizePos (constref apos: TLayPos; constref asize: TLaySize); inline; begin
+  //writeln(self.className, '; pos=', apos.toString, '; size=', asize.toString);
   if (mParent <> nil) then
   begin
     mX := apos.x;
@@ -838,7 +832,7 @@ begin
   if (not par.eatDelim('{')) then exit;
   while (not par.eatDelim('}')) do
   begin
-    if (par.tokType <> par.TTId) and (par.tokType <> par.TTStr) then par.error('property name expected');
+    if (not par.isIdOrStr) then par.error('property name expected');
     pn := par.tokStr;
     par.skipToken();
     par.eatDelim(':'); // optional
@@ -856,13 +850,14 @@ begin
   par.expectDelim('{');
   while (not par.eatDelim('}')) do
   begin
-    if (par.tokType <> par.TTId) then par.error('control name expected');
+    if (not par.isIdOrStr) then par.error('control name expected');
     cc := findCtlClass(par.tokStr);
     if (cc = nil) then par.errorfmt('unknown control name: ''%s''', [par.tokStr]);
     //writeln('children for <', par.tokStr, '>: <', cc.className, '>');
     par.skipToken();
     par.eatDelim(':'); // optional
-    ctl := cc.Create(nil);
+    ctl := cc.Create();
+    //writeln('  mHoriz=', ctl.mHoriz);
     try
       ctl.parseProperties(par);
     except
@@ -879,6 +874,7 @@ end;
 function THControl.parseProperty (const prname: AnsiString; par: TTextParser): Boolean;
 begin
   result := true;
+  if (strEquCI1251(prname, 'id')) then begin mId := par.expectStrOrId(true); exit; end; // allow empty strings
   if (strEquCI1251(prname, 'flex')) then begin flex := par.expectInt(); exit; end;
   // sizes
   if (strEquCI1251(prname, 'defsize')) then begin mDefSize := parseSize(par); exit; end;
@@ -1179,8 +1175,7 @@ begin
   y := trunc(y*gh_ui_scale);
   w := trunc(w*gh_ui_scale);
   h := trunc(h*gh_ui_scale);
-  //y := gWinSizeY-(y+h);
-  scis.setRect(x, y, w, h);
+  scis.combineRect(x, y, w, h);
 end;
 
 
@@ -1199,9 +1194,16 @@ end;
 procedure THControl.setScissor (lx, ly, lw, lh: Integer);
 var
   x, y: Integer;
+  //ox, oy, ow, oh: Integer;
 begin
   if not scallowed then exit;
-  if not intersectRect(lx, ly, lw, lh, 0, 0, mWidth, mHeight) then begin glScissor(0, 0, 0, 0); exit; end;
+  //ox := lx; oy := ly; ow := lw; oh := lh;
+  if not intersectRect(lx, ly, lw, lh, 0, 0, mWidth, mHeight) then
+  begin
+    //writeln('oops: <', self.className, '>: old=(', ox, ',', oy, ')-[', ow, ',', oh, ']');
+    glScissor(0, 0, 0, 0);
+    exit;
+  end;
   x := lx;
   y := ly;
   toGlobal(x, y);
@@ -1245,6 +1247,7 @@ end;
 
 procedure THControl.drawControlPost (sx, sy: Integer);
 begin
+  // shadow
   if mDrawShadow and (mWidth > 0) and (mHeight > 0) then
   begin
     setScissorGLInternal(sx+8, sy+8, mWidth, mHeight);
@@ -1328,7 +1331,7 @@ end;
 // ////////////////////////////////////////////////////////////////////////// //
 constructor THTopWindow.Create (const atitle: AnsiString; ax, ay: Integer; aw: Integer=-1; ah: Integer=-1);
 begin
-  inherited Create(ax, ay, aw, ah, nil);
+  inherited Create(ax, ay, aw, ah);
   mFrameWidth := 8;
   mFrameHeight := 8;
   mTitle := atitle;
@@ -1527,7 +1530,7 @@ end;
 
 
 // ////////////////////////////////////////////////////////////////////////// //
-constructor THCtlSimpleText.Create (ax, ay: Integer; aparent: THControl=nil);
+constructor THCtlSimpleText.Create (ax, ay: Integer);
 begin
   mItems := nil;
   inherited Create(ax, ay, 4, 4);
@@ -1609,7 +1612,7 @@ end;
 
 
 // ////////////////////////////////////////////////////////////////////////// //
-constructor THCtlCBListBox.Create (ax, ay: Integer; aparent: THControl=nil);
+constructor THCtlCBListBox.Create (ax, ay: Integer);
 begin
   mItems := nil;
   mCurIndex := -1;
@@ -1768,9 +1771,9 @@ end;
 
 
 // ////////////////////////////////////////////////////////////////////////// //
-constructor THCtlBox.Create (ahoriz: Boolean; aparent: THControl=nil);
+constructor THCtlBox.Create (ahoriz: Boolean);
 begin
-  inherited Create(aparent);
+  inherited Create();
   mHoriz := ahoriz;
 end;
 
@@ -1829,6 +1832,7 @@ begin
   end;
 end;
 
+
 function THCtlBox.mouseEvent (var ev: THMouseEvent): Boolean;
 var
   lx, ly: Integer;
@@ -1851,23 +1855,24 @@ end;
 
 
 // ////////////////////////////////////////////////////////////////////////// //
-constructor THCtlHBox.Create (aparent: THControl=nil);
+procedure THCtlHBox.AfterConstruction ();
 begin
-  inherited Create(true, aparent);
+  inherited AfterConstruction();
+  mHoriz := true;
 end;
 
 
 // ////////////////////////////////////////////////////////////////////////// //
-constructor THCtlVBox.Create (aparent: THControl=nil);
+procedure THCtlVBox.AfterConstruction ();
 begin
-  inherited Create(false, aparent);
+  inherited AfterConstruction();
+  mHoriz := false;
 end;
 
-
 // ////////////////////////////////////////////////////////////////////////// //
-constructor THCtlTextLabel.Create (const atext: AnsiString; aparent: THControl=nil);
+constructor THCtlTextLabel.Create (const atext: AnsiString);
 begin
-  inherited Create(aparent);
+  inherited Create();
   mHAlign := -1;
   mVAlign := 0;
   mText := atext;
index d6f8763b401724947277acb25e5b7c79d28beb8a..61fa5f6278474d08943b9c2193f7860c7d52c4f6 100644 (file)
@@ -119,7 +119,7 @@ type
     procedure restore ();
 
     // set new scissor rect, bounded by the saved scissor rect
-    procedure setRect (x, y, w, h: Integer);
+    procedure combineRect (x, y, w, h: Integer);
   end;
 
 
@@ -1072,11 +1072,21 @@ begin
   if wassc then glEnable(GL_SCISSOR_TEST) else glDisable(GL_SCISSOR_TEST);
 end;
 
-procedure TScissorSave.setRect (x, y, w, h: Integer);
+procedure TScissorSave.combineRect (x, y, w, h: Integer);
+//var ox, oy, ow, oh: Integer;
 begin
   if (w < 1) or (h < 1) then begin glScissor(0, 0, 0, 0); exit; end;
   y := gScrHeight-(y+h);
-  if not intersectRect(x, y, w, h, scxywh[0], scxywh[1], scxywh[2], scxywh[3]) then glScissor(0, 0, 0, 0) else glScissor(x, y, w, h);
+  //ox := x; oy := y; ow := w; oh := h;
+  if not intersectRect(x, y, w, h, scxywh[0], scxywh[1], scxywh[2], scxywh[3]) then
+  begin
+    //writeln('oops: COMBINE: old=(', ox, ',', oy, ')-(', ox+ow-1, ',', oy+oh-1, '); sci: (', scxywh[0], ',', scxywh[1], ')-(', scxywh[0]+scxywh[2]-1, ',', scxywh[1]+scxywh[3]-1, ')');
+    glScissor(0, 0, 0, 0);
+  end
+  else
+  begin
+    glScissor(x, y, w, h);
+  end;
 end;
 
 //TODO: overflow checks
@@ -1087,11 +1097,11 @@ begin
   result := false;
   if (w0 < 1) or (h0 < 1) or (w1 < 1) or (h1 < 1) then exit;
   // check for intersection
-  if (x0+w0 <= x1) or (y0+h0 <= y1) or (x1+w1 <= x0) or (y1+h1 <= y0) then exit;
-  if (x0 >= x1+w1) or (y0 >= y1+h1) or (x1 >= x0+h0) or (y1 >= y0+h0) then exit;
-  // ok, intersects
   ex0 := x0+w0;
   ey0 := y0+h0;
+  if (ex0 <= x1) or (ey0 <= y1) or (x1+w1 <= x0) or (y1+h1 <= y0) then exit;
+  if (x0 >= x1+w1) or (y0 >= y1+h1) or (x1 >= ex0) or (y1 >= ey0) then exit;
+  // ok, intersects
   if (x0 < x1) then x0 := x1;
   if (y0 < y1) then y0 := y1;
   if (ex0 > x1+w1) then ex0 := x1+w1;
index b985f1a30a781724b03a058c5b644621b9d0c851..0f2c2ece5b06731f2a18d6c4a46dcf15e445f7d3 100644 (file)
@@ -106,6 +106,8 @@ type
     function skipToken1 (): Boolean;
     {$ENDIF}
 
+    function isIdOrStr (): Boolean; inline;
+
     function expectId (): AnsiString;
     procedure expectId (const aid: AnsiString; caseSens: Boolean=true);
     function eatId (const aid: AnsiString; caseSens: Boolean=true): Boolean;
@@ -650,6 +652,12 @@ begin
 end;
 
 
+function TTextParser.isIdOrStr (): Boolean; inline;
+begin
+  result := (mTokType = TTId) or (mTokType = TTStr);
+end;
+
+
 function TTextParser.expectId (): AnsiString;
 begin
   if (mTokType <> TTId) then raise Exception.Create('identifier expected');