StdTables.Table, aligning cell content to right or center
Posted: Thu Mar 16, 2017 12:18 pm
Problem: if the string shown in a cell of StdTables.Table is very large, the aligning to right or center does not work.
In order to align to right, one must click on the right part of the column header. One can also change the width of the column dynamically (click and drag the border of the column), and the new content gets updated to the new size.
Same problem aligning to center.
Trying to solve this, I arrived to these changes to module StdTables:
I have not tried, but imagine same problem happens to SqlControls.DrawField.
In order to align to right, one must click on the right part of the column header. One can also change the width of the column dynamically (click and drag the border of the column), and the new content gets updated to the new size.
Same problem aligning to center.
Trying to solve this, I arrived to these changes to module StdTables:
Code: Select all
PROCEDURE DrawLabel ...
VAR ...
k, end, delta: INTEGER;
BEGIN
...
sw := font.StringWidth(s);
IF sw > w THEN
IF (rw >= 0) & (LEN(s) >= 4) THEN
IF mode = left THEN
rw := w - font.StringWidth("...");
i := f.CharIndex(0, rw, s, font);
IF i > 0 THEN DEC(i) END;
IF i > LEN(s) - 4 THEN i := LEN(s) - 4 END;
s[i] := "."; s[i+1] := "."; s[i+2] := "."; s[i+3] := 0X;
ELSIF mode = right THEN
(* Instead of this, is it better to reverse array, align to left, and reverse again? *)
s[0] := "."; s[1] := "."; s[2] := ".";
i := f.CharIndex(0, w, s, font);
end := LEN(s$) - 1;
Log.String("Init: '" + s + "' "); Log.String(" len="); Log.Int(LEN(s$)); Log.String(" end="); Log.Int(end); Log.String(" i = "); Log.Int(i);Log.Ln;
WHILE (i <= end) DO
(* We could remove one char by one char to strinsg "s" from the left, until if fits, but instead, "delta" gives us a faster way to advance, although not very precise. *)
delta := end - i + 2; IF delta < 1 THEN delta := 1 END;
DEC(end, delta);
FOR k := 3 TO end DO s[k] := s[k + delta] END;
IF end >= -1 THEN s[end + 1] := 0X ELSE s[0] := 0X END;
i := f.CharIndex(0, w, s, font);
Log.String("delta="); Log.Int(delta); Log.String(" '" + s + "' "); Log.String(" len="); Log.Int(LEN(s$)); Log.String(" end="); Log.Int(end); Log.String(" i ="); Log.Int(i);Log.Ln;
END;
ELSE (* center *)
s[0] := "."; s[1] := "."; s[2] := ".";
end := LEN(s$) - 1;
IF end > 2 THEN s[end - 2] := "."; s[end - 1] := "."; s[end] := "." END;
i := f.CharIndex(0, w, s, font);
Log.String("Init: '" + s + "' "); Log.String(" len="); Log.Int(LEN(s$)); Log.String(" end="); Log.Int(end); Log.String(" i = "); Log.Int(i);Log.Ln;
WHILE (i <= end) DO
(* We could remove to strinsg "s" in each iteration one char from the left and another from the right, until if fits, but instead, "delta" gives us a faster way to advance, although not very precise. *)
delta := (end - i + 2) DIV 2; IF delta < 1 THEN delta := 1 END;
DEC(end, delta * 2);
FOR k := 3 TO end - 3 DO s[k] := s[k + delta] END;
IF end > 2 THEN s[end - 2] := "."; s[end - 1] := "."; s[end] := "." END;
IF end >= -1 THEN s[end + 1] := 0X ELSE s[0] := 0X END;
i := f.CharIndex(0, w, s, font);
Log.String("delta="); Log.Int(delta); Log.String(" '" + s + "' "); Log.String(" len="); Log.Int(LEN(s$)); Log.String(" end="); Log.Int(end); Log.String(" i ="); Log.Int(i);Log.Ln;
END;
END;
sw := font.StringWidth(s)
ELSE sw := 0
END
END;
...
END DrawLabel;
PROCEDURE DrawField ...
same changes as DrawLabel
END DrawField;