diff --git a/App/READCOM.App.Globals.dfm b/App/READCOM.App.Globals.dfm
index e485e81..635e139 100644
--- a/App/READCOM.App.Globals.dfm
+++ b/App/READCOM.App.Globals.dfm
@@ -27482,7 +27482,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'Edit'
SVGText =
@@ -27527,7 +27527,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'reverse'
SVGText =
@@ -27547,7 +27547,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'play'
SVGText =
@@ -27567,8 +27567,8 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Width = 87
- Height = 109
+ Width = 24
+ Height = 30
end>
IconName = 'Diagram'
SVGText =
@@ -27664,7 +27664,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'OpenFileFolder'
SVGText =
@@ -27700,7 +27700,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'Save'
SVGText =
@@ -27797,7 +27797,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'Plus'
SVGText =
@@ -27918,7 +27918,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'Home'
SVGText =
@@ -27976,7 +27976,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'Info'
SVGText =
@@ -28001,7 +28001,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'Questionmark'
SVGText =
@@ -28041,7 +28041,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'CopyAction'
SVGText =
@@ -28076,7 +28076,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'PasteAction'
SVGText =
@@ -28126,7 +28126,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'FlipHorizontally'
SVGText =
@@ -28162,7 +28162,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'FlipVertically'
SVGText =
@@ -28198,7 +28198,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'ThoughtEllipsis'
SVGText =
@@ -28226,7 +28226,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'Timer'
SVGText =
@@ -28258,7 +28258,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'FramedPicture'
SVGText =
@@ -28301,7 +28301,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'READ-COM square'
SVGText =
@@ -28394,7 +28394,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'Scissors'
SVGText =
@@ -28464,7 +28464,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'Sun'
SVGText =
@@ -28587,7 +28587,7 @@ object Globals: TGlobals
item
MultiResBitmap = <
item
- Size = 136
+ Size = 30
end>
IconName = 'Gear8Teeth'
SVGText =
@@ -28681,32 +28681,32 @@ object Globals: TGlobals
Layers = <
item
Name = 'Edit'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'reverse'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'play'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'Diagram'
- SourceRect.Right = 109.000000000000000000
- SourceRect.Bottom = 109.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
@@ -28729,16 +28729,16 @@ object Globals: TGlobals
Layers = <
item
Name = 'OpenFileFolder'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'Save'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
@@ -28761,8 +28761,8 @@ object Globals: TGlobals
Layers = <
item
Name = 'Plus'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
@@ -28785,8 +28785,8 @@ object Globals: TGlobals
Layers = <
item
Name = 'Home'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
@@ -28801,96 +28801,96 @@ object Globals: TGlobals
Layers = <
item
Name = 'Info'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'Questionmark'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'CopyAction'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'PasteAction'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'FlipHorizontally'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'FlipVertically'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'ThoughtEllipsis'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'Timer'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'FramedPicture'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'READ-COM square'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'Scissors'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
Layers = <
item
Name = 'Sun'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
@@ -28913,8 +28913,8 @@ object Globals: TGlobals
Layers = <
item
Name = 'Gear8Teeth'
- SourceRect.Right = 136.000000000000000000
- SourceRect.Bottom = 136.000000000000000000
+ SourceRect.Right = 30.000000000000000000
+ SourceRect.Bottom = 30.000000000000000000
end>
end
item
diff --git a/App/READCOM.App.Models.pas b/App/READCOM.App.Models.pas
index 8987357..cdfad23 100644
--- a/App/READCOM.App.Models.pas
+++ b/App/READCOM.App.Models.pas
@@ -154,6 +154,9 @@ interface
function IsBorderVisible: Boolean;
procedure SetBorderVisible(const Value: Boolean);
+ {Root}
+ function IsRoot: Boolean;
+
{Home}
function IsHome: Boolean; //note: a Home StoryItem doesn't have to be StoryPoint, could be just the startup instructions that are shown once and not when looping through the StoryPoints
procedure SetHome(const Value: Boolean);
diff --git a/App/READCOM_App.dproj b/App/READCOM_App.dproj
index ca14587..e76a444 100644
--- a/App/READCOM_App.dproj
+++ b/App/READCOM_App.dproj
@@ -4,8 +4,8 @@
19.4
FMX
True
- Release
- Android64
+ Debug
+ Win32
168979
Application
READCOM_App.dpr
@@ -449,6 +449,13 @@
+
+
+ TFrame
+
+
+
+
diff --git a/App/Views/READCOM.Views.Main.pas b/App/Views/READCOM.Views.Main.pas
index d17785e..5b1813f 100644
--- a/App/Views/READCOM.Views.Main.pas
+++ b/App/Views/READCOM.Views.Main.pas
@@ -167,7 +167,8 @@ TMainForm = class(TForm, IStory)
MainForm: TMainForm;
resourcestring
- MSG_CONFIRM_CLEAR_STORY = 'Clearing story: are you sure?';
+ MSG_CONFIRM_CLEAR_STORY = 'Clearing Story: are you sure?';
+ MSG_CONFIRM_DELETION = 'Deleting ActiveStoryItem: are you sure?';
implementation
uses
@@ -787,32 +788,39 @@ procedure TMainForm.DeleteActiveStoryItem; //Note: make sure any keyboard action
begin
if not Assigned(ActiveStoryItem) then exit;
- if (Assigned(RootStoryItem) and (ActiveStoryItem.View <> RootStoryItem.View)) then //Note: don't compare IStoryItem interfaces with "=", compare the TStoryItem components they correspond to (getting their "View")
- ActiveStoryItem.Delete //this makes ParentStoryItem active (which updates StructureView)
- else //note: confirmation is only done at "HUDactionCutExecute"
- NewRootStoryItem; //deleting the RootStoryItem via "NewRootStoryItem", but not via "HUD.actionNew.Execute" since that also tries "LoadDefaultDocument" first //RootStoryItem change updates StructureView
+ if ActiveStoryItem.IsRoot then
+ NewRootStoryItem //deleting the RootStoryItem via "NewRootStoryItem", but not via "HUD.actionNew.Execute" since that also tries "LoadDefaultDocument" first //RootStoryItem change updates StructureView //note: confirmation is only done at "HUDactionCutExecute"
+ else
+ ActiveStoryItem.Delete; //this makes ParentStoryItem active (which updates StructureView)
end;
procedure TMainForm.CutActiveStoryItem; //Note: make sure any keyboard actions call the action event handlers since only those do confirmation
begin
if not Assigned(ActiveStoryItem) then exit;
- if (Assigned(RootStoryItem) and (ActiveStoryItem.View <> RootStoryItem.View)) then
- ActiveStoryItem.Cut //this makes ParentStoryItem active (which updates StructureView)
- else //note: confirmation is only done at "HUDactionCutExecute"
+ if ActiveStoryItem.IsRoot then
begin
ActiveStoryItem.Copy; //needed to simulate "Cut"
- NewRootStoryItem; //deleting the RootStoryItem via "NewRootStoryItem", but not via "HUD.actionNew.Execute" since that also tries "LoadDefaultDocument" first //RootStoryItem change updates StructureView
- end;
+ NewRootStoryItem; //deleting the RootStoryItem via "NewRootStoryItem", but not via "HUD.actionNew.Execute" since that also tries "LoadDefaultDocument" first //RootStoryItem change updates StructureView //note: confirmation is only done at "HUDactionCutExecute"
+ end
+ else
+ ActiveStoryItem.Cut //this makes ParentStoryItem active (which updates StructureView)
end;
{$endregion}
procedure TMainForm.HUDactionDeleteExecute(Sender: TObject);
begin
- if not HUD.EditMode then exit; //only in Edit mode
+ if not (HUD.EditMode and Assigned(ActiveStoryItem)) then exit; //only in Edit mode (plus safety check for ActiveStoryItem)
- TApplication.Confirm(MSG_CONFIRM_CLEAR_STORY, //confirmation done only at the action level //Note: could also use Application.Confirm since Confirm is defined as a class function in ApplicationHelper (and those can be called on object instances of the respective class too)
+ var msg: String;
+ if ActiveStoryItem.IsRoot then
+ msg := MSG_CONFIRM_CLEAR_STORY
+ else
+ msg := MSG_CONFIRM_DELETION;
+
+ //Always confirming for destructive actions like deletion
+ TApplication.Confirm(msg, //confirmation done only at the action level //Note: could also use Application.Confirm since Confirm is defined as a class function in ApplicationHelper (and those can be called on object instances of the respective class too)
procedure(Confirmed: Boolean)
begin
if Confirmed then
@@ -823,15 +831,19 @@ procedure TMainForm.HUDactionDeleteExecute(Sender: TObject);
procedure TMainForm.HUDactionCutExecute(Sender: TObject);
begin
- if not HUD.EditMode then exit; //only in Edit mode
+ if not (HUD.EditMode and Assigned(ActiveStoryItem)) then exit; //only in Edit mode (plus safety check for ActiveStoryItem)
- TApplication.Confirm(MSG_CONFIRM_CLEAR_STORY, //confirmation done only at the action level //Note: could also use Application.Confirm since Confirm is defined as a class function in ApplicationHelper (and those can be called on object instances of the respective class too)
- procedure(Confirmed: Boolean)
- begin
- if Confirmed then
- CutActiveStoryItem;
- end
- );
+ //Not considering Cut a destructive action since one can Paste back. However when cutting the RootStoryItem, since it has no parent to be activated and a new RootStoryItem will be created, paste back means it will become a child of the new RootStoryItem, so asking for confirmation only when cutting the RootStoryItem
+ if ActiveStoryItem.IsRoot then
+ TApplication.Confirm(MSG_CONFIRM_CLEAR_STORY, //confirmation done only at the action level //Note: could also use Application.Confirm since Confirm is defined as a class function in ApplicationHelper (and those can be called on object instances of the respective class too)
+ procedure(Confirmed: Boolean)
+ begin
+ if Confirmed then
+ CutActiveStoryItem;
+ end
+ )
+ else
+ CutActiveStoryItem; //no confirmation for cutting non-Root StoryItems
end;
procedure TMainForm.HUDactionCopyExecute(Sender: TObject);
diff --git a/App/Views/READCOM.Views.StoryItem.pas b/App/Views/READCOM.Views.StoryItem.pas
index d9cd285..4ab61ab 100644
--- a/App/Views/READCOM.Views.StoryItem.pas
+++ b/App/Views/READCOM.Views.StoryItem.pas
@@ -122,10 +122,11 @@ TStoryItem = class(TCustomManipulator, IStoryItem, IClipboardEnabled, IStoreab
function IsActive: Boolean; virtual;
procedure SetActive(const Value: Boolean); virtual;
- {HomeStoryItem}
- class procedure SetHomeStoryItem(const Value: IStoryItem); static; //static means has no "Self" passed to it, required for "class property" accessors
+ {Root}
+ function IsRoot: Boolean;
{Home}
+ class procedure SetHomeStoryItem(const Value: IStoryItem); static; //static means has no "Self" passed to it, required for "class property" accessors
function IsHome: Boolean; virtual;
procedure SetHome(const Value: Boolean); virtual;
@@ -671,6 +672,11 @@ procedure TStoryItem.SetActive(const Value: Boolean);
PlayRandomAudioStoryItem; //TODO: maybe should play AudioStoryItems in the order they exist in their parent StoryItem (but would need to remember last one played in that case which may be problematic if they are reordered etc.)
end;
+function TStoryItem.IsRoot: Boolean;
+begin
+ result := not Assigned(ParentStoryItem);
+end;
+
procedure TStoryItem.ActivateParentStoryItem;
begin
var parentItem := ParentStoryItem;
@@ -1223,7 +1229,10 @@ procedure TStoryItem.MouseClick(Button: TMouseButton; Shift: TShiftState; X, Y:
var LActiveStoryItemParent := ActiveStoryItem.ParentStoryItem;
if not Assigned(LActiveStoryItemParent) then exit(false); //ActiveStoryItem is the RootStoryItem, so we can't be its Sibling
- result := (LActiveStoryItemParent.View = ParentStoryItem.View); //check if we have the same parent as the ActiveStoryItem //Note: we can't compare the IStoryPoint interfaces directly, must compare the TStoryPoint objects they wrap (the views)
+ var LParent := ParentStoryItem;
+ if not Assigned(LParent) then exit(false); //we're the RootStoryItem, so we can't have Siblings
+
+ result := (LActiveStoryItemParent.View = LParent.View); //check if we have the same parent as the ActiveStoryItem //Note: we can't compare the IStoryPoint interfaces directly, must compare the TStoryPoint objects they wrap (the views)
end;
begin
@@ -1244,8 +1253,8 @@ procedure TStoryItem.MouseClick(Button: TMouseButton; Shift: TShiftState; X, Y:
else
begin
- if ((ssCtrl in Shift) or (ssRight in Shift)) and //either Ctrl+LeftClick or just RightClick
- HasActiveChildStoryItem or HasActiveSiblingStoryItem then //and one of our children is the ActiveStoryItem...
+ if (((ssCtrl in Shift) or (ssRight in Shift)) and //either Ctrl+LeftClick or just RightClick
+ (HasActiveChildStoryItem or HasActiveSiblingStoryItem)) then //and (one of our children is the ActiveStoryItem or we're its Sibling)...
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)
else
begin