diff --git a/editor/src/messages/dialog/simple_dialogs/licenses_dialog.rs b/editor/src/messages/dialog/simple_dialogs/licenses_dialog.rs index e531858d..e4fe5792 100644 --- a/editor/src/messages/dialog/simple_dialogs/licenses_dialog.rs +++ b/editor/src/messages/dialog/simple_dialogs/licenses_dialog.rs @@ -18,25 +18,19 @@ impl DialogLayoutHolder for LicensesDialog { fn layout_column_2(&self) -> Layout { #[allow(clippy::type_complexity)] let button_definitions: &[(&str, &str, fn() -> Message)] = &[ - ("GraphiteLogo", "Graphite Logo", || { + ("Code", "Source Code License", || { FrontendMessage::TriggerVisitLink { - url: "https://graphite.art/logo/".into(), + url: "https://graphite.art/license#source-code".into(), } .into() }), - ("IconsGrid", "Graphite Icons", || { + ("GraphiteLogo", "Branding License", || { FrontendMessage::TriggerVisitLink { - url: "https://raw.githubusercontent.com/GraphiteEditor/Graphite/master/frontend/assets/LICENSE.md".into(), + url: "https://graphite.art/license#branding".into(), } .into() }), - ("License", "Graphite License", || { - FrontendMessage::TriggerVisitLink { - url: "https://graphite.art/license/".into(), - } - .into() - }), - ("License", "Other Licenses", || FrontendMessage::TriggerDisplayThirdPartyLicensesDialog.into()), + ("IconsGrid", "Dependency Licenses", || FrontendMessage::TriggerDisplayThirdPartyLicensesDialog.into()), ]; let widgets = button_definitions .iter() @@ -52,13 +46,11 @@ impl LayoutHolder for LicensesDialog { let year = &self.localized_commit_year; let description = format!( " - The Graphite logo and brand identity are copyright © {year}\nGraphite Labs, LLC. See \"Graphite Logo\" for usage policy.\n\ + Graphite source code is copyright © {year} Graphite contrib-\nutors and is available under the Apache License 2.0. See\n\"Source Code License\" for details.\n\ \n\ - The Graphite editor's icons and design assets are copyright\n© {year} Graphite Labs, LLC. See \"Graphite Icons\" for details.\n\ + The Graphite logo, icons, and visual identity are copyright ©\n{year} Graphite Labs, LLC. See \"Branding License\" for details.\n\ \n\ - Graphite code is copyright © {year} Graphite contributors\nand is made available under the Apache 2.0 license. See\n\"Graphite License\" for details.\n\ - \n\ - Graphite is distributed with third-party open source code\ndependencies. See \"Other Licenses\" for details. + Graphite is distributed with third-party open source code\ndependencies. See \"Dependency Licenses\" for details. " ); let description = description.trim(); diff --git a/editor/src/messages/frontend/frontend_message.rs b/editor/src/messages/frontend/frontend_message.rs index a63c6a22..0467abe1 100644 --- a/editor/src/messages/frontend/frontend_message.rs +++ b/editor/src/messages/frontend/frontend_message.rs @@ -327,6 +327,9 @@ pub enum FrontendMessage { UpdateStatusBarHintsLayout { diff: Vec, }, + UpdateStatusBarInfoLayout { + diff: Vec, + }, UpdateWorkingColorsLayout { diff: Vec, }, diff --git a/editor/src/messages/layout/layout_message_handler.rs b/editor/src/messages/layout/layout_message_handler.rs index dcfcc1da..57a98eb0 100644 --- a/editor/src/messages/layout/layout_message_handler.rs +++ b/editor/src/messages/layout/layout_message_handler.rs @@ -481,6 +481,7 @@ impl LayoutMessageHandler { LayoutTarget::NodeGraphControlBar => FrontendMessage::UpdateNodeGraphControlBarLayout { diff }, LayoutTarget::PropertiesPanel => FrontendMessage::UpdatePropertiesPanelLayout { diff }, LayoutTarget::StatusBarHints => FrontendMessage::UpdateStatusBarHintsLayout { diff }, + LayoutTarget::StatusBarInfo => FrontendMessage::UpdateStatusBarInfoLayout { diff }, LayoutTarget::ToolOptions => FrontendMessage::UpdateToolOptionsLayout { diff }, LayoutTarget::ToolShelf => FrontendMessage::UpdateToolShelfLayout { diff }, LayoutTarget::WelcomeScreenButtons => FrontendMessage::UpdateWelcomeScreenButtonsLayout { diff }, diff --git a/editor/src/messages/layout/utility_types/layout_widget.rs b/editor/src/messages/layout/utility_types/layout_widget.rs index dedb17c1..0c8d7ac2 100644 --- a/editor/src/messages/layout/utility_types/layout_widget.rs +++ b/editor/src/messages/layout/utility_types/layout_widget.rs @@ -46,6 +46,8 @@ pub enum LayoutTarget { PropertiesPanel, /// The contextual input key/mouse combination shortcuts shown in the status bar at the bottom of the window. StatusBarHints, + /// The version information shown in the status bar at the bottom right of the window. + StatusBarInfo, /// The left side of the control bar directly above the canvas. ToolOptions, /// The vertical buttons for all of the tools on the left of the canvas. diff --git a/editor/src/messages/portfolio/portfolio_message.rs b/editor/src/messages/portfolio/portfolio_message.rs index b601e3f5..8b914d77 100644 --- a/editor/src/messages/portfolio/portfolio_message.rs +++ b/editor/src/messages/portfolio/portfolio_message.rs @@ -111,6 +111,7 @@ pub enum PortfolioMessage { }, PrevDocument, RequestWelcomeScreenButtonsLayout, + RequestStatusBarInfoLayout, SetActivePanel { panel: PanelType, }, diff --git a/editor/src/messages/portfolio/portfolio_message_handler.rs b/editor/src/messages/portfolio/portfolio_message_handler.rs index 70f34489..fb7c5268 100644 --- a/editor/src/messages/portfolio/portfolio_message_handler.rs +++ b/editor/src/messages/portfolio/portfolio_message_handler.rs @@ -131,6 +131,9 @@ impl MessageHandler> for Portfolio // Before loading any documents, initially prepare the welcome screen buttons layout responses.add(PortfolioMessage::RequestWelcomeScreenButtonsLayout); + // Request status bar info layout + responses.add(PortfolioMessage::RequestStatusBarInfoLayout); + // Tell frontend to finish loading persistent documents responses.add(FrontendMessage::TriggerLoadRestAutoSaveDocuments); @@ -950,6 +953,16 @@ impl MessageHandler> for Portfolio layout_target: LayoutTarget::WelcomeScreenButtons, }); } + PortfolioMessage::RequestStatusBarInfoLayout => { + let row = LayoutGroup::Row { + widgets: vec![TextLabel::new("Graphite (beta) 1.0.0-RC1").disabled(true).widget_instance()], + }; + + responses.add(LayoutMessage::SendLayout { + layout: Layout(vec![row]), + layout_target: LayoutTarget::StatusBarInfo, + }); + } PortfolioMessage::SetActivePanel { panel } => { self.active_panel = panel; responses.add(DocumentMessage::SetActivePanel { active_panel: self.active_panel }); diff --git a/frontend/src/components/panels/Welcome.svelte b/frontend/src/components/panels/Welcome.svelte index dc69cdec..c2af5f7c 100644 --- a/frontend/src/components/panels/Welcome.svelte +++ b/frontend/src/components/panels/Welcome.svelte @@ -4,6 +4,7 @@ import type { Editor } from "@graphite/editor"; import type { Layout } from "@graphite/messages"; import { patchLayout, UpdateWelcomeScreenButtonsLayout } from "@graphite/messages"; + import { isDesktop } from "@graphite/utility-functions/platform"; import { extractPixelData } from "@graphite/utility-functions/rasterization"; import LayoutCol from "@graphite/components/layout/LayoutCol.svelte"; @@ -72,13 +73,15 @@ - {#if new Date().getFullYear() === 2025} - + + {#if isDesktop()} + You are testing Release Candidate 1 of the 1.0.0 desktop release. Please regularly check Discord for the next testing build and report issues you encounter. + {:else if new Date().getFullYear() === 2025} September 2025 release — What's new? (video) — Note: some older documents may render differently and require manual fixes. Need the old version? - - {/if} + {/if} + diff --git a/frontend/src/components/window/MainWindow.svelte b/frontend/src/components/window/MainWindow.svelte index 19be805d..fb33864d 100644 --- a/frontend/src/components/window/MainWindow.svelte +++ b/frontend/src/components/window/MainWindow.svelte @@ -4,10 +4,12 @@ import type { AppWindowState } from "@graphite/state-providers/app-window"; import type { DialogState } from "@graphite/state-providers/dialog"; import type { TooltipState } from "@graphite/state-providers/tooltip"; + import { isDesktop } from "@graphite/utility-functions/platform"; import Dialog from "@graphite/components/floating-menus/Dialog.svelte"; import Tooltip from "@graphite/components/floating-menus/Tooltip.svelte"; import LayoutCol from "@graphite/components/layout/LayoutCol.svelte"; + import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte"; import StatusBar from "@graphite/components/window/status-bar/StatusBar.svelte"; import TitleBar from "@graphite/components/window/title-bar/TitleBar.svelte"; import Workspace from "@graphite/components/window/workspace/Workspace.svelte"; @@ -29,6 +31,17 @@ {#if $tooltip.visible} {/if} + {#if isDesktop() && new Date() > new Date("2026-01-31")} + + +

+ This is an outdated desktop release candidate build. Its testing
+ period has concluded and the next build is available for download.
+ Please update to help us continue testing by reporting new issues. +

+
+
+ {/if} diff --git a/frontend/src/components/window/status-bar/StatusBar.svelte b/frontend/src/components/window/status-bar/StatusBar.svelte index a17d3d26..67ca5e4b 100644 --- a/frontend/src/components/window/status-bar/StatusBar.svelte +++ b/frontend/src/components/window/status-bar/StatusBar.svelte @@ -3,25 +3,33 @@ import type { Editor } from "@graphite/editor"; import type { Layout } from "@graphite/messages"; - import { patchLayout, UpdateStatusBarHintsLayout } from "@graphite/messages"; + import { patchLayout, UpdateStatusBarHintsLayout, UpdateStatusBarInfoLayout } from "@graphite/messages"; import LayoutRow from "@graphite/components/layout/LayoutRow.svelte"; + import Separator from "@graphite/components/widgets/labels/Separator.svelte"; import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte"; const editor = getContext("editor"); let statusBarHintsLayout: Layout = []; + let statusBarInfoLayout: Layout = []; onMount(() => { editor.subscriptions.subscribeJsMessage(UpdateStatusBarHintsLayout, (data) => { patchLayout(statusBarHintsLayout, data); statusBarHintsLayout = statusBarHintsLayout; }); + editor.subscriptions.subscribeJsMessage(UpdateStatusBarInfoLayout, (data) => { + patchLayout(statusBarInfoLayout, data); + statusBarInfoLayout = statusBarInfoLayout; + }); }); + + diff --git a/frontend/src/messages.ts b/frontend/src/messages.ts index 28aaf6e8..3d3707fc 100644 --- a/frontend/src/messages.ts +++ b/frontend/src/messages.ts @@ -1474,6 +1474,7 @@ export type LayoutTarget = | "NodeGraphControlBar" | "PropertiesPanel" | "StatusBarHints" + | "StatusBarInfo" | "ToolOptions" | "ToolShelf" | "WelcomeScreenButtons" @@ -1634,6 +1635,8 @@ export class UpdateDataPanelLayout extends WidgetDiffUpdate {} export class UpdateStatusBarHintsLayout extends WidgetDiffUpdate {} +export class UpdateStatusBarInfoLayout extends WidgetDiffUpdate {} + export class UpdateToolOptionsLayout extends WidgetDiffUpdate {} export class UpdateToolShelfLayout extends WidgetDiffUpdate {} @@ -1724,6 +1727,7 @@ export const messageMakers: Record = { UpdatePropertiesPanelLayout, UpdatePropertiesPanelState, UpdateStatusBarHintsLayout, + UpdateStatusBarInfoLayout, UpdateToolOptionsLayout, UpdateToolShelfLayout, UpdateViewportHolePunch, diff --git a/node-graph/nodes/vector/src/vector_nodes.rs b/node-graph/nodes/vector/src/vector_nodes.rs index d01be226..a979db66 100644 --- a/node-graph/nodes/vector/src/vector_nodes.rs +++ b/node-graph/nodes/vector/src/vector_nodes.rs @@ -1250,6 +1250,7 @@ where output.element.concat(other, transform, collision_hash_seed); + // TODO: Make this instead use the first encountered style // Use the last encountered style as the output style output.element.style = row.element.style.clone(); } diff --git a/website/content/license.md b/website/content/license.md index b5333a08..06ac3690 100644 --- a/website/content/license.md +++ b/website/content/license.md @@ -209,9 +209,9 @@ Graphite Branding License Copyright (c) 2021-2025 Graphite Labs, LLC. All rights reserved. -This repository includes proprietary assets (the "Assets"), including but not limited to logos, icons, and branding materials. The Assets are not software source code and are consequently not licensed under the same terms as the other works of Graphite software materials. The intention of this license is to maintain the full permissiveness of the software code while reserving protections for the brand and visual identity of the official Graphite product. +The repository `https://github.com/Keavon/graphite-branded-assets/` includes proprietary assets (the "Assets"), including but not limited to logos, icons, and branding materials. The Assets are not software source code and are consequently not licensed under the same terms as the other works of Graphite software materials. The intention of this license is to maintain the full permissiveness of the software code while reserving protections for the brand and visual identity of the official Graphite product. -Permission is granted to use, reproduce, and distribute the Assets solely as part of unmodified build artifacts produced from the official Graphite repository at https://github.com/GraphiteEditor/Graphite, on master branch commits, using the official build process as documented therein. Any other use of the Assets—including copying, extraction, incorporation into modified or forked builds, or use in other projects or contexts—is prohibited without prior written permission from the copyright holder. +Permission is granted to use, reproduce, and distribute the Assets solely as part of unmodified build artifacts produced from the official Graphite repository at `https://github.com/GraphiteEditor/Graphite`, on master branch commits, using the official build process as documented therein. Any other use of the Assets—including copying, extraction, incorporation into modified or forked builds, or use in other projects or contexts—is prohibited without prior written permission from the copyright holder. This license does not grant any rights under trademark law or affect the licensing of the software source code.