plugin_view/
plugin_view.rs1use std::path::PathBuf;
2
3use maruzzella::{
4 default_product_spec, plugin_tab, run, ButtonAppearance, ButtonStyle, MaruzzellaConfig,
5 SurfaceAppearance, SurfaceLevel, TabGroupSpec, TabStripAppearance, TabStripStyle, TextRole,
6 ThemeSpec, Tone, WorkbenchNodeSpec,
7};
8
9fn main() {
10 let plugin_path = example_plugin_path();
11 if !plugin_path.exists() {
12 eprintln!(
13 "example plugin not found at {}\nbuild it first with: cargo build -p example_plugin",
14 plugin_path.display()
15 );
16 return;
17 }
18
19 let mut product = default_product_spec();
20 product.branding.title = "Plugin View Demo".to_string();
21 product.branding.search_placeholder = "Search plugin demo".to_string();
22 product.branding.status_text = "Plugin-backed GTK view with semantic shell styling".to_string();
23
24 product.layout.workbench = WorkbenchNodeSpec::Group(
25 TabGroupSpec::new(
26 "workbench-plugin-demo",
27 Some("plugin-welcome"),
28 vec![
29 plugin_tab(
30 "plugin-welcome",
31 "workbench-plugin-demo",
32 "Plugin Welcome",
33 "com.example.hello.welcome",
34 "The example plugin view could not be created.",
35 false,
36 ),
37 maruzzella::text_tab(
38 "notes",
39 "workbench-plugin-demo",
40 "Notes",
41 "This second tab remains host-owned placeholder content.",
42 true,
43 ),
44 ],
45 )
46 .with_panel_appearance("demo-workbench")
47 .with_panel_header_appearance("demo-header")
48 .with_tab_strip_appearance("demo-tabs"),
49 );
50
51 let config = MaruzzellaConfig::new("com.example.maruzzella.plugin-view")
52 .with_persistence_id("plugin-view-demo")
53 .with_theme(plugin_demo_theme())
54 .with_product(product)
55 .with_plugin_path(plugin_path);
56
57 run(config);
58}
59
60fn example_plugin_path() -> PathBuf {
61 let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
62 path.push("target");
63 path.push("debug");
64 path.push(format!(
65 "{}example_plugin{}",
66 std::env::consts::DLL_PREFIX,
67 std::env::consts::DLL_SUFFIX
68 ));
69 path
70}
71
72fn plugin_demo_theme() -> ThemeSpec {
73 let mut theme = ThemeSpec::default();
74 theme.typography.font_family = "\"Space Grotesk\", \"Noto Sans\", sans-serif".to_string();
75 theme.typography.mono_font_family = "\"JetBrains Mono\", monospace".to_string();
76 theme.palette.bg_0 = "#0f1318".to_string();
77 theme.palette.bg_1 = "#18202a".to_string();
78 theme.palette.workbench = "#0c1015".to_string();
79 theme.palette.panel_left = "#131920".to_string();
80 theme.palette.panel_right = "#131a22".to_string();
81 theme.palette.panel_bottom = "#0a0d12".to_string();
82 theme.palette.border = "#27303c".to_string();
83 theme.palette.border_strong = "#3d4959".to_string();
84 theme.palette.text_0 = "#e3edf7".to_string();
85 theme.palette.text_1 = "#acb9c8".to_string();
86 theme.palette.text_2 = "#738197".to_string();
87 theme.palette.accent = "#36c2a3".to_string();
88 theme.palette.accent_strong = "#72f0cf".to_string();
89 theme.density.radius_medium = 10;
90 theme.density.radius_large = 14;
91 theme.density.toolbar_height = 42;
92 theme.density.tab_height = 30;
93
94 theme
95 .with_surface_appearance(
96 "topbar",
97 SurfaceAppearance::new(Tone::Primary, SurfaceLevel::Flat, TextRole::BodyStrong),
98 )
99 .with_surface_appearance(
100 "toolbar",
101 SurfaceAppearance::new(Tone::Primary, SurfaceLevel::Raised, TextRole::Body),
102 )
103 .with_surface_appearance(
104 "demo-workbench",
105 SurfaceAppearance::new(Tone::Neutral, SurfaceLevel::Sunken, TextRole::Body)
106 .borderless(),
107 )
108 .with_surface_appearance(
109 "demo-header",
110 SurfaceAppearance::new(Tone::Secondary, SurfaceLevel::Flat, TextRole::SectionLabel),
111 )
112 .with_button_appearance(
113 "primary",
114 ButtonAppearance::new(Tone::Accent, ButtonStyle::Solid, TextRole::BodyStrong),
115 )
116 .with_button_appearance(
117 "ghost",
118 ButtonAppearance::new(Tone::Secondary, ButtonStyle::Ghost, TextRole::Body),
119 )
120 .with_tab_strip_appearance(
121 "demo-tabs",
122 TabStripAppearance::new(Tone::Secondary, TabStripStyle::Editor, TextRole::TabLabel),
123 )
124}