You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Implemented Snapping logic, Allowing to ctrl/right click parent storyitem (its empty area) to make it active, Fixed GetBackIndex of StoryItem to not count Border when it's not visible (items where getting hidden), fixed GetBackIndex to not count invisible items
//Global IStory (context) //TODO: talk to that so that we could tell it to open hyperlinks (e.g. http:/...) but also special hyperlinks like story:next, story:previous etc. that can invoke methods to navigate in the story (actually could pass the "verb" to the story itself via special method and it would know how to handle the hyperlinks and the special ones [not have any download and url opening code in the StoryItem])
50
+
//Global IStory (context) //TODO: talk to that so that we could tell it to open hyperlinks (e.g. http://...) but also special hyperlinks like story:next, story:previous etc. that can invoke methods to navigate in the story (actually could pass the "verb" to the story itself via special method and it would know how to handle the hyperlinks and the special ones [not have any download and url opening code in the StoryItem])
//don't apply snapping at this point, it is supposed to be applied when user drags and drops an unanchored StoryItem into the area of a snapping StoryItem which are both children of the ActiveStoryItem. So we need to know what was dropped to check if there's a snapping sibling's area containing the drop point (comparing in absolute coordinates)
992
994
end;
993
995
996
+
procedureTStoryItem.DoSnapping;
997
+
begin
998
+
var LParent := ParentStoryItem;
999
+
ifnot Assigned(LParent) then exit;
1000
+
1001
+
try
1002
+
Enabled := false; //disable temporarily
1003
+
//Check if our CenterPoint lies inside the bounds of a sibling that has Snapping on
1004
+
var LObj := LParent.View.ObjectAtLocalPoint(BoundsRect.CenterPoint, false, false, false, false); //only checking the immediate children (ignoring SubComponents) of our ParentStoryPoint, not checking the disabled ones since we make ourself temporarily disabled to exclude us
1005
+
if Assigned(LObj) and (LObj.GetObject is TStoryItem) then
1006
+
begin
1007
+
var LStoryItemUnderneath := TStoryItem(LObj.GetObject);
1008
+
if LStoryItemUnderneath.Snapping then
1009
+
Position.Point := LStoryItemUnderneath.BoundsRect.CenterPoint - PointF(Width/2, Height/2); //use same center as the Snapping sibling //Note: should be must faster than BoundsRect := BoundsRect.CenterAt(LStoryItemUnderneath.BoundsRect), at least in Delphi 11.1, where CenterAt calls RectCenter which doesn't seem to be optimized (does 3 OffsetRect operations)
1010
+
end;
1011
+
finally
1012
+
Enabled := true; //make sure we always enable again
if (ssCtrl in Shift) or (ssRight in Shift) then//either Ctrl+LeftClick or just RightClick
1134
1156
begin
1135
-
var LObj := ObjectAtLocalPoint(PointF(X, Y) + AreaSelector.Position.Point, false, true, false, false); //only checking the immediate children (ignoring SubComponents) //TODO: this won't work if we reuse an AreaSelector that belongs to other parent
1157
+
var LPoint := PointF(X, Y) + AreaSelector.Position.Point;
1158
+
var LObj := ObjectAtLocalPoint(LPoint, false, true, false, false); //only checking the immediate children (ignoring SubComponents) //TODO: this won't work if we reuse an AreaSelector that belongs to other parent
1136
1159
if Assigned(LObj) and (LObj.GetObject is TStoryItem) then
1137
1160
TStoryItem(LObj.GetObject).Active := true; //make the ActiveStoryItem
1138
1161
end;
1139
-
end;
1162
+
end;//TODO: should also do the extra logic from TStoryPoint.MouseDown that can make the parent storyitem active (maybe make reusable methods)
result := (StoryItems.GetFirst( //Note: don't use Contains(ActiveStoryItem), can't compare interfaces for equality (they may both point to same object but be different instances)
1212
+
function(StoryItem: IStoryItem):Boolean
1213
+
begin
1214
+
result := StoryItem.Active;
1215
+
end
1216
+
) <> nil);
1217
+
end;
1218
+
1183
1219
begin
1184
1220
Shift := FMouseShift; //TODO: remove if Delphi fixes related bug (more at FMouseShift definition)
1185
1221
1186
1222
inherited; //fire event handlers
1187
1223
1188
-
ifnot EditMode then
1224
+
if EditMode then//don't use check (Story.StoryMode = TStoryMode.EditMode) aka Global EditMode, in that case would have issue working at a given nesting level (grandchidlren would get in our way, getting activated by accident)
1225
+
begin
1226
+
if (ssCtrl in Shift) or (ssRight in Shift) then//either Ctrl+LeftClick or just RightClick
1227
+
begin
1228
+
var LObj := ObjectAtLocalPoint(PointF(X, Y), false, true, false, false); //only checking the immediate children (ignoring SubComponents)
1229
+
if Assigned(LObj) and (LObj.GetObject is TStoryItem) then
1230
+
TStoryItem(LObj.GetObject).Active := true //make the child under mouse cursor the ActiveStoryItem
1231
+
end;
1232
+
end
1233
+
1234
+
else
1235
+
1236
+
begin
1237
+
if ((ssCtrl in Shift) or (ssRight in Shift)) and//either Ctrl+LeftClick or just RightClick
1238
+
HasActiveChildStoryItem then//and one of our children is the ActiveStoryItem...
1239
+
Active := true //...make us (the parent of the ActiveStoryItem) the Active one (so that we can go back to the parent level by right-clicking it without using the keyboard's ESC key)
1240
+
else
1189
1241
begin
1190
1242
var LParent := ParentStoryItem;
1191
1243
if ((FUrlAction <> '') {and //TODO: should have URLs clickable only for children of ActiveStoryItem (and for itself if it's the RootStoryItem maybe) //in non-EditMode should disable HitTest though at everything that isn't the current StoryItem or direct child of the ActiveStoryItem apart from the TextStoryItems maybe (could maybe just disble HitTest at all siblings of ActiveStoryItem and have everything under ActiveStoryItem HitTest-enabled)
1192
1244
((Assigned(LParent) and LParent.Active) or
1193
1245
((not Assigned(LParent)) and Active))}) then//only when ParentStoryItem is the ActiveStoryItem //assuming short-circuit evaluation //if no LParent then it's the RootStoryItem, allowing it to have URLAction too
1194
1246
FStory.OpenUrl(FUrlAction);
1195
-
end
1196
-
1197
-
else//EditMode //TODO: if the StoryItem is not in EditMode but the Story is in EditMode, then make the StoryItem active (else do like below)
1198
-
1199
-
if (ssCtrl in Shift) or (ssRight in Shift) then//either Ctrl+LeftClick or just RightClick
1200
-
begin
1201
-
var LObj := ObjectAtLocalPoint(PointF(X, Y), false, true, false, false); //only checking the immediate children (ignoring SubComponents)
1202
-
if Assigned(LObj) and (LObj.GetObject is TStoryItem) then
1203
-
TStoryItem(LObj.GetObject).Active := true; //make the ActiveStoryItem
0 commit comments