Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Centralize Left Content Margin calculation #369

Closed
vincentparrett opened this issue Jan 21, 2015 · 3 comments
Closed

Centralize Left Content Margin calculation #369

vincentparrett opened this issue Jan 21, 2015 · 3 comments
Assignees
Milestone

Comments

@vincentparrett
Copy link
Contributor

From Arioch...@gmail.com on September 06, 2013 20:51:14

Part of https://groups.google.com/forum/?hl=ru#!topic/virtual-treeview/84WAMRb299E Related: https://code.google.com/p/virtual-treeview/issues/detail?id=368 VTV Nodes contain a lot of control-managed content, such as margins, cell margins, tree lines, [+] buttons, checkmarks, custom images and whatever

The code to calculate that, with regard to all the possible states and settings of the node, is copy-pasted all around the sources - just grep for "FCheckImages.Width" and see.

Worse, that calculation is almost not reachable from outside, so to proper implement OnMeasureXXXX events app-developer would have to copy-paste internals of VTV yet again.

When new versions of VTV would change hard-coded constants or number of possible elements or introduce some (like StringTree introduces Cell Margins) - all that copies would have to be found and changed accordingly one after another.

Note: app-developer can call GetDisplayRect(Node, -1, true, false, true).Left but that function is heavy per se, calculates much more than the only needed Left margin, if called from OnMeasureTextXXXX events lead to stack overflow.

Proposal: eliminate all those internal copies and instead introduce something like this drafting:

Type VTInternalNodeLeftElements = (niControlMargin, niNodeIndent, niTreeLine, niTreeExpandButton,
niCheckBox, niVSTCellMargin, ...)
VTInternalNodeLeftElementsOffsets = array[ VTInternalNodeLeftElements ] of integer;
PVTInternalNodeLeftElementsOffsets = ^VTInternalNodeLeftElementsOffsets;

public
function GetNodeTextMargin(Node, Column): integer; // or property?
protected
function PositionNodeInternalElements(Node, Column, Flags {like in .GetDisplayRect},
var Offsets: VTInternalNodeLeftElementsOffsets): integer;

function TVirtualBaseTree.GetNodeTextMargin(Node, Column): integer; // or property?
begin
Result := PositionNodeInternalElements(Node, Column,
[TextOnly, ApplyCellContentMargin, non-Unclipped],
PVTInternalNodeLeftElementsOffsets(nil)^ );
end;

function TVirtualBaseTree.PositionNodeInternalElements(Node, Column, Flags {like in .GetDisplayRect},
var Offsets: VTInternalNodeLeftElementsOffsets): integer;
var POffs: PInteger; NOffs: VTInternalNodeLeftElements;
procedure StoreOffset(const offs: integer);
begin
{$IfOpt D+}
Assert(NOffs > High(VTInternalNodeLeftElements),
'error: internal consistency failure, probably wrong refactory or updating');
Inc(NOffs);
{$EndIf}
if nil = POffs then exit;
POffs^ := offs;
Inc(POffs);
end;
begin
Result := -1;
if (nil = Node) or (FRoot = Node) then exit; // or assert ?

if nil = @offsets
then POffs := nil
else POffs := @offsets[Low(Offsets)];
{$IfOpt D+}
NOffs := Low(NOffs);
{$EndIf}

Result := -1;
if nil <> POffs then FillChar(POffs^, SizeOf(Offsets), -1);
if (nil = Node) or (FRoot = Node) then exit; // or assert ?

if not IsEffectivelyVisible[Node] then
Exit;

MainColumnHit := (Column = FHeader.MainColumn) or (Column = NoColumn);

if not (vsInitialized in Node.States) then
InitNode(Node);

if Column > NoColumn
then FHeader.FColumns.GetColumnBounds(Column, Result, dummy)
else Result := 0;
Inc(Result, FMargin);
StoreOffset(Result); // base indent

if MainColumnHit then begin
Inc(Result, FIndent * GetNodeIndent(Node));
if toShowRoot in FOptions.FPaintOptions then
Inc(Result, FIndent);
end;
StoreOffset(Result);

if MainColumnHit then
begin
if (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages) and (Node.CheckType <> ctNone) then
Inc(Result, FCheckImages.Width + 2);
end;
StoreOffset(Result);

if Assigned(FStateImages) and HasImage(Node, ikState, Column) then
Inc(Result, FStateImages.Width + 2);
StoreOffset(Result);

if Assigned(FImages) and HasImage(Node, ikNormal, Column) then
Inc(Result, GetNodeImageSize(Node).cx + 2);
StoreOffset(Result);

if ApplyCellContentMargin in Flags then
.... cpmGetContentMargin ?
end;

TODO: think about right-to-left and BiDi mode

End result should be that all drawing procedures get the coordinates via this unified function, siongle responsibility body(DRY Principle).

Original issue: http://code.google.com/p/virtual-treeview/issues/detail?id=369

@vincentparrett
Copy link
Contributor Author

