Alcinoe icon indicating copy to clipboard operation
Alcinoe copied to clipboard

Impressive TALDialog component

Open Elinulok32 opened this issue 8 months ago • 17 comments

I have been wondering when we'll ever see a more modern looking and advanced Dialog from Embarcadero. I taught of creating my own custom dialogs to match the modern look and feel of apps, and there you are at it again, creating another amazing, good-looking and highly customizable component. Your approach is wonderful, and I love it. This is great. The Delphi community is blessed to have you.

Elinulok32 avatar May 22 '25 06:05 Elinulok32

Thanks a lot, @Elinulok32!

I'm currently working on a dynamic list box component (ideal for building apps like Instagram), and I'm looking for testers to provide feedback:

👉 https://play.google.com/store/apps/details?id=io.magicfoundation.alcinoe.alfmxdynamiclistboxdemo

If you're unable to download it, I may need to add your email to the tester list manually. In that case, please send your email to: [email protected]

Zeus64 avatar May 22 '25 07:05 Zeus64

It's indeed impressive!

Spelt avatar May 22 '25 13:05 Spelt

The link is not valid ?

Spelt avatar May 22 '25 13:05 Spelt

@Spelt just send me your android email to [email protected], to make the link working for you i must add you in the tester list.

Zeus64 avatar May 22 '25 14:05 Zeus64

Hello @Zeus64 I would like to try, is that possible?

proyectoanamnesis avatar May 22 '25 14:05 proyectoanamnesis

Hello @Zeus64 I would like to try, is that possible?

off course, just send me your android email so i can add it to the tester list

Zeus64 avatar May 22 '25 14:05 Zeus64

Hello @Zeus64, I've seen ways to retrieve and customize controls added to the TALDialog using their respective get functions like GetRadioButton, GetCheckBox and GetEdit but can't figure out how to retrieve and customize the buttons added by the "AddButton" procedure. Are the buttons customizable?

Also, what's the best approach to achieving something like this:

TDialogService.MessageDialog('Are you sure you want to logout?' , TMsgDlgType.MtConfirmation,
  [TMsgDlgBtn.MbCancel, TMsgDlgBtn.MbYes], TMsgDlgBtn.MbYes, 0,
      procedure(const AResult: TModalResult) begin
          case AResult of
              mrOK, mrYES : begin
                  //Yes action ;
              end;
              mrCancel : begin 
                  //Cancel action
               end;
          end;
      end
  );

Elinulok32 avatar May 22 '25 20:05 Elinulok32

you are right, i forget to add a property to retrieve all buttons (GetButtons). I will add it asap ! in the meantime you can update the style of the dialog manager default button

for exemple in alfmxcontrolsDemo i do : TALStyleManager.Instance.ApplyDialogManagerStyle('Material.DialogManager', TALDialogManager.Instance, 18{AFontSize});

but you can create your own style instead of applying the default Material.DialogManager

you just need to update the file

Alcinoe\Source\CustomStyles\Alcinoe.FMX.CustomStyles.pas

and define here a new style. take in sample the procedure procedure ALApplyMaterialDialogManagerStyle(const ADialogManager: TALDialogManager; const ARatio: Single = 1); defined in Alcinoe.FMX.Styles.pas

regarding your MessageDialog, you can do like this :

TALDialog.Builder
    .SetMessageText('Are you sure you want to logout?')
    .addButton('Yes', mrYES )
    .addButton('Cancel', mrCancel)
    .SetOnActionCallback(
       procedure(Const ADialog: TALDialog; const AAction: Integer; var ACanClose: Boolean)
       begin
           ACanClose := true;
           case AAction of
              mrOK, mrYES : begin
                  //Yes action ;
              end;
              mrCancel : begin 
                  //Cancel action
               end;
          end;          
       end)
    .Show;

I propose you to add at least an icon it's much more beautifull with it :)

Zeus64 avatar May 22 '25 22:05 Zeus64

Thanks. Tried it and it worked perfectly.

you are right, i forget to add a property to retrieve all buttons (GetButtons). I will add it asap !

and also GetButton(const ATag: NativeInt): TALButton

Elinulok32 avatar May 22 '25 23:05 Elinulok32

Hello @Zeus64, I hope these questions finds you well. I Have 2 questions.

  1. How do you get the TALDialog to follow the theme set by the App and not the system. My app has 3 theme options. (a) System Default (b) Light Mode and (c) Dark Mode. If I set the app theme to Light or Dark, I want TALDialog to adjust itself accordingly regardless of the system theme.

  2. The code below crashes the app, I believe it's because I'm calling another TALDialog within the callback procedure of a TALDialog

    
    TALDialog.Builder
    .SetHeadlineText('Enter Security Code')
    .AddEdit('Security Code', 'Security Code', '', 1)
    .addButton('OK', 1)
    .addButton('Cancel', 2)
    .SetOnActionCallback(
         procedure(Const ADialog: TALDialog; const AAction: Integer; var ACanClose: Boolean)
         begin
             ACanClose := True;
             SetFocused(nil);
             if AAction = 1 then begin
                 Var LLoginEdit := ADialog.GetEdit(1);
                 if LLoginEdit.Text = '' then begin
                     ACanClose := False;
                     TALDialog.Builder
                     .setMessageText('Invalid Security Code')
                     .addButton('OK', 1)
                     .Show;
                 end;
             end;
       end)
    .Show;

What is the way to resolve this since I want to use only TALDialog throughout my app.

Elinulok32 avatar May 25 '25 17:05 Elinulok32

  1. How do you get the TALDialog to follow the theme set by the App and not the system. My app has 3 theme options. (a) System Default (b) Light Mode and (c) Dark Mode. If I set the app theme to Light or Dark, I want TALDialog to adjust itself accordingly regardless of the system theme.

To achieve this, you must configure:

TALStyleManager.Instance.DarkModeBehavior := AlwaysDark; // or AlwaysLight / FollowSystem

This setting ensures that dialogs follow the app's theme rather than the system’s theme. The choice is automatically persisted between app restarts.

You can see this behavior in action in the alfmxcontrols demo.

Additionally, make sure to apply the appropriate material style to the dialog manager at app startup:

TALStyleManager.Instance.ApplyDialogManagerStyle(
  'Material.DialogManager',
  TALDialogManager.Instance,
  18 {FontSize}
);

This ensures the dialogs use the Material style defined for your app.

2. The code below crashes the app, I believe it's because I'm calling another TALDialog within the callback procedure of a

TALDialog:    
    TALDialog.Builder
    .SetHeadlineText('Enter Security Code')
    .AddEdit('Security Code', 'Security Code', '', 1)
    .addButton('OK', 1)
    .addButton('Cancel', 2)
    .SetOnActionCallback(
         procedure(Const ADialog: TALDialog; const AAction: Integer; var ACanClose: Boolean)
         begin
             ACanClose := True;
             SetFocused(nil);
             if AAction = 1 then begin
                 Var LLoginEdit := ADialog.GetEdit(1);
                 if LLoginEdit.Text = '' then begin
                     ACanClose := False;
                     TALDialog.Builder
                     .setMessageText('Invalid Security Code')
                     .addButton('OK', 1)
                     .Show;
                 end;
             end;
       end)
    .Show;

showing a new dialog on top of an existing one is considered a UI anti-pattern.

Instead of displaying a new alert, apply an error style to the edit field and display a supporting message:

TALDialog:    
  TALDialog.Builder
    .SetHeadlineText('Enter Security Code')
    .AddEdit('Security Code', 'Security Code', '', 1)
    .AddButton('OK', 1)
    .AddButton('Cancel', 2)
    .SetOnActionCallback(
      procedure(const ADialog: TALDialog; const AAction: Integer; var ACanClose: Boolean)
      begin
        ACanClose := True;
        SetFocused(nil);
        if AAction = 1 then
        begin
          var LLoginEdit := ADialog.GetEdit(1);
          if LLoginEdit.Text = '' then
          begin
            ACanClose := False;
            TALStyleManager.Instance.ApplyEditStyle('Material.Edit.Hybrid.Error', LLoginEdit);
            LLoginEdit.SupportingText := 'Invalid Security Code';
          end;
        end;
      end)
    .Show;

This provides immediate, inline feedback to the user without interrupting the dialog flow or nesting alerts.

Zeus64 avatar May 25 '25 23:05 Zeus64

i added GetButton(const ATag: NativeInt): TALButton and GetButtons in the last commit. please update your repository

Zeus64 avatar May 26 '25 08:05 Zeus64

i added GetButton(const ATag: NativeInt): TALButton and GetButtons in the last commit. please update your repository

That's wonderful, Thanks so much.

Regarding the themes, before posting the question, I earlier on referred to the demo for assistance and tried
TALStyleManager.Instance.DarkModeBehavior := TALStyleManager.TDarkModeBehavior.AlwaysLight; for light mode and TALStyleManager.Instance.DarkModeBehavior := TALStyleManager.TDarkModeBehavior.AlwaysDark; for dark mode and also applied
TALStyleManager.Instance.ApplyDialogManagerStyle('Material.DialogManager', TALDialogManager.Instance, 18); but it didn't change as expected. It only changes when system theme changes.

Regarding the TALDialog, In the situation where you display a dialog with an Edit field (in Android) and request the user to enter a file name to be used in saving a file, and after the file is saved you want to show the user where (directory) the file has been saved to, with another dialog. The initial dialog with the edit field should not still be showing, when new information dialog shows up. I'm trying to avoid TDialogServices.ShowMessage('Your file has been saved to ' + TPath.GetSharedDocumentsPath + PathDelim + FileName + '.pdf'); and use TALDialog instead.

Elinulok32 avatar May 26 '25 09:05 Elinulok32

Regarding the TALDialog, In the situation where you display a dialog with an Edit field (in Android) and request the user to enter a file name to be used in saving a file, and after the file is saved you want to show the user where (directory) the file has been saved to, with another dialog. The initial dialog with the edit field should not still be showing, when new information dialog shows up. I'm trying to avoid TDialogServices.ShowMessage('Your file has been saved to ' + TPath.GetSharedDocumentsPath + PathDelim + FileName + '.pdf'); and use TALDialog instead.

so that ok, you can in the procedure(const ADialog: TALDialog; const AAction: Integer; var ACanClose: Boolean) show another dialog ? this must work ... else could you please provide me a demo showing the problem ?

Zeus64 avatar May 26 '25 09:05 Zeus64

MultiDeviceTest.zip

I noticed that the app theme change works well on Windows but not on Android. Haven't tested on iOS yet.

Elinulok32 avatar May 26 '25 10:05 Elinulok32

Hello @Zeus64, I hope you're doing well. Please any updates on the theme change issue pertaining to android? (works well on Windows and iOS). Also, any updates regarding the TALDialog scenario I gave? Were you able to run the demo I posted? I can tell you've been very busy. It's just a gentle reminder.

Elinulok32 avatar Jun 02 '25 00:06 Elinulok32

I found a solution to my subsequent Dialog situation. It may not be the right approach but works well without crashing the app. I displayed the subsequent dialog in a thread and allowed half a second interval before displaying it. Also, the app theme change works on all platforms. All along, I was testing on Android version 10 (Huawei Y9s), and that was where I had the issue. Testing it on Android 14 worked perfectly.

Elinulok32 avatar Jun 09 '25 15:06 Elinulok32