Search code examples
inno-setuppascalscript

Inno Setup - Conditionally hide/show static text based on task selection


[Components]
Name: "Slasher"; Description: "Dagon Slasher"; Types: Slasher Full
Name: "Frankenstein"; Description: "Dagon Frankenstein"; Types: Frankenstein Full

[Types]
Name: "Full"; Description: "Dagon Video Tools"
Name: "Slasher"; Description: "Dagon Slasher"
Name: "Frankenstein"; Description: "Dagon FrankenStein"

[Tasks]
Name: "Debug"; Description: "Nothing"; Components: not Slasher
Name: "Vid"; Description: "Install Extra Codecs for Frankenstein"; Flags: unchecked; Components: not Slasher

[Code]
var
  Warning: TNewStaticText;

procedure InitializeWizard;
begin
  Warning := TNewStaticText.Create(WizardForm);
  Warning.Parent := WizardForm.SelectTasksPage;
  Warning.Visible := False;
  Warning.AutoSize := False;
  Warning.SetBounds(
    WizardForm.TasksList.Left,
    WizardForm.TasksList.Top + WizardForm.TasksList.Height,
    WizardForm.TasksList.Width,
    50
  );
  Warning.Font.Color := clRed;
  Warning.Caption := 'Warning: This will result in a non-functional "Join in FrankenStein" button in the Tools Menu.';
end;

I used yet another amazing piece of code by TLama. The problem is I need the note to be visible when the user selects the task, and be hidden otherwise (while on the same page).


Solution

  • You have to handle WizardForm.TasksList.OnClickCheck event and update the Warning label visibility accordingly.

    var
      Warning: TNewStaticText;
    
    procedure TasksListClickCheck(Sender: TObject);
    begin
      Warning.Visible :=
        { This (and the task index below)  has to be kept in sync with the expression }
        { in "Components" parameter of the respective task. }
        { Though note that in your specific case the test }
        { is redundant as when "Slasher" is selected, you have no tasks, }
        { and the "Tasks" page is completely skipped, so you do not even get here. }
        (not IsComponentSelected('Slasher')) and
        WizardForm.TasksList.Checked[0]; { You can also use WizardIsTaskSelected }
    end;
    
    procedure InitializeWizard;
    begin
      Warning := TNewStaticText.Create(WizardForm);
      ...
      { Update Warning label visibility on task selection change }
      WizardForm.TasksList.OnClickCheck := @TasksListClickCheck
    end;
    
    procedure CurPageChanged(CurPageID: Integer);
    begin
      if CurPageID = wpSelectTasks then
      begin
        { Update initial visibility }
        TasksListClickCheck(WizardForm.TasksList);
      end;
    end;
    

    Task selected

    Task unselected


    Side notes:

    • Do not hard code the height to fixed 50. Scale it with DPI instead: ScaleY(50).
    • You should set Warning.WordWrap := True as the caption does not fit page width.
    • You should shrink TasksList's height as the label does not fit below the list. You are missing the WizardForm.TasksList.Height := WizardForm.TasksList.Height - NoteHeight; from @TLama's code. Again note that he is missing the scaling of the NoteHeight.
    const
      NoteHeight = 50;
    
    procedure InitializeWizard;
    begin
      WizardForm.TasksList.Height := WizardForm.TasksList.Height - ScaleY(NoteHeight);
    
      Warning := TNewStaticText.Create(WizardForm);
      Warning.Parent := WizardForm.SelectTasksPage;
      Warning.AutoSize := False;
      Warning.WordWrap := True;
      Warning.SetBounds(
        WizardForm.TasksList.Left,
        WizardForm.TasksList.Top + WizardForm.TasksList.Height,
        WizardForm.TasksList.Width,
        ScaleY(NoteHeight)
      );
      Warning.Font.Color := clRed;
      { Update Warning label visibility on task selection change }
      WizardForm.TasksList.OnClickCheck := @TasksListClickCheck
      Warning.Caption :=
        'Warning: This will result in a non-functional "Join in FrankenStein" button ' +
        'in the Tools Menu.';
    end;