From joachim....@gmail.com on September 09, 2013 11:53:55

Labels: -Type-Defect Type-Enhancement

@vincentparrett
Copy link
Contributor Author

From joachim....@gmail.com on December 10, 2013 11:43:46

Labels: -Priority-Medium Priority-High

@joachimmarder joachimmarder added this to the V7.0 milestone May 10, 2017
@joachimmarder joachimmarder self-assigned this Nov 12, 2017
@joachimmarder joachimmarder changed the title Enhancement: centralize Left Content Margin calculation Centralize Left Content Margin calculation Nov 12, 2017
joachimmarder pushed a commit that referenced this issue Nov 12, 2017
…into new member FImagesMargin

* ChangeScale() now also scales FImagesMargin, FMargin and FTextMargin
* Further work on issue #369: Centralize Left Content Margin calculation
@joachimmarder
Copy link
Contributor

joachimmarder commented Jan 25, 2018

TVTElement enum has been introduced as well as methods GetOffset()and GetOffsets(). Next step: Use these method instead of copied calculation code.

joachimmarder pushed a commit that referenced this issue Jan 25, 2018
* Improved TBaseVirtualTree.GetOffsets() 
* Now using GetOffsets() in TBaseVirtualTree.CollectSelectedNodesLTR()
joachimmarder pushed a commit that referenced this issue Mar 7, 2018
* TBaseVirtualTree.GetMaxColumnWidth() now uses GetOffsets() instead of doing own calculation.
* TBaseVirtualTree.GetOffsets() now respects the flag toFixedIndent
joachimmarder pushed a commit that referenced this issue Mar 7, 2018
* TBaseVirtualTree.GetMaxRightExtend() now uses GetOffsets() instead of doing own calculation.
* TBaseVirtualTree.GetOffsets() now supports TVTElement.ofsRightOfText which incldues the label text.
joachimmarder pushed a commit that referenced this issue Mar 7, 2018
joachimmarder pushed a commit that referenced this issue Mar 14, 2018
joachimmarder pushed a commit that referenced this issue Mar 17, 2018
* TBaseVirtualTree.GetDisplayRect() now uses GetOffset() instead of doing own calculation.
joachimmarder pushed a commit that referenced this issue Mar 17, 2018
* TBaseVirtualTree.DetermineHitPositionLTR() now uses GetOffsets()
joachimmarder pushed a commit that referenced this issue Mar 17, 2018
* Fixed compiler warnings
* CollectSelectedNodesLTR() no longer stores all offset, but only the one of TVTElement.ofsLabel
joachimmarder pushed a commit that referenced this issue Mar 17, 2018
* TVTPaintInfo now includes TVTOffsets
* X-postion of toggle button is now calculated using TVTPaintInfo.Offsets. This fixes #520 (Plus/Minus buttons - hot painting not correct)
joachimmarder pushed a commit that referenced this issue Mar 17, 2018
* In AdjustImageBorder() we no longer decrease the X-positoon of the image by 1. In times of high-dpi monitors it amkes no sense to ahve offsets, margins or paddings of 1 pixels, and if so, these values should be scaled.
* We now draw the tree lines close to the checkboxes / images.
joachimmarder pushed a commit that referenced this issue Mar 18, 2018
* TBaseVirtualTree.AdjustImageBorder() must use FImagesMargin instead of hardcoded "2". 
* Minor paint optimization
joachimmarder pushed a commit that referenced this issue Mar 18, 2018
* Renamed ofsControlMargin to ofsMargin, which fits better
* Now uing PaintInfo.Offsets[ofsMargin] instead of FMargin in PaintTreeLines()
joachimmarder pushed a commit that referenced this issue Mar 18, 2018
TBaseVirtualTree.GetOffsets() now has an optional parameter for the column index. We now use this in DetermineHitPositionLTR() and PaintTree() to avoid duplicate calculations. This is work in progress for PaintTree()
joachimmarder pushed a commit that referenced this issue Jun 2, 2018
joachimmarder pushed a commit that referenced this issue Jun 2, 2018
…ffsets() not only for the main column, but for all columns.
joachimmarder pushed a commit that referenced this issue Jun 3, 2018
…CheckBox inclusing fImagesMargin in order to be compatible with PaintTree()

* Removed no longer used variable from GetDisplayRect()
joachimmarder pushed a commit that referenced this issue Jun 3, 2018
…Tree.AdjustImageBorder() to TVTPaintInfo.AdjustImageCoordinates() where we now use TVTOffsets.
joachimmarder pushed a commit that referenced this issue Jun 3, 2018
…aseVirtualTree.AdjustImageBorder() to TVTPaintInfo.AdjustImageCoordinates() and removed now empty AdjustImageBorder().
joachimmarder pushed a commit that referenced this issue Jun 3, 2018
* Moved initial assingment of TVTPaintInfo.ContentRect entirely to TVTPaintInfo.AdjustImageCoordinates()
* Removed unused variable from TVTPaintInfo.AdjustImageCoordinates()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants