mirror of
https://github.com/storytold/craft-launcher.git
synced 2026-10-14 14:26:48 -04:00
fix(ui): remove third-party product comparisons
PR #84. Closes #83. Includes formatting-only corrections in the shared UI. Co-authored-by: skylar taylor-barrick <[email protected]>
This commit is contained in:
1 parent
7ba85e54f0
commit
93caf01c4e
8 files changed
+10
-99
No files matched your search
@@ -50,7 +50,7 @@
|
||||
<img src="docs/screenshots/artcraft-launcher-grid.png" alt="ArtCraft Launcher on macOS in the grid view (dark theme): a card for each Craft App with its icon, status, version, release date and an Install or Open button" width="900">
|
||||
</p>
|
||||
<p align="center">
|
||||
<img src="docs/screenshots/artcraft-launcher-table.png" alt="The same apps in the table view (light theme), with columns for what each app is inspired by, its status, installed and latest versions, and release date" width="900"><br>
|
||||
<img src="docs/screenshots/artcraft-launcher-table.png" alt="The same apps in the table view (light theme), with columns for each app's status, installed and latest versions, and release date" width="900"><br>
|
||||
<sub>Switch between the grid and a sortable table.</sub>
|
||||
</p>
|
||||
|
||||
@@ -301,8 +301,6 @@ are trademarks of the ArtCraft Team and are not covered by this license. They ma
|
||||
part of this repository and ArtCraft Launcher, under [`docs/brand/LICENSE-brand.txt`](docs/brand/LICENSE-brand.txt).
|
||||
Forks and modified versions must remove them.
|
||||
|
||||
<sub>Adobe, Photoshop, Illustrator, Premiere Pro, Lightroom, Acrobat, After Effects and InDesign are either registered trademarks or trademarks of Adobe in the United States and/or other countries. Microsoft, Word, PowerPoint and Excel are trademarks of the Microsoft group of companies. Autodesk and AutoCAD are registered trademarks or trademarks of Autodesk, Inc. Avid and Pro Tools are trademarks or registered trademarks of Avid Technology, Inc. All other trademarks are the property of their respective owners. These names are used only to describe what each Craft App is for; the Craft App Suite is independent and is not affiliated with, sponsored by or endorsed by any of these companies.</sub>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://getartcraft.com/"><img alt="ArtCraft" src="docs/brand/artcraft-mark.svg" width="28"></a><br>
|
||||
<sub>Made by the <a href="https://getartcraft.com/">ArtCraft</a> team and community.</sub>
|
||||
|
||||
@@ -34,8 +34,6 @@ pub struct CraftApp {
|
||||
pub name: &'static str,
|
||||
/// What it's for, in a few words (English; the UI translates it by app id).
|
||||
pub tagline: &'static str,
|
||||
/// The familiar app it reimplements, for orientation.
|
||||
pub like: &'static str,
|
||||
pub group: AppGroup,
|
||||
/// Brand colour (sRGB), for surfaces: getartcraft.com's `--app`.
|
||||
pub color: [u8; 3],
|
||||
@@ -50,11 +48,6 @@ pub struct CraftApp {
|
||||
}
|
||||
|
||||
impl CraftApp {
|
||||
/// The product it's inspired by, with its registered-trademark sign (`Adobe Photoshop®`).
|
||||
pub fn inspired_by(&self) -> String {
|
||||
format!("{}®", self.like)
|
||||
}
|
||||
|
||||
/// `ai.storyteller.<id>`: macOS bundle id, Flatpak id and Linux desktop-file id.
|
||||
pub fn bundle_id(&self) -> String {
|
||||
format!("ai.storyteller.{}", self.id)
|
||||
@@ -87,12 +80,11 @@ const fn app(
|
||||
id: &'static str,
|
||||
name: &'static str,
|
||||
tagline: &'static str,
|
||||
like: &'static str,
|
||||
group: AppGroup,
|
||||
[color, ink_light, ink_dark]: [[u8; 3]; 3],
|
||||
repo: &'static str,
|
||||
) -> CraftApp {
|
||||
CraftApp { id, name, tagline, like, group, color, ink_light, ink_dark, repo, former_ids: &[] }
|
||||
CraftApp { id, name, tagline, group, color, ink_light, ink_dark, repo, former_ids: &[] }
|
||||
}
|
||||
|
||||
/// The Craft App Suite, in display order: the seven classic apps, then the five new ones.
|
||||
@@ -101,7 +93,6 @@ pub const SUITE: [CraftApp; 12] = [
|
||||
"photocraft",
|
||||
"PhotoCraft",
|
||||
"Image editing",
|
||||
"Adobe Photoshop",
|
||||
AppGroup::Classic,
|
||||
[[0x2f, 0x7b, 0xf5], [0x1a, 0x5b, 0xc4], [0x7f, 0xb0, 0xff]],
|
||||
"storytold/photocraft",
|
||||
@@ -110,7 +101,6 @@ pub const SUITE: [CraftApp; 12] = [
|
||||
"vectorcraft",
|
||||
"VectorCraft",
|
||||
"Vector illustration",
|
||||
"Adobe Illustrator",
|
||||
AppGroup::Classic,
|
||||
[[0xe8, 0x57, 0x3f], [0xb8, 0x3a, 0x24], [0xff, 0x8a, 0x70]],
|
||||
"storytold/vectorcraft",
|
||||
@@ -119,7 +109,6 @@ pub const SUITE: [CraftApp; 12] = [
|
||||
"filmcraft",
|
||||
"FilmCraft",
|
||||
"Video editing, color and sound",
|
||||
"Adobe Premiere Pro",
|
||||
AppGroup::Classic,
|
||||
[[0x8b, 0x5c, 0xf6], [0x6a, 0x3f, 0xd6], [0xb6, 0x9c, 0xff]],
|
||||
"storytold/filmcraft",
|
||||
@@ -128,7 +117,6 @@ pub const SUITE: [CraftApp; 12] = [
|
||||
"lightcraft",
|
||||
"LightCraft",
|
||||
"Photo library and raw development",
|
||||
"Adobe Lightroom",
|
||||
AppGroup::Classic,
|
||||
[[0xf2, 0xa5, 0x16], [0x8a, 0x58, 0x00], [0xff, 0xc1, 0x4d]],
|
||||
"storytold/lightcraft",
|
||||
@@ -139,7 +127,6 @@ pub const SUITE: [CraftApp; 12] = [
|
||||
"pdfcraft",
|
||||
"PdfCraft",
|
||||
"Reading, organizing and protecting PDFs",
|
||||
"Adobe Acrobat",
|
||||
AppGroup::Classic,
|
||||
[[0x12, 0xa5, 0x8a], [0x0a, 0x75, 0x63], [0x3f, 0xd6, 0xb8]],
|
||||
"storytold/pdfcraft",
|
||||
@@ -149,7 +136,6 @@ pub const SUITE: [CraftApp; 12] = [
|
||||
"effectcraft",
|
||||
"EffectCraft",
|
||||
"Motion graphics and visual effects",
|
||||
"Adobe After Effects",
|
||||
AppGroup::Classic,
|
||||
[[0xe0, 0x36, 0x8f], [0xb0, 0x20, 0x6c], [0xff, 0x7a, 0xb8]],
|
||||
"storytold/effectcraft",
|
||||
@@ -158,7 +144,6 @@ pub const SUITE: [CraftApp; 12] = [
|
||||
"designcraft",
|
||||
"DesignCraft",
|
||||
"Page layout and publishing",
|
||||
"Adobe InDesign",
|
||||
AppGroup::Classic,
|
||||
[[0x7b, 0xb5, 0x1c], [0x45, 0x70, 0x08], [0xa6, 0xe0, 0x4a]],
|
||||
"storytold/designcraft",
|
||||
@@ -167,7 +152,6 @@ pub const SUITE: [CraftApp; 12] = [
|
||||
"wordcraft",
|
||||
"WordCraft",
|
||||
"Writing and document design",
|
||||
"Microsoft Word",
|
||||
AppGroup::New,
|
||||
[[0x3f, 0x5f, 0xe0], [0x2a, 0x44, 0xb8], [0x8e, 0xa2, 0xff]],
|
||||
"storytold/wordcraft",
|
||||
@@ -176,7 +160,6 @@ pub const SUITE: [CraftApp; 12] = [
|
||||
"deckcraft",
|
||||
"DeckCraft",
|
||||
"Presentations and slide shows",
|
||||
"Microsoft PowerPoint",
|
||||
AppGroup::New,
|
||||
[[0xf0, 0x7a, 0x1e], [0xa8, 0x4f, 0x0a], [0xff, 0xa0, 0x60]],
|
||||
"storytold/deckcraft",
|
||||
@@ -185,7 +168,6 @@ pub const SUITE: [CraftApp; 12] = [
|
||||
"gridcraft",
|
||||
"GridCraft",
|
||||
"Spreadsheets and data",
|
||||
"Microsoft Excel",
|
||||
AppGroup::New,
|
||||
[[0x1f, 0x9d, 0x55], [0x12, 0x70, 0x3a], [0x4f, 0xd6, 0x8a]],
|
||||
"storytold/gridcraft",
|
||||
@@ -194,7 +176,6 @@ pub const SUITE: [CraftApp; 12] = [
|
||||
"cadcraft",
|
||||
"CADCraft",
|
||||
"Computer-aided design and drafting",
|
||||
"Autodesk AutoCAD",
|
||||
AppGroup::New,
|
||||
[[0x3e, 0xa6, 0xe8], [0x1a, 0x6f, 0xa8], [0x7c, 0xc8, 0xff]],
|
||||
"storytold/cadcraft",
|
||||
@@ -203,21 +184,12 @@ pub const SUITE: [CraftApp; 12] = [
|
||||
"soundcraft",
|
||||
"SoundCraft",
|
||||
"Recording, editing and mixing audio",
|
||||
"Avid Pro Tools",
|
||||
AppGroup::New,
|
||||
[[0x1f, 0xa5, 0xc9], [0x0e, 0x72, 0x90], [0x5f, 0xd0, 0xee]],
|
||||
"storytold/soundcraft",
|
||||
),
|
||||
];
|
||||
|
||||
/// Shown wherever the products the apps are inspired by are named.
|
||||
pub const TRADEMARK_NOTICE: &str = "Adobe, Photoshop, Illustrator, Premiere Pro, Lightroom, Acrobat, After Effects and InDesign are either \
|
||||
registered trademarks or trademarks of Adobe in the United States and/or other countries. Microsoft, Word, PowerPoint and Excel are \
|
||||
trademarks of the Microsoft group of companies. Autodesk and AutoCAD are registered trademarks or trademarks of Autodesk, Inc. Avid \
|
||||
and Pro Tools are trademarks or registered trademarks of Avid Technology, Inc. All other trademarks are the property of their \
|
||||
respective owners. These names are used only to describe what each Craft App is for; the Craft App Suite is independent and is not \
|
||||
affiliated with, sponsored by or endorsed by any of these companies.";
|
||||
|
||||
/// ArtCraft's website.
|
||||
pub const WEBSITE_URL: &str = "https://getartcraft.com";
|
||||
/// ArtCraft on GitHub: every Craft App's source.
|
||||
@@ -241,7 +213,6 @@ pub const LAUNCHER: CraftApp = app(
|
||||
"artcraft-launcher",
|
||||
"ArtCraft Launcher",
|
||||
"Installs and updates the Craft App Suite",
|
||||
"",
|
||||
AppGroup::New,
|
||||
[[0x0b, 0x0b, 0x0c], [0x0b, 0x0b, 0x0c], [0xf2, 0xf1, 0xee]],
|
||||
"storytold/craft-launcher",
|
||||
@@ -270,17 +241,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_inspiring_product_is_covered_by_the_trademark_notice() {
|
||||
for a in &SUITE {
|
||||
assert!(a.inspired_by().ends_with('®'));
|
||||
// The company and the product name both appear in the notice.
|
||||
let (company, product) = a.like.split_once(' ').unwrap();
|
||||
assert!(TRADEMARK_NOTICE.contains(company), "{company}");
|
||||
assert!(TRADEMARK_NOTICE.contains(product), "{product}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pdfcraft_also_answers_to_printcraft() {
|
||||
let pdf = CraftApp::by_id("pdfcraft").unwrap();
|
||||
|
||||
@@ -485,7 +485,6 @@ impl LauncherUi {
|
||||
ViewMode::Table => self.table(ui, &ids),
|
||||
}
|
||||
}
|
||||
self.trademark_notice(ui);
|
||||
ui.add_space(16.0);
|
||||
});
|
||||
});
|
||||
@@ -511,10 +510,7 @@ impl LauncherUi {
|
||||
Filter::Updates => s == AppStatus::UpdateAvailable,
|
||||
Filter::NotInstalled => !s.is_installed(),
|
||||
};
|
||||
keep && (needle.is_empty()
|
||||
|| e.app.name.to_lowercase().contains(&needle)
|
||||
|| e.app.tagline.to_lowercase().contains(&needle)
|
||||
|| e.app.like.to_lowercase().contains(&needle))
|
||||
keep && (needle.is_empty() || e.app.name.to_lowercase().contains(&needle) || e.app.tagline.to_lowercase().contains(&needle))
|
||||
})
|
||||
.collect();
|
||||
let platform = self.platform;
|
||||
@@ -534,7 +530,6 @@ impl LauncherUi {
|
||||
let ord = match self.settings.sort {
|
||||
SortKey::Suite => dir(ia.cmp(ib)),
|
||||
SortKey::Name => dir(a.app.name.cmp(b.app.name)),
|
||||
SortKey::InspiredBy => dir(a.app.like.cmp(b.app.like)),
|
||||
SortKey::Status => {
|
||||
dir(crate::model::status_rank(&a.status(platform, manage)).cmp(&crate::model::status_rank(&b.status(platform, manage))))
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
Sort Сортировка
|
||||
Suite order По классу приложений
|
||||
Name Имя
|
||||
Inspired by Вдохновлено
|
||||
Status Статус
|
||||
Installed version Установленная версия
|
||||
Latest version Последняя версия
|
||||
@@ -215,7 +214,6 @@ month Dec дек.
|
||||
Descending По убыванию
|
||||
Click to reverse the order Нажмите, чтобы изменить порядок
|
||||
Click to sort by this column Нажмите, чтобы сортировать по этому столбцу
|
||||
Like {name} Аналог {name}
|
||||
{done} of {total} {done} из {total}
|
||||
Downloading Скачивание
|
||||
Verifying checksum… Проверка контрольной суммы…
|
||||
@@ -298,7 +296,6 @@ filter Installed Установлены
|
||||
@id filter.notinstalled Не установленные
|
||||
@id sort.suite По классу приложений
|
||||
@id sort.name Имя
|
||||
@id sort.inspired Вдохновлено
|
||||
@id sort.status Статус
|
||||
@id sort.installed Установленная версия
|
||||
@id sort.latest Последняя версия
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 13 and column 44.
|
@@ -21,7 +21,6 @@
|
||||
Sort 排序
|
||||
Suite order 默认顺序
|
||||
Name 名称
|
||||
Inspired by 参考软件
|
||||
Status 状态
|
||||
Installed version 已安装版本
|
||||
Latest version 最新版本
|
||||
@@ -140,7 +139,6 @@ month Dec 12月
|
||||
Descending 降序
|
||||
Click to reverse the order 点击切换排序方向
|
||||
Click to sort by this column 点击按此列排序
|
||||
Like {name} 类似 {name}
|
||||
{done} of {total} {done} / {total}
|
||||
Downloading 正在下载
|
||||
Verifying checksum… 正在验证校验和…
|
||||
@@ -203,7 +201,6 @@ filter Installed 已安装
|
||||
@id filter.notinstalled 未安装
|
||||
@id sort.suite 默认顺序
|
||||
@id sort.name 名称
|
||||
@id sort.inspired 参考软件
|
||||
@id sort.status 状态
|
||||
@id sort.installed 已安装版本
|
||||
@id sort.latest 最新版本
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 4 and column 3.
|
@@ -26,12 +26,11 @@ pub enum Filter {
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum SortKey {
|
||||
/// Suite order: classic apps, then new.
|
||||
/// Suite order: classic apps, then new. Settings saved with the removed "Inspired by" sort load as this.
|
||||
#[default]
|
||||
#[serde(alias = "InspiredBy")]
|
||||
Suite,
|
||||
Name,
|
||||
/// The product an app is inspired by.
|
||||
InspiredBy,
|
||||
Status,
|
||||
/// Installed version.
|
||||
Installed,
|
||||
|
||||
@@ -231,15 +231,7 @@ impl LauncherUi {
|
||||
.selected_text(RichText::new(sort_label(self.settings.sort)).size(13.0))
|
||||
.width(140.0)
|
||||
.show_ui(ui, |ui| {
|
||||
for key in [
|
||||
SortKey::Suite,
|
||||
SortKey::Name,
|
||||
SortKey::InspiredBy,
|
||||
SortKey::Status,
|
||||
SortKey::Installed,
|
||||
SortKey::Latest,
|
||||
SortKey::Released,
|
||||
] {
|
||||
for key in [SortKey::Suite, SortKey::Name, SortKey::Status, SortKey::Installed, SortKey::Latest, SortKey::Released] {
|
||||
if ui.selectable_label(self.settings.sort == key, sort_label(key)).clicked() {
|
||||
self.settings.sort = key;
|
||||
self.settings.sort_descending = key.starts_descending();
|
||||
@@ -425,10 +417,10 @@ impl LauncherUi {
|
||||
let ui = &mut child;
|
||||
ui.horizontal(|ui| {
|
||||
const ICON: f32 = 56.0;
|
||||
let [name, tagline, like] = [FontId::new(22.0, theme::display()), FontId::proportional(13.5), FontId::proportional(12.0)];
|
||||
let [name, tagline] = [FontId::new(22.0, theme::display()), FontId::proportional(13.5)];
|
||||
const GAP: f32 = 4.0;
|
||||
// The slot is as tall as the text beside it when that is taller, so the two share a centre.
|
||||
let block = lines_height(ui, &[&name, &tagline, &like], GAP);
|
||||
let block = lines_height(ui, &[&name, &tagline], GAP);
|
||||
let (slot, icon_response) = ui.allocate_exact_size(vec2(ICON, block.max(ICON)), Sense::hover());
|
||||
icon_response.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Image, true, fmt(tl!("{name} icon"), &[("name", app.name)])));
|
||||
// The icon rises a little on hover, over a soft drop shadow (the site's only shadow).
|
||||
@@ -441,7 +433,7 @@ impl LauncherUi {
|
||||
egui::Image::new(icon).paint_at(ui, icon_rect);
|
||||
}
|
||||
ui.add_space(6.0);
|
||||
centered_lines(ui, &[&name, &tagline, &like], GAP, |ui| {
|
||||
centered_lines(ui, &[&name, &tagline], GAP, |ui| {
|
||||
// The name's row is as tall as its text, not as a button.
|
||||
ui.spacing_mut().interact_size.y = 0.0;
|
||||
ui.horizontal(|ui| {
|
||||
@@ -451,10 +443,6 @@ impl LauncherUi {
|
||||
}
|
||||
});
|
||||
ui.add(egui::Label::new(RichText::new(tr_ctx(current(), app.id, app.tagline)).font(tagline.clone()).color(t.muted)).truncate());
|
||||
ui.add(
|
||||
egui::Label::new(RichText::new(fmt(tl!("Like {name}"), &[("name", &app.inspired_by())])).font(like.clone()).color(t.faint))
|
||||
.truncate(),
|
||||
);
|
||||
});
|
||||
});
|
||||
ui.add_space(14.0);
|
||||
@@ -499,7 +487,6 @@ impl LauncherUi {
|
||||
.vscroll(false)
|
||||
.cell_layout(egui::Layout::left_to_right(egui::Align::Center))
|
||||
.column(Column::remainder().at_least(220.0).clip(true))
|
||||
.column(Column::exact(172.0).clip(true))
|
||||
.column(Column::exact(176.0))
|
||||
.column(Column::exact(84.0))
|
||||
.column(Column::exact(84.0))
|
||||
@@ -508,7 +495,6 @@ impl LauncherUi {
|
||||
.header(42.0, |mut header| {
|
||||
for (key, label) in [
|
||||
(Some(SortKey::Name), tl!("App")),
|
||||
(Some(SortKey::InspiredBy), tl!("Inspired by")),
|
||||
(Some(SortKey::Status), tl!("Status")),
|
||||
(Some(SortKey::Installed), tr_ctx(current(), "column", "Installed")),
|
||||
(Some(SortKey::Latest), tr_ctx(current(), "column", "Latest")),
|
||||
@@ -582,9 +568,6 @@ impl LauncherUi {
|
||||
);
|
||||
});
|
||||
});
|
||||
row.col(|ui| {
|
||||
ui.add(egui::Label::new(RichText::new(entry.app.inspired_by()).size(13.0).color(t.muted)).truncate());
|
||||
});
|
||||
row.col(|ui| {
|
||||
let (text, tone) = model::entry_status_text(&entry, &status, self.caps.manage_apps);
|
||||
let r = widgets::badge(ui, &text, widgets::tone_color(&t, tone));
|
||||
@@ -625,13 +608,6 @@ impl LauncherUi {
|
||||
}
|
||||
}
|
||||
|
||||
/// The trademark notice under the grid and the table.
|
||||
pub(crate) fn trademark_notice(&self, ui: &mut Ui) {
|
||||
let t = Tokens::get(ui.ctx());
|
||||
ui.add_space(8.0);
|
||||
ui.add(egui::Label::new(RichText::new(artcraft_launcher_core::catalog::TRADEMARK_NOTICE).size(11.0).color(t.faint)).wrap());
|
||||
}
|
||||
|
||||
// ---- actions -------------------------------------------------------------------------
|
||||
|
||||
fn primary_action(&self, entry: &AppEntry, status: &AppStatus) -> Primary {
|
||||
@@ -861,7 +837,6 @@ fn sort_label(k: SortKey) -> &'static str {
|
||||
match k {
|
||||
SortKey::Suite => tl!("Suite order"),
|
||||
SortKey::Name => tl!("Name"),
|
||||
SortKey::InspiredBy => tl!("Inspired by"),
|
||||
SortKey::Status => tl!("Status"),
|
||||
SortKey::Installed => tl!("Installed version"),
|
||||
SortKey::Latest => tl!("Latest version"),
|
||||
|
||||
@@ -201,11 +201,9 @@ fn grid_shows_every_status_and_installs_on_click() {
|
||||
h.get_by_label("Update to 0.5.0");
|
||||
h.get_by_label("Update to 0.6.0");
|
||||
h.get_by_label_contains("0.4.1 installed → 0.5.0 released");
|
||||
h.get_by_label("Like Adobe Photoshop®");
|
||||
// The window has no title bar of its own here (the web build, and the tests).
|
||||
assert!(h.query_by_label("Close").is_none());
|
||||
assert!(h.query_all_by_label_contains("Discord").count() >= 2); // header link and footer link
|
||||
h.get_by_label_contains("Adobe, Photoshop, Illustrator");
|
||||
assert!(h.query_all_by_label("Coming soon").count() >= 1);
|
||||
h.get_by_label_contains("48 MB of 131 MB");
|
||||
h.get_by_label("Update all (2)").click();
|
||||
@@ -367,9 +365,6 @@ fn table_view_and_light_theme() {
|
||||
let (mut h, sent) = harness(ViewMode::Table, egui::Theme::Light, true);
|
||||
h.run_steps(8);
|
||||
snapshot(&mut h, "table-light");
|
||||
h.get_by_label("Adobe Photoshop®");
|
||||
h.get_by_label("Microsoft Excel®");
|
||||
h.get_by_label_contains("Avid and Pro Tools are trademarks");
|
||||
h.get_by_label("Update to 0.5.0").click();
|
||||
h.run_steps(2);
|
||||
assert!(sent.borrow().contains(&Command::Install { app: "photocraft".into() }));
|
||||
@@ -411,7 +406,7 @@ fn name_and_tagline_are_centred_on_the_icon() {
|
||||
let (mut h, _) = harness_at(ViewMode::Grid, egui::Theme::Dark, true, scale);
|
||||
h.run_steps(8);
|
||||
snapshot(&mut h, &format!("grid-dark{suffix}"));
|
||||
let off = below_icon_centre(&h, &["PhotoCraft", "Image editing", "Like Adobe Photoshop®"]);
|
||||
let off = below_icon_centre(&h, &["PhotoCraft", "Image editing"]);
|
||||
assert!(off.abs() < 0.25, "grid at {scale}x: {off}");
|
||||
let (mut h, _) = harness_at(ViewMode::Table, egui::Theme::Light, true, scale);
|
||||
h.run_steps(8);
|
||||
@@ -453,11 +448,6 @@ fn every_table_column_sorts_both_ways() {
|
||||
h.run_steps(3);
|
||||
let o = order(&h);
|
||||
assert_eq!(&o[..4], ["WordCraft", "LightCraft", "PhotoCraft", "EffectCraft"], "{o:?}");
|
||||
// Inspired by: A to Z.
|
||||
h.get_by_label("Inspired by").click();
|
||||
h.run_steps(3);
|
||||
let o = order(&h);
|
||||
assert_eq!(o.first().map(String::as_str), Some("PdfCraft"), "{o:?}"); // Adobe Acrobat
|
||||
// Latest: highest version first, SoundCraft (no release) last.
|
||||
h.get_by_label("Latest").click();
|
||||
h.run_steps(3);
|
||||
|
||||
Reference in new issue
Block a user