Generated reference › API — ICoreBlocks/ICoreStudio/StudioObjects/Panels/ICoreUpdater
kind: generated#api#icoreblocks-icorestudio-studioobjects-panels-icoreupdater

API — ICoreBlocks/ICoreStudio/StudioObjects/Panels/ICoreUpdater

The public contract of 2 header(s) under src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/ICoreUpdater — 2 class/struct definition(s), 36 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.

HeaderDefinesDeclarationsBases
ICoreUpdateBanner.hICoreUpdateBanner16public ICoreWidget
ICoreUpdateDialog.hICoreUpdateDialog20public ICoreDialog

ICoreUpdateBanner.h#

src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/ICoreUpdater/ICoreUpdateBanner.h

ICoreUpdateBanner#

ICoreUpdateBanner.h:54 · class · final · bases public ICoreWidget · pImpl · 16 declaration(s)

ICoreUpdateBanner — the strip that says a build is waiting, and the very different strip that says the one you are running was pulled.

class ICoreUpdateBanner final : public ICoreWidget {
public:
    explicit ICoreUpdateBanner(ICoreWidget* parent = nullptr);
    ~ICoreUpdateBanner() override;

    // ICoreBannerStrip::HEIGHT, so a host can reserve the space without
    // instantiating one, and so the two banners cannot drift apart.
    static const int BANNER_HEIGHT;

    // Follow ICoreUpdateService::instance() for the rest of this object's life:
    // its `decided` signal, and its lastDecision() for the check that already
    // ran before this banner existed. Called once by the host.
    void followUpdateService();

    // Render one decision. What followUpdateService() calls, and what a suite
    // drives directly.
    void showDecision(const ICoreUpdateChecker::Decision& decision);

    // The running build is below `releases.min_supported_version` — a protocol
    // break rather than a withdrawal, and a DISTINCT sentence from a yank
    // because "this version was pulled" and "this version is no longer
    // supported" send a user to different places.
    //
    // ⚠ DRIVEN SINCE 2026-08-21 (U8.1). showDecision() routes
    // Outcome::RunningUnsupported here rather than repeating the sentence, so a
    // caller with a Decision does not have to know this function exists. It
    // stays public because the floor can also be reported by a caller that has
    // the two versions and no Decision.
    //
    // ⚠ The banner is the WHOLE enforcement. Being below the floor does not
    // stop the application: U8.1's answer was to build the control and leave it
    // off, and refusing to run on a server's say-so is a separate question with
    // a much worse failure mode.
    //
    // ⚠ ONLY FOR A BUILD THAT CANNOT UPDATE FROM HERE (2026-09-28). Below the
    // floor with a release this machine can take is an UpdateAvailable with
    // `supportedFloor` set, and showDecision() words that one itself: equally
    // loud, but it names the build that is ready to install.
    void showUnsupported(const std::string& runningVersion,
                         const std::string& minSupportedVersion);

    // An automatic install has already landed and the new build is what opens
    // next time. ⚠ A NOTICE, NOT A DANGER: nothing is wrong and nothing is
    // required -- the user is being told what happened, and can dismiss it.
    //
    // ⚠ ONLY EVER REACHED FROM AN AUTOMATIC RUN. followUpdateService() checks
    // ICoreUpdateService::isInstallingAutomatically() before calling it, so a
    // user who has turned automatic updating off sees the strips this class
    // showed before this function existed and no others. That is a deliberate
    // constraint rather than an accident of wiring: "nothing changes when it is
    // off" has to include what the banner says.
    void showInstalled(const std::string& version);

    // Back to silence.
    void clear();

    // ---- what it currently says, for a suite with no screen ---------------

    [[nodiscard]] ICoreString message() const;

    // True for the withdrawn/unsupported kind: the loud, undismissable one.
    [[nodiscard]] bool isUrgent() const;

    // Which outcomes put anything on screen at all. A host can ask before it
    // makes room, and a case can assert it without a screen.
    [[nodiscard]] static bool isBannerOutcome(ICoreUpdateChecker::Outcome outcome);

    // Available only, and only until the next decision.
    void dismissForThisSession();
    [[nodiscard]] bool isDismissed() const;

    // "Details…" was pressed. The host opens ICoreUpdateDialog; the banner
    // deliberately does not know how to, and owns no part of the download.
    ICoreSignal<> onDetailsRequested;

    // The strip showed or hid itself. It floats under the top panel in a stack
    // with the licence banner (owner, 2026-09-28), and the host re-stacks on
    // this -- ICoreStudioSurface::relayoutStripsUnderTopPanel().
    ICoreSignal<> onVisibilityChanged;

protected:
    void paintContent(ICorePainter& painter) override;

    // ⚠ IT FLOATS OVER THE CANVAS (2026-09-28, like the licence banner), so a
    // gesture on its bare ground is swallowed: a declined press or wheel walks
    // on and pans, zooms or deselects the diagram underneath. Its buttons are
    // children and are offered the gesture first.
    bool mousePressed(const ICoreMouseEvent& event) override;
    bool mouseReleased(const ICoreMouseEvent& event) override;
    bool mouseDoubleClicked(const ICoreMouseEvent& event) override;
    bool wheelScrolled(const ICoreWheelEvent& event) override;

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};

ICoreUpdateDialog.h#

src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/ICoreUpdater/ICoreUpdateDialog.h

ICoreUpdateDialog#

ICoreUpdateDialog.h:70 · class · final · bases public ICoreDialog · pImpl · 20 declaration(s)

ICoreUpdateDialog — what the user is shown about a new build.

class ICoreUpdateDialog final : public ICoreDialog {
public:
    explicit ICoreUpdateDialog(ICoreWidget* parent = nullptr);
    ~ICoreUpdateDialog() override;

    // ---- what to show ----------------------------------------------------

    // The decision and the release it is about. `release` may be an empty row
    // (UpToDate has nothing to describe); the size and notes lines then simply
    // do not appear rather than showing "0 bytes" and a dead link.
    void showDecision(const ICoreUpdateChecker::Decision& decision,
                      const ICoreUpdateManifest::Release& release);

    [[nodiscard]] ICoreUpdateChecker::Outcome outcome() const;

    // Which install the buttons are about. The constructor asks
    // ICoreInstallKind::detect(); a suite hands in a fabricated one to drive
    // the /Applications cases on a machine that is not installed there.
    void setInstall(const ICoreInstallKind::Result& install);

    // ---- the download, while it runs -------------------------------------

    // 0..100, or -1 for "started, length unknown" — a presigned URL that
    // answers without a Content-Length is ordinary, and a bar stuck at 0 reads
    // as a hang. Calling this is what puts the dialog into its downloading
    // state; the Install button becomes Cancel.
    void setDownloadProgress(int percent, std::int64_t bytesReceived,
                             std::int64_t bytesTotal);

    // The download finished, or could not. `error` empty means it worked.
    void setDownloadFinished(const ICoreString& error);

    // U6.6: the Download run ended with the verified artifact in the user's
    // hands. `opened` false means it verified and could not be shown.
    void setManualInstallReady(bool opened);

    [[nodiscard]] bool isDownloading() const;

    // ---- what the user chose ---------------------------------------------

    // Install (or, while downloading, Cancel) was pressed. The dialog does not
    // download or apply anything itself: it reports, and the caller owns the
    // downloader — which is what keeps ICoreStudio out of the update mechanism
    // entirely.
    ICoreSignal<>            installRequested;
    ICoreSignal<>            cancelRequested;

    // "Later". Distinguished from closing the window so a caller can tell a
    // deliberate decline from a dismissal, which the banner reads differently.
    ICoreSignal<>            postponed;

    // ---- the text, for a suite with no screen -----------------------------

    [[nodiscard]] ICoreString headlineText() const;
    [[nodiscard]] ICoreString detailText() const;
    [[nodiscard]] ICoreString sizeText() const;
    [[nodiscard]] ICoreString progressText() const;

    [[nodiscard]] bool hasInstallButton() const;
    // The same primary button, reading Download (U6.6). Never true together
    // with hasInstallButton() outside a download in flight.
    [[nodiscard]] bool hasDownloadButton() const;
    // U6.8: "Open in Microsoft Store", for an install the Store owns and
    // updates. Shown beside the Store's hint, never with Install or Download.
    [[nodiscard]] bool hasStoreButton() const;
    void pressStore();
    [[nodiscard]] bool hasReleaseNotesLink() const;

    // The Install button, pressed programmatically. A suite asserts what the
    // dialog DOES, not only what it says.
    void pressInstall();
    void pressLater();

    // ---- formatting, which is the part that is easy to get wrong ----------

    // "148.2 MB". Powers of 1000, because that is what a download manager and
    // every operating system's file dialog show, and a user comparing this to
    // their browser's number must see the same one. 0 and negatives answer an
    // empty string rather than "0 B" — an unknown size is not a size.
    [[nodiscard]] static ICoreString describeSize(std::int64_t bytes);

    static int selfTest(std::vector<std::string>* failures);

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};