diff --git a/.gitignore b/.gitignore index 753303f..32d8d72 100644 --- a/.gitignore +++ b/.gitignore @@ -75,3 +75,6 @@ modules/ **Debug/ **Release/ + +*.app +*.app.zip diff --git a/App/READCOM.App.Globals.dfm b/App/READCOM.App.Globals.dfm index 635e139..50bab03 100644 --- a/App/READCOM.App.Globals.dfm +++ b/App/READCOM.App.Globals.dfm @@ -28001,7 +28001,7 @@ object Globals: TGlobals item MultiResBitmap = < item - Size = 30 + Size = 136 end> IconName = 'Questionmark' SVGText = @@ -28675,6 +28675,67 @@ object Globals: TGlobals '567,2.7163-2.2783L44.21,21.3711A1.4519,1.4519,0,0,0,44.8818,19.7' + '754Z"/>'#10' '#10''#10 Opacity = 1.000000000000000000 + end + item + MultiResBitmap = < + item + Size = 136 + end> + IconName = 'Hourglass' + SVGText = + ''#10' '#10' '#10' '#10' '#10' ' + + ' '#10' '#10' '#10 + + ' '#10' '#10' '#10' '#10' '#10' '#10' '#10' '#10' '#10' '#10' '#10' '#10' '#10' '#10' '#10' '#10''#10 + Opacity = 1.000000000000000000 end> Destination = < item @@ -28809,8 +28870,8 @@ object Globals: TGlobals Layers = < item Name = 'Questionmark' - SourceRect.Right = 30.000000000000000000 - SourceRect.Bottom = 30.000000000000000000 + SourceRect.Right = 136.000000000000000000 + SourceRect.Bottom = 136.000000000000000000 end> end item @@ -28925,6 +28986,14 @@ object Globals: TGlobals SourceRect.Bottom = 136.000000000000000000 end> end + item + Layers = < + item + Name = 'Hourglass' + SourceRect.Right = 136.000000000000000000 + SourceRect.Bottom = 136.000000000000000000 + end> + end item Layers = <> end> diff --git a/App/READCOM.App.Globals.pas b/App/READCOM.App.Globals.pas index 513c40d..9f65242 100644 --- a/App/READCOM.App.Globals.pas +++ b/App/READCOM.App.Globals.pas @@ -6,12 +6,6 @@ interface System.SysUtils, System.Classes, FMX.Types, FMX.Controls, System.ImageList, FMX.ImgList, FMX.SVGIconImageList; -resourcestring - URL_HELP = 'https://github.com/Zoomicon/READCOM_App/wiki'; - URL_READCOM = 'https://www.read-com-eu.uma.es'; - STR_APP_TITLE = 'READ-COM: Reading Communities'; - STR_COMPATIBILITY_MODE = '[Compatibility mode]'; - type TGlobals = class(TDataModule) diff --git a/App/READCOM.App.Main.pas b/App/READCOM.App.Main.pas index 723859c..7093ae6 100644 --- a/App/READCOM.App.Main.pas +++ b/App/READCOM.App.Main.pas @@ -21,6 +21,7 @@ implementation READCOM.Views.Main, READCOM.App.Debugging, READCOM.App.Globals, //for TGlobals + READCOM.App.Messages, READCOM.App.URLs; //for OpenURLinBrowser procedure ParseCommandLine; diff --git a/App/READCOM.App.Messages.pas b/App/READCOM.App.Messages.pas new file mode 100644 index 0000000..cce18c4 --- /dev/null +++ b/App/READCOM.App.Messages.pas @@ -0,0 +1,14 @@ +unit READCOM.App.Messages; + +interface + +resourcestring + URL_HELP = 'https://github.com/Zoomicon/READCOM_App/wiki'; + URL_READCOM = 'https://www.read-com-eu.uma.es'; + STR_APP_TITLE = 'READ-COM: Reading Communities'; + STR_COMPATIBILITY_MODE = '[Compatibility mode]'; + ERR_DOWNLOAD = 'Download failed (%s)'; + +implementation + +end. diff --git a/App/READCOM_App.dpr b/App/READCOM_App.dpr index cf108fa..8ea8ce8 100644 --- a/App/READCOM_App.dpr +++ b/App/READCOM_App.dpr @@ -40,11 +40,13 @@ uses Zoomicon.Media.Models in '..\Zoomicon.Media\Zoomicon.Media.Models.pas', Zoomicon.Puzzler.Classes in '..\Zoomicon.Puzzler\Zoomicon.Puzzler.Classes.pas', Zoomicon.Puzzler.Models in '..\Zoomicon.Puzzler\Zoomicon.Puzzler.Models.pas', + Zoomicon.Text in '..\Zoomicon.Text\Zoomicon.Text.pas', READCOM.App.Globals in 'READCOM.App.Globals.pas' {Globals: TDataModule}, READCOM.App.Models in 'READCOM.App.Models.pas', READCOM.App.URLs in 'READCOM.App.URLs.pas', READCOM.Views.Options.StoryItemOptions in 'Views\Options\READCOM.Views.Options.StoryItemOptions.pas' {StoryItemOptions: TFrame}, READCOM.Views.Options.ImageStoryItemOptions in 'Views\Options\READCOM.Views.Options.ImageStoryItemOptions.pas' {ImageStoryItemOptions: TFrame}, + READCOM.Views.Options.TextStoryItemOptions in 'Views\Options\READCOM.Views.Options.TextStoryItemOptions.pas' {TextStoryItemOptions: TFrame}, READCOM.Views.StoryItem in 'Views\READCOM.Views.StoryItem.pas' {StoryItem: TFrame}, READCOM.Views.ImageStoryItem in 'Views\READCOM.Views.ImageStoryItem.pas' {ImageStoryItem: TFrame}, READCOM.Views.AudioStoryItem in 'Views\READCOM.Views.AudioStoryItem.pas' {AudioStoryItem: TFrame}, @@ -53,10 +55,10 @@ uses READCOM.Views.Menu.HUD in 'Views\READCOM.Views.Menu.HUD.pas' {StoryHUD: TFrame}, READCOM.Views.Main in 'Views\READCOM.Views.Main.pas' {MainForm}, READCOM.Views.About in 'Views\READCOM.Views.About.pas' {AboutFrame: TFrame}, + READCOM.Views.Wait in 'Views\READCOM.Views.Wait.pas' {WaitFrame: TFrame}, READCOM.App.Main in 'READCOM.App.Main.pas', READCOM.App.Debugging in 'READCOM.App.Debugging.pas', - Zoomicon.Text in '..\Zoomicon.Text\Zoomicon.Text.pas', - READCOM.Views.Options.TextStoryItemOptions in 'Views\Options\READCOM.Views.Options.TextStoryItemOptions.pas' {TextStoryItemOptions: TFrame}, + READCOM.App.Messages in 'READCOM.App.Messages.pas', FMX.Image32SVG in '..\3rdPartyLib\SVGIconImageList\Source\FMX.Image32SVG.pas', Img32.SVG.Core in '..\3rdPartyLib\SVGIconImageList\Image32\source\Img32.SVG.Core.pas'; diff --git a/App/READCOM_App.dproj b/App/READCOM_App.dproj index de93022..e6ae570 100644 --- a/App/READCOM_App.dproj +++ b/App/READCOM_App.dproj @@ -525,6 +525,7 @@ +
Globals
TDataModule @@ -539,6 +540,10 @@
ImageStoryItemOptions
TFrame
+ +
TextStoryItemOptions
+ TFrame +
StoryItem
TFrame @@ -567,14 +572,13 @@
AboutFrame
TFrame
- - - - -
TextStoryItemOptions
- fmx + +
WaitFrame
TFrame
+ + + diff --git a/App/Views/READCOM.Views.About.fmx b/App/Views/READCOM.Views.About.fmx index 6128892..6d462ba 100644 --- a/App/Views/READCOM.Views.About.fmx +++ b/App/Views/READCOM.Views.About.fmx @@ -1,162 +1,171 @@ object AboutFrame: TAboutFrame - Size.Width = 476.000000000000000000 - Size.Height = 396.000000000000000000 + Align = Contents + Size.Width = 508.000000000000000000 + Size.Height = 320.000000000000000000 Size.PlatformDefault = False object rectBackground: TRectangle Align = Contents - Size.Width = 476.000000000000000000 - Size.Height = 396.000000000000000000 + Fill.Color = xBBE0E0E0 + Size.Width = 508.000000000000000000 + Size.Height = 320.000000000000000000 Size.PlatformDefault = False - object GlyphLogo: TGlyph - OnTap = GlyphLogoTap - Align = Scale - Position.X = 9.333336830139160000 - Position.Y = 8.425530433654785000 - Size.Width = 127.166633605957000000 - Size.Height = 114.797874450683600000 + Stroke.Thickness = 0.000000000000000000 + object rectBorder: TRectangle + Align = Center + Size.Width = 508.000000000000000000 + Size.Height = 320.000000000000000000 Size.PlatformDefault = False - ImageIndex = 24 - Images = Globals.SVGIconImageList - end - object PanelTitleVersion: TPanel - Anchors = [akLeft, akTop, akRight] - Position.X = 125.000000000000000000 - Position.Y = 8.000000000000000000 - Size.Width = 343.000000000000000000 - Size.Height = 109.000000000000000000 - Size.PlatformDefault = False - TabOrder = 0 - object FlowLayout1: TFlowLayout - Align = Contents - Padding.Top = 20.000000000000000000 - Size.Width = 343.000000000000000000 + object MemoInfo: TMemo + Touch.InteractiveGestures = [Pan, LongTap, DoubleTap] + DataDetectorTypes = [] + Lines.Strings = ( + 'Author:' + 'George Birbilis / Zoomicon.com' + '' + 'READ-COM Project:' + 'https://www.read-com-eu.uma.es/' + '' + 'Source code and Wiki:' + 'https://github.com/zoomicon/READCOM_App' + '' + 'Stories and Assets Gallery:' + 'https://github.com/zoomicon/READCOM_Gallery' + '' + 'Icons:' + 'https://openmoji.org' + 'https://oNlineWebFonts.com') + ReadOnly = True + Anchors = [akLeft, akTop, akRight, akBottom] + Position.X = 8.000000000000000000 + Position.Y = 125.000000000000000000 + Size.Width = 492.000000000000000000 + Size.Height = 187.000000000000000000 + Size.PlatformDefault = False + TabOrder = 1 + Viewport.Width = 472.000000000000000000 + Viewport.Height = 183.000000000000000000 + end + object btnHelp: TSpeedButton + Action = actionHelp + Anchors = [akRight, akBottom] + Enabled = True + Images = Globals.SVGIconImageList + ImageIndex = 16 + Margins.Left = 3.000000000000000000 + Margins.Top = 3.000000000000000000 + Margins.Right = 3.000000000000000000 + Margins.Bottom = 3.000000000000000000 + Position.X = 440.000000000000000000 + Position.Y = 260.000000000000000000 + Size.Width = 45.000000000000000000 + Size.Height = 53.000000000000000000 + Size.PlatformDefault = False + StyleLookup = 'searchtoolbutton' + end + object GlyphLogo: TGlyph + OnTap = GlyphLogoTap + Align = Scale + Position.X = 9.960789680480957000 + Position.Y = 6.808507442474365000 + Size.Width = 135.715652465820300000 + Size.Height = 92.765899658203130000 + Size.PlatformDefault = False + ImageIndex = 24 + Images = Globals.SVGIconImageList + end + object PanelTitleVersion: TPanel + Anchors = [akLeft, akTop, akRight] + Position.X = 125.000000000000000000 + Position.Y = 8.000000000000000000 + Size.Width = 375.000000000000000000 Size.Height = 109.000000000000000000 Size.PlatformDefault = False - TabOrder = 2 - Justify = Center - JustifyLastLine = Center - FlowDirection = LeftToRight - object lblTitle: TLabel - Align = Horizontal - StyledSettings = [Family, Size, FontColor] - Position.X = 9.500000000000000000 - Position.Y = 20.000000000000000000 - Size.Width = 324.000000000000000000 - Size.Height = 16.000000000000000000 - Size.PlatformDefault = False - TextSettings.Font.StyleExt = {00070000000000000004000000} - TextSettings.HorzAlign = Center - Text = 'READ-COM: Reading Communities' - TabOrder = 1 - end - object FlowLayoutBreak1: TFlowLayoutBreak - ChangesRules = False - Justify = Left - JustifyLastLine = Left - FlowDirection = LeftToRight - end - object lblBlankRow: TLabel - Position.X = 111.500000000000000000 - Position.Y = 36.000000000000000000 - TabOrder = 3 - end - object FlowLayoutBreak2: TFlowLayoutBreak - ChangesRules = False - Justify = Left - JustifyLastLine = Left - FlowDirection = LeftToRight - end - object FlowLayout2: TFlowLayout - Align = Horizontal - Padding.Left = 20.000000000000000000 - Position.X = 6.500000000000000000 - Position.Y = 53.000000000000000000 - Size.Width = 330.000000000000000000 - Size.Height = 25.000000000000000000 + TabOrder = 0 + object TitleAndVersionLayout: TFlowLayout + Align = Contents + Padding.Top = 20.000000000000000000 + Size.Width = 375.000000000000000000 + Size.Height = 109.000000000000000000 Size.PlatformDefault = False TabOrder = 2 Justify = Center JustifyLastLine = Center FlowDirection = LeftToRight - object lblVersion: TLabel - Align = MostLeft - Position.X = 93.399993896484380000 - Size.Width = 87.200004577636720000 + object lblTitle: TLabel + Align = Horizontal + StyledSettings = [Family, Size, FontColor] + Position.X = 25.500000000000000000 + Position.Y = 20.000000000000000000 + Size.Width = 324.000000000000000000 Size.Height = 16.000000000000000000 Size.PlatformDefault = False - Text = 'Version:' + TextSettings.Font.StyleExt = {00070000000000000004000000} + TextSettings.HorzAlign = Center + Text = 'READ-COM: Reading Communities' + TabOrder = 1 + end + object NewLine1: TFlowLayoutBreak + ChangesRules = False + Justify = Left + JustifyLastLine = Left + FlowDirection = LeftToRight + end + object lblBlankRow: TLabel + Position.X = 127.500000000000000000 + Position.Y = 36.000000000000000000 TabOrder = 3 end - object lblVersionValue: TLabel - Align = MostLeft - Position.X = 180.600006103515600000 - Size.Width = 76.000000000000000000 - Size.Height = 16.000000000000000000 + object NewLine2: TFlowLayoutBreak + ChangesRules = False + Justify = Left + JustifyLastLine = Left + FlowDirection = LeftToRight + end + object VersionLayout: TFlowLayout + Align = Horizontal + Padding.Left = 20.000000000000000000 + Position.X = 22.500000000000000000 + Position.Y = 53.000000000000000000 + Size.Width = 330.000000000000000000 + Size.Height = 25.000000000000000000 Size.PlatformDefault = False - Text = '0.0.0' TabOrder = 2 + Justify = Center + JustifyLastLine = Center + FlowDirection = LeftToRight + object lblVersion: TLabel + Align = MostLeft + Position.X = 93.399993896484380000 + Size.Width = 87.200004577636720000 + Size.Height = 16.000000000000000000 + Size.PlatformDefault = False + Text = 'Version:' + TabOrder = 3 + end + object lblVersionValue: TLabel + Align = MostLeft + Position.X = 180.600006103515600000 + Size.Width = 76.000000000000000000 + Size.Height = 16.000000000000000000 + Size.PlatformDefault = False + Text = '0.0.0' + TabOrder = 2 + end end end + object btnClose: TSpeedButton + Position.X = -117.000000000000000000 + Position.Y = -1.000000000000000000 + Size.Width = 24.000000000000000000 + Size.Height = 24.000000000000000000 + Size.PlatformDefault = False + StyleLookup = 'stoptoolbutton' + Text = 'stoptoolbutton' + OnClick = btnCloseClick + end end - object btnClose: TSpeedButton - Anchors = [akTop, akRight] - Position.X = -125.000000000000000000 - Position.Y = -8.000000000000000000 - Size.Width = 24.000000000000000000 - Size.Height = 24.000000000000000000 - Size.PlatformDefault = False - StyleLookup = 'stoptoolbutton' - Text = 'stoptoolbutton' - OnClick = btnCloseClick - end - end - object MemoInfo: TMemo - Touch.InteractiveGestures = [Pan, LongTap, DoubleTap] - DataDetectorTypes = [] - Lines.Strings = ( - 'Author:' - 'George Birbilis / Zoomicon.com' - '' - 'READ-COM Project:' - 'https://www.read-com-eu.uma.es/' - '' - 'Source code and Wiki:' - 'https://github.com/zoomicon/READCOM_App' - '' - 'Stories and Assets Gallery:' - 'https://github.com/zoomicon/READCOM_Gallery' - '' - 'Icons:' - 'https://openmoji.org' - 'https://oNlineWebFonts.com') - ReadOnly = True - Anchors = [akLeft, akTop, akRight, akBottom] - Position.X = 8.000000000000000000 - Position.Y = 125.000000000000000000 - Size.Width = 460.000000000000000000 - Size.Height = 263.000000000000000000 - Size.PlatformDefault = False - TabOrder = 1 - Viewport.Width = 456.000000000000000000 - Viewport.Height = 259.000000000000000000 end end - object btnHelp: TSpeedButton - Action = actionHelp - Enabled = True - Images = Globals.SVGIconImageList - ImageIndex = 16 - Margins.Left = 3.000000000000000000 - Margins.Top = 3.000000000000000000 - Margins.Right = 3.000000000000000000 - Margins.Bottom = 3.000000000000000000 - Position.X = 424.000000000000000000 - Position.Y = 336.000000000000000000 - Size.Width = 45.000000000000000000 - Size.Height = 53.000000000000000000 - Size.PlatformDefault = False - StyleLookup = 'searchtoolbutton' - end object ActionList: TActionList Images = Globals.SVGIconImageList Left = 352 diff --git a/App/Views/READCOM.Views.About.pas b/App/Views/READCOM.Views.About.pas index ecb627e..7b072b6 100644 --- a/App/Views/READCOM.Views.About.pas +++ b/App/Views/READCOM.Views.About.pas @@ -1,3 +1,6 @@ +//Description: READ-COM About dialog +//Author: George Birbilis (http://zoomicon.com) + unit READCOM.Views.About; interface @@ -20,28 +23,33 @@ TAboutFrame = class(TFrame) rectBackground: TRectangle; btnClose: TSpeedButton; GlyphLogo: TGlyph; - FlowLayout1: TFlowLayout; - FlowLayout2: TFlowLayout; - FlowLayoutBreak1: TFlowLayoutBreak; + TitleAndVersionLayout: TFlowLayout; + VersionLayout: TFlowLayout; + NewLine1: TFlowLayoutBreak; lblBlankRow: TLabel; - FlowLayoutBreak2: TFlowLayoutBreak; + NewLine2: TFlowLayoutBreak; ActionList: TActionList; actionHelp: TAction; btnHelp: TSpeedButton; + rectBorder: TRectangle; procedure btnCloseClick(Sender: TObject); procedure GlyphLogoTap(Sender: TObject; const Point: TPointF); procedure actionHelpExecute(Sender: TObject); - private - {Private declarations} + + protected + class var + Frame: TFrame; public - {Public declarations} constructor Create(AOwner: TComponent); override; + class procedure ShowModal(const TheParent: TFmxObject; const VisibleFlag: Boolean = true); //TODO: abstract design into a reusable ModalFrame class (see TWaitFrame too) + end; implementation uses Zoomicon.Helpers.FMX.Forms.ApplicationHelper, //for AppVersion READCOM.App.Main, + READCOM.App.Messages, READCOM.App.URLs; //for OpenURLinBrowser {$R *.fmx} @@ -59,6 +67,23 @@ constructor TAboutFrame.Create(AOwner: TComponent); {$endregion} +class procedure TAboutFrame.ShowModal(const TheParent: TFmxObject; const VisibleFlag: Boolean = true); +begin + if not Assigned(Frame) then + begin + Frame := Create(Application); //use Application as the Owner since we reuse the same WaitFrame instance + //Frame.Align := TAlignLayout.Content; //already set at frame designer (could be a property [Content, Center, Scale etc.]) + end; + + with Frame do + begin + Parent := TheParent; + + //Visible := VisibleFlag; + if not VisibleFlag then FreeAndNil(Frame); //destroy instead of hiding to save memory + end; +end; + {$region 'Events'} procedure TAboutFrame.GlyphLogoTap(Sender: TObject; const Point: TPointF); //TODO: use some custom TGlyph descendent that surfaces MouseClick event and Cursor properties instead so that we can handle Click event too @@ -73,10 +98,9 @@ procedure TAboutFrame.actionHelpExecute(Sender: TObject); procedure TAboutFrame.btnCloseClick(Sender: TObject); begin - Parent := nil; - Visible := false; + TAboutFrame.ShowModal(Parent, false); end; {$endregion} -end. \ No newline at end of file +end. diff --git a/App/Views/READCOM.Views.Main.fmx b/App/Views/READCOM.Views.Main.fmx index e1aac59..0d7ca41 100644 --- a/App/Views/READCOM.Views.Main.fmx +++ b/App/Views/READCOM.Views.Main.fmx @@ -39,7 +39,14 @@ object MainForm: TMainForm inherited layoutButtons: TLayout Size.Width = 876.000000000000000000 Size.Height = 616.000000000000000000 - inherited layoutButtonsMain: TFlowLayout [0] + inherited layoutButtonsNavigation: TLayout + Position.Y = 564.000000000000000000 + Size.Width = 856.000000000000000000 + inherited btnNext: TSpeedButton + Position.X = 800.000000000000000000 + end + end + inherited layoutButtonsMain: TFlowLayout Size.Height = 564.000000000000000000 inherited btnToggleStructureVisible: TSpeedButton Hint = @@ -53,7 +60,7 @@ object MainForm: TMainForm 'e. Light and dark mode ones are available.' end end - inherited layoutButtonsEdit: TFlowLayout [1] + inherited layoutButtonsEdit: TFlowLayout Position.X = 816.000000000000000000 Size.Height = 564.000000000000000000 TabOrder = 174 @@ -107,20 +114,13 @@ object MainForm: TMainForm OnChange = HUDcomboBackColorChange end end - object StoryTimer: TTimer [2] + object StoryTimer: TTimer Enabled = False Interval = 100 OnTimer = StoryTimerTimer Left = 86 Top = 24 end - inherited layoutButtonsNavigation: TLayout [3] - Position.Y = 564.000000000000000000 - Size.Width = 856.000000000000000000 - inherited btnNext: TSpeedButton - Position.X = 800.000000000000000000 - end - end end inherited MultiView: TMultiView NavigationPaneOptions.CollapsedWidth = 0.000000000000000000 diff --git a/App/Views/READCOM.Views.Main.pas b/App/Views/READCOM.Views.Main.pas index 7903247..5d5e6a1 100644 --- a/App/Views/READCOM.Views.Main.pas +++ b/App/Views/READCOM.Views.Main.pas @@ -183,8 +183,10 @@ implementation READCOM.App.Main, //for StorySource READCOM.App.URLs, //for OpenURLinBrowser and DownloadFileWithFallbackCache READCOM.App.Debugging, //for ToggleObjectDebuggerVisibility + READCOM.App.Messages, READCOM.Views.ImageStoryItem, //for TBitmapImageStoryItem - READCOM.Views.TextStoryItem; //for TTextStoryItem + READCOM.Views.TextStoryItem, //for TTextStoryItem + READCOM.Views.Wait; //for TWaitFrame {$R *.fmx} @@ -1078,27 +1080,29 @@ function TMainForm.LoadFromFile(const Filepath: string): Boolean; function TMainForm.LoadFromUrl(const Url: String): Boolean; //TODO: should add LoadFromUrl and AddFromUrl to TStoryItem too begin - //var memStream := DownloadFileWithFallbackCache(Url); //TODO: this seems to bring empty file try - //result := LoadFromStream(memStream); //tell app to open the fetched memstream as new RootStoryItem, can create .readcom story files that serve as galleries that point to other readcom files via thumbnails - and can use that at the Default.readcom file too that gets loaded on 1st run //TODO: maybe make global RootStoryItem like ActiveStoryItem with change event and app can listen to that + TWaitFrame.ShowModal(MainForm); - var loaded := false; - Log('Before call to TURLStream'); - TURLStream.Create(Url, //TODO: try to fix the downloader (but do check on mobiles too) since this is Delphi 11.1, else make a version of the downloader that can use that to also have caching + TURLStream.Create(Url, procedure(AStream: TStream) begin Log('Started download'); - loaded := LoadFromStream(AStream); //probably it can start loading while the content is coming + LoadFromStream(AStream); //probably it can start loading while the content is coming Log('Finished download'); + TWaitFrame.ShowModal(MainForm, false); end, true, //ASynchronizeProvide: call the anonymous proc (AProvider parameter) in the context of the main thread //IMPORTANT (it not done various AV errors occur later: we shouldn't touch the UI from other than the main thread) true //free on completion - ).AsyncResult.AsyncWaitEvent.WaitFor; //TODO: check if this works properly on Android - Log('After call to TURLStream'); //TODO: this should be output after "Finished download" but seems to be output immediately after "Before call..." which means the TURLStream WaitFor doesn't work as expected - result := loaded; //TODO: due to WaitFor not working as expected, make sure the result of LoadFromUrl isn't used for now (will be false) + ); - finally - //FreeAndNil(memStream); + result := true; //assuming download will progress fine + except + on e: Exception do + begin + TWaitFrame.ShowModal(MainForm, false); + ShowMessageFmt(ERR_DOWNLOAD, [e.Message]); + result := false; //probably no network connection etc. + end; end; end; diff --git a/App/Views/READCOM.Views.Menu.HUD.pas b/App/Views/READCOM.Views.Menu.HUD.pas index 6099fac..8c99bad 100644 --- a/App/Views/READCOM.Views.Menu.HUD.pas +++ b/App/Views/READCOM.Views.Menu.HUD.pas @@ -120,7 +120,7 @@ TStoryHUD = class(TFrame) implementation uses - READCOM.App.URLs; //for url_Open_In_Browser + READCOM.App.URLs, READCOM.Views.Main; //for url_Open_In_Browser {$R *.fmx} @@ -247,14 +247,7 @@ procedure TStoryHUD.btnToggleUseStoryTimerClick(Sender: TObject); procedure TStoryHUD.actionAboutExecute(Sender: TObject); begin - if not Assigned(FAboutFrame) then - begin - FAboutFrame := TAboutFrame.Create(Self); - FAboutFrame.Align := TAlignLayout.Center; - end; - - FAboutFrame.Parent := Self; - FAboutFrame.Visible := true; + TAboutFrame.ShowModal(MainForm); //has [X] button to close itself end; {$endregion} diff --git a/App/Views/READCOM.Views.Wait.fmx b/App/Views/READCOM.Views.Wait.fmx new file mode 100644 index 0000000..87d6e48 --- /dev/null +++ b/App/Views/READCOM.Views.Wait.fmx @@ -0,0 +1,21 @@ +object WaitFrame: TWaitFrame + Align = Contents + Size.Width = 240.000000000000000000 + Size.Height = 216.000000000000000000 + Size.PlatformDefault = False + object rectBackground: TRectangle + Align = Contents + Fill.Color = xBBE0E0E0 + Size.Width = 240.000000000000000000 + Size.Height = 216.000000000000000000 + Size.PlatformDefault = False + object GlyphLogo: TGlyph + Align = Scale + Size.Width = 240.000000000000000000 + Size.Height = 216.000000000000000000 + Size.PlatformDefault = False + ImageIndex = 31 + Images = Globals.SVGIconImageList + end + end +end diff --git a/App/Views/READCOM.Views.Wait.pas b/App/Views/READCOM.Views.Wait.pas new file mode 100644 index 0000000..6776f84 --- /dev/null +++ b/App/Views/READCOM.Views.Wait.pas @@ -0,0 +1,64 @@ +//Description: READ-COM Wait dialog +//Author: George Birbilis (http://zoomicon.com) + +unit READCOM.Views.Wait; + +interface + +uses + READCOM.App.Globals, //for Globals.SVGIconImageList + System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, + FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, + FMX.Memo.Types, FMX.ScrollBox, FMX.Memo, FMX.Controls.Presentation, + FMX.Objects, FMX.SVGIconImage, FMX.ImgList, FMX.Layouts, + FMX.ActnList; + +type + TWaitFrame = class(TFrame) + rectBackground: TRectangle; + GlyphLogo: TGlyph; + + protected + class var + Frame: TFrame; + + public + constructor Create(AOwner: TComponent); override; + class procedure ShowModal(const TheParent: TFmxObject; const VisibleFlag: Boolean = true); //TODO: abstract design into a reusable ModalFrame class (see TAboutFrame too) + + end; + +implementation + uses + READCOM.App.Main; + +{$R *.fmx} + +{$region 'Initialization'} + +constructor TWaitFrame.Create(AOwner: TComponent); +begin + inherited; + GlyphLogo.Cursor := crHourGlass; +end; + +{$endregion} + +class procedure TWaitFrame.ShowModal(const TheParent: TFmxObject; const VisibleFlag: Boolean = true); +begin + if not Assigned(Frame) then + begin + Frame := Create(Application); //use Application as the Owner since we reuse the same WaitFrame instance + //Frame.Align := TAlignLayout.Content; //already set at frame designer (could be a property [Content, Center, Scale etc.]) + end; + + with Frame do + begin + Parent := TheParent; + + //Visible := VisibleFlag; + if not VisibleFlag then FreeAndNil(Frame); //destroy instead of hiding to save memory + end; +end; + +end. diff --git a/Zoomicon.Media/Zoomicon.Media.FMX.dpk b/Zoomicon.Media/Zoomicon.Media.FMX.dpk index f3f0d0b..57359a7 100644 --- a/Zoomicon.Media/Zoomicon.Media.FMX.dpk +++ b/Zoomicon.Media/Zoomicon.Media.FMX.dpk @@ -44,3 +44,4 @@ end. +