Skip to content

Commit 0e46790

Browse files
authored
Improve font import; replace Inconsolata with Source Code Pro; show third-party licenses in editor dialog (#3079)
* Improve font import; replace Inconsolata with Source Code Pro; show third-party licenses in editor dialog * Code review
1 parent e56f858 commit 0e46790

26 files changed

Lines changed: 363 additions & 176 deletions

File tree

.vscode/settings.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,11 @@
3939
"eslint.validate": ["javascript", "typescript", "svelte"],
4040
// Svelte config
4141
"svelte.plugin.svelte.compilerWarnings": {
42-
// NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
43-
"css-unused-selector": "ignore",
44-
"vite-plugin-svelte-css-no-scopable-elements": "ignore",
45-
"a11y-no-static-element-interactions": "ignore",
46-
"a11y-no-noninteractive-element-interactions": "ignore",
47-
"a11y-click-events-have-key-events": "ignore"
42+
"css-unused-selector": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
43+
"vite-plugin-svelte-css-no-scopable-elements": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
44+
"a11y-no-static-element-interactions": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
45+
"a11y-no-noninteractive-element-interactions": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
46+
"a11y-click-events-have-key-events": "ignore" // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
4847
},
4948
// VS Code config
5049
"html.format.wrapLineLength": 200,

about.toml

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
# Keep this list in sync with those in `/deny.toml` and `/frontend/vite.config.ts`.
21
accepted = [
3-
"Apache-2.0 WITH LLVM-exception",
4-
"Apache-2.0",
5-
"BSD-2-Clause",
6-
"BSD-3-Clause",
7-
"BSL-1.0",
8-
"CC0-1.0",
9-
"CDLA-Permissive-2.0",
10-
"ISC",
11-
"MIT-0",
12-
"MIT",
13-
"MPL-2.0",
14-
"OpenSSL",
15-
"Unicode-3.0",
16-
"Unicode-DFS-2016",
17-
"Zlib",
18-
"NCSA",
19-
"bzip2-1.0.6",
2+
"Apache-2.0 WITH LLVM-exception", # Keep this list in sync with those in `/deny.toml`
3+
"Apache-2.0", # Keep this list in sync with those in `/deny.toml`
4+
"BSD-2-Clause", # Keep this list in sync with those in `/deny.toml`
5+
"BSD-3-Clause", # Keep this list in sync with those in `/deny.toml`
6+
"BSL-1.0", # Keep this list in sync with those in `/deny.toml`
7+
"CC0-1.0", # Keep this list in sync with those in `/deny.toml`
8+
"CDLA-Permissive-2.0", # Keep this list in sync with those in `/deny.toml`
9+
"ISC", # Keep this list in sync with those in `/deny.toml`
10+
"MIT-0", # Keep this list in sync with those in `/deny.toml`
11+
"MIT", # Keep this list in sync with those in `/deny.toml`
12+
"MPL-2.0", # Keep this list in sync with those in `/deny.toml`
13+
"OpenSSL", # Keep this list in sync with those in `/deny.toml`
14+
"Unicode-3.0", # Keep this list in sync with those in `/deny.toml`
15+
"Unicode-DFS-2016", # Keep this list in sync with those in `/deny.toml`
16+
"Zlib", # Keep this list in sync with those in `/deny.toml`
17+
"NCSA", # Keep this list in sync with those in `/deny.toml`
18+
"bzip2-1.0.6", # Keep this list in sync with those in `/deny.toml`
19+
"OFL-1.1", # Keep this list in sync with those in `/deny.toml`
2020
]
2121
workarounds = ["ring"]
2222
ignore-build-dependencies = true

deny.toml

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -63,25 +63,25 @@ ignore = [
6363
# See https://spdx.org/licenses/ for list of possible licenses
6464
# [possible values: any SPDX 3.11 short identifier (+ optional exception)].
6565
#
66-
# Keep this list in sync with those in `/about.toml` and `/frontend/vite.config.ts`.
6766
allow = [
68-
"Apache-2.0 WITH LLVM-exception",
69-
"Apache-2.0",
70-
"BSD-2-Clause",
71-
"BSD-3-Clause",
72-
"BSL-1.0",
73-
"CC0-1.0",
74-
"CDLA-Permissive-2.0",
75-
"ISC",
76-
"MIT-0",
77-
"MIT",
78-
"MPL-2.0",
79-
"OpenSSL",
80-
"Unicode-3.0",
81-
"Unicode-DFS-2016",
82-
"Zlib",
83-
"NCSA",
84-
"bzip2-1.0.6",
67+
"Apache-2.0 WITH LLVM-exception", # Keep this list in sync with those in `/about.toml`
68+
"Apache-2.0", # Keep this list in sync with those in `/about.toml`
69+
"BSD-2-Clause", # Keep this list in sync with those in `/about.toml`
70+
"BSD-3-Clause", # Keep this list in sync with those in `/about.toml`
71+
"BSL-1.0", # Keep this list in sync with those in `/about.toml`
72+
"CC0-1.0", # Keep this list in sync with those in `/about.toml`
73+
"CDLA-Permissive-2.0", # Keep this list in sync with those in `/about.toml`
74+
"ISC", # Keep this list in sync with those in `/about.toml`
75+
"MIT-0", # Keep this list in sync with those in `/about.toml`
76+
"MIT", # Keep this list in sync with those in `/about.toml`
77+
"MPL-2.0", # Keep this list in sync with those in `/about.toml`
78+
"OpenSSL", # Keep this list in sync with those in `/about.toml`
79+
"Unicode-3.0", # Keep this list in sync with those in `/about.toml`
80+
"Unicode-DFS-2016", # Keep this list in sync with those in `/about.toml`
81+
"Zlib", # Keep this list in sync with those in `/about.toml`
82+
"NCSA", # Keep this list in sync with those in `/about.toml`
83+
"bzip2-1.0.6", # Keep this list in sync with those in `/about.toml`
84+
"OFL-1.1", # Keep this list in sync with those in `/about.toml`
8585
]
8686
# The confidence threshold for detecting a license from license text.
8787
# The higher the value, the more closely the license text must be to the

editor/src/messages/dialog/dialog_message.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ pub enum DialogMessage {
3333
RequestLicensesDialogWithLocalizedCommitDate {
3434
localized_commit_year: String,
3535
},
36+
RequestLicensesThirdPartyDialogWithLicenseText {
37+
license_text: String,
38+
},
3639
RequestNewDocumentDialog,
3740
RequestPreferencesDialog,
3841
}

editor/src/messages/dialog/dialog_message_handler.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::new_document_dialog::NewDocumentDialogMessageContext;
22
use super::simple_dialogs::{self, AboutGraphiteDialog, ComingSoonDialog, DemoArtworkDialog, LicensesDialog};
3+
use crate::messages::dialog::simple_dialogs::LicensesThirdPartyDialog;
34
use crate::messages::input_mapper::utility_types::input_mouse::ViewportBounds;
45
use crate::messages::layout::utility_types::widget_prelude::*;
56
use crate::messages::prelude::*;
@@ -103,6 +104,10 @@ impl MessageHandler<DialogMessage, DialogMessageContext<'_>> for DialogMessageHa
103104

104105
dialog.send_dialog_to_frontend(responses);
105106
}
107+
DialogMessage::RequestLicensesThirdPartyDialogWithLicenseText { license_text } => {
108+
let dialog = LicensesThirdPartyDialog { license_text };
109+
dialog.send_dialog_to_frontend(responses);
110+
}
106111
DialogMessage::RequestNewDocumentDialog => {
107112
self.new_document_dialog = NewDocumentDialogMessageHandler {
108113
name: portfolio.generate_new_document_name(),

editor/src/messages/dialog/export_dialog/export_dialog_message_handler.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,13 @@ impl LayoutHolder for ExportDialogMessageHandler {
9292
.collect();
9393

9494
let export_type = vec![
95-
TextLabel::new("File Type").table_align(true).min_width(100).widget_holder(),
95+
TextLabel::new("File Type").table_align(true).min_width("100px").widget_holder(),
9696
Separator::new(SeparatorType::Unrelated).widget_holder(),
9797
RadioInput::new(entries).selected_index(Some(self.file_type as u32)).widget_holder(),
9898
];
9999

100100
let resolution = vec![
101-
TextLabel::new("Scale Factor").table_align(true).min_width(100).widget_holder(),
101+
TextLabel::new("Scale Factor").table_align(true).min_width("100px").widget_holder(),
102102
Separator::new(SeparatorType::Unrelated).widget_holder(),
103103
NumberInput::new(Some(self.scale_factor))
104104
.unit("")
@@ -144,14 +144,14 @@ impl LayoutHolder for ExportDialogMessageHandler {
144144
}
145145

146146
let export_area = vec![
147-
TextLabel::new("Bounds").table_align(true).min_width(100).widget_holder(),
147+
TextLabel::new("Bounds").table_align(true).min_width("100px").widget_holder(),
148148
Separator::new(SeparatorType::Unrelated).widget_holder(),
149149
DropdownInput::new(entries).selected_index(Some(index as u32)).widget_holder(),
150150
];
151151

152152
let checkbox_id = CheckboxId::new();
153153
let transparent_background = vec![
154-
TextLabel::new("Transparency").table_align(true).min_width(100).for_checkbox(checkbox_id).widget_holder(),
154+
TextLabel::new("Transparency").table_align(true).min_width("100px").for_checkbox(checkbox_id).widget_holder(),
155155
Separator::new(SeparatorType::Unrelated).widget_holder(),
156156
CheckboxInput::new(self.transparent_background)
157157
.disabled(self.file_type == FileType::Jpg)

editor/src/messages/dialog/new_document_dialog/new_document_dialog_message_handler.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ impl DialogLayoutHolder for NewDocumentDialogMessageHandler {
7979
impl LayoutHolder for NewDocumentDialogMessageHandler {
8080
fn layout(&self) -> Layout {
8181
let name = vec![
82-
TextLabel::new("Name").table_align(true).min_width(90).widget_holder(),
82+
TextLabel::new("Name").table_align(true).min_width("90px").widget_holder(),
8383
Separator::new(SeparatorType::Unrelated).widget_holder(),
8484
TextInput::new(&self.name)
8585
.on_update(|text_input: &TextInput| NewDocumentDialogMessage::Name { name: text_input.value.clone() }.into())
@@ -89,7 +89,7 @@ impl LayoutHolder for NewDocumentDialogMessageHandler {
8989

9090
let checkbox_id = CheckboxId::new();
9191
let infinite = vec![
92-
TextLabel::new("Infinite Canvas").table_align(true).min_width(90).for_checkbox(checkbox_id).widget_holder(),
92+
TextLabel::new("Infinite Canvas").table_align(true).min_width("90px").for_checkbox(checkbox_id).widget_holder(),
9393
Separator::new(SeparatorType::Unrelated).widget_holder(),
9494
CheckboxInput::new(self.infinite)
9595
.on_update(|checkbox_input: &CheckboxInput| NewDocumentDialogMessage::Infinite { infinite: checkbox_input.checked }.into())
@@ -98,7 +98,7 @@ impl LayoutHolder for NewDocumentDialogMessageHandler {
9898
];
9999

100100
let scale = vec![
101-
TextLabel::new("Dimensions").table_align(true).min_width(90).widget_holder(),
101+
TextLabel::new("Dimensions").table_align(true).min_width("90px").widget_holder(),
102102
Separator::new(SeparatorType::Unrelated).widget_holder(),
103103
NumberInput::new(Some(self.dimensions.x as f64))
104104
.label("W")

editor/src/messages/dialog/simple_dialogs/licenses_dialog.rs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,31 @@ impl DialogLayoutHolder for LicensesDialog {
1616
}
1717

1818
fn layout_column_2(&self) -> Layout {
19-
let icons_license_link = "https://raw.githubusercontent.com/GraphiteEditor/Graphite/master/frontend/assets/LICENSE.md";
20-
let links = [
21-
("GraphiteLogo", "Graphite Logo", "https://graphite.rs/logo/"),
22-
("IconsGrid", "Graphite Icons", icons_license_link),
23-
("License", "Graphite License", "https://graphite.rs/license/"),
24-
("License", "Other Licenses", "/third-party-licenses.txt"),
19+
#[allow(clippy::type_complexity)]
20+
let button_definitions: &[(&str, &str, fn() -> Message)] = &[
21+
("GraphiteLogo", "Graphite Logo", || {
22+
FrontendMessage::TriggerVisitLink {
23+
url: "https://graphite.rs/logo/".into(),
24+
}
25+
.into()
26+
}),
27+
("IconsGrid", "Graphite Icons", || {
28+
FrontendMessage::TriggerVisitLink {
29+
url: "https://raw.githubusercontent.com/GraphiteEditor/Graphite/master/frontend/assets/LICENSE.md".into(),
30+
}
31+
.into()
32+
}),
33+
("License", "Graphite License", || {
34+
FrontendMessage::TriggerVisitLink {
35+
url: "https://graphite.rs/license/".into(),
36+
}
37+
.into()
38+
}),
39+
("License", "Other Licenses", || FrontendMessage::TriggerDisplayThirdPartyLicensesDialog.into()),
2540
];
26-
let widgets = links
27-
.into_iter()
28-
.map(|(icon, label, url)| {
29-
TextButton::new(label)
30-
.icon(Some(icon.into()))
31-
.flush(true)
32-
.on_update(|_| FrontendMessage::TriggerVisitLink { url: url.into() }.into())
33-
.widget_holder()
34-
})
41+
let widgets = button_definitions
42+
.iter()
43+
.map(|&(icon, label, message_factory)| TextButton::new(label).icon(Some((icon).into())).flush(true).on_update(move |_| message_factory()).widget_holder())
3544
.collect();
3645

3746
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Column { widgets }]))
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use crate::messages::layout::utility_types::widget_prelude::*;
2+
use crate::messages::prelude::*;
3+
4+
pub struct LicensesThirdPartyDialog {
5+
pub license_text: String,
6+
}
7+
8+
impl DialogLayoutHolder for LicensesThirdPartyDialog {
9+
const ICON: &'static str = "License12px";
10+
const TITLE: &'static str = "Third-Party Software License Notices";
11+
12+
fn layout_buttons(&self) -> Layout {
13+
let widgets = vec![TextButton::new("OK").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_holder()];
14+
15+
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
16+
}
17+
}
18+
19+
impl LayoutHolder for LicensesThirdPartyDialog {
20+
fn layout(&self) -> Layout {
21+
// Remove the header and begin with the line containing the first license section (we otherwise keep the title for standalone viewing of the licenses text file)
22+
let license_text = if let Some(first_underscore_line) = self.license_text.lines().position(|line| line.contains('_')) {
23+
// Find the byte position where the line with underscore starts
24+
let char_position = self.license_text.split('\n').take(first_underscore_line).map(|line| line.len() + '\n'.len_utf8()).sum();
25+
self.license_text[char_position..].to_string()
26+
} else {
27+
// This shouldn't be encountered, but if no underscore line is found, we use the full text as a safety fallback
28+
self.license_text.clone()
29+
};
30+
31+
// Two characters (one before, one after) the sequence of underscore characters, plus one additional column to provide a space between the text and the scrollbar
32+
let non_wrapping_column_width = license_text.split('\n').map(|line| line.chars().filter(|&c| c == '_').count()).max().unwrap_or(0) + 2 + 1;
33+
34+
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row {
35+
widgets: vec![
36+
TextLabel::new(license_text)
37+
.monospace(true)
38+
.multiline(true)
39+
.min_width(format!("{non_wrapping_column_width}ch"))
40+
.widget_holder(),
41+
],
42+
}]))
43+
}
44+
}

editor/src/messages/dialog/simple_dialogs/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod coming_soon_dialog;
55
mod demo_artwork_dialog;
66
mod error_dialog;
77
mod licenses_dialog;
8+
mod licenses_third_party_dialog;
89

910
pub use about_graphite_dialog::AboutGraphiteDialog;
1011
pub use close_all_documents_dialog::CloseAllDocumentsDialog;
@@ -14,3 +15,4 @@ pub use demo_artwork_dialog::ARTWORK;
1415
pub use demo_artwork_dialog::DemoArtworkDialog;
1516
pub use error_dialog::ErrorDialog;
1617
pub use licenses_dialog::LicensesDialog;
18+
pub use licenses_third_party_dialog::LicensesThirdPartyDialog;

0 commit comments

Comments
 (0)