feat: Added example

This commit is contained in:
Byson94
2025-08-06 20:26:34 +05:30
parent 3de7da96af
commit a7f6929186
7 changed files with 217 additions and 109 deletions

View File

@@ -322,19 +322,13 @@ impl<B: DisplayBackend> App<B> {
let initiator = WindowInitiator::new(&window_def, window_args)?;
// TODO replace this
// let root_widget = crate::widgets::build_widget::build_gtk_widget(
// &mut self.scope_graph.borrow_mut(),
// Rc::new(self.ewwii_config.get_widget_definitions().clone()),
// window_scope,
// window_def.widget,
// None,
// )?;
let root_widget = build_gtk_widget(WidgetInput::Window(window_def))?;
root_widget.style_context().add_class(window_name);
println!("Root widget type: {}", root_widget.widget_name());
println!("Style classes: {:?}", root_widget.style_context().list_classes());
let monitor = get_gdk_monitor(initiator.monitor.clone())?;
let mut ewwii_window = initialize_window::<B>(&initiator, monitor, root_widget)?;
ewwii_window.gtk_window.style_context().add_class(window_name);
@@ -513,6 +507,16 @@ fn initialize_window<B: DisplayBackend>(
window.connect_screen_changed(on_screen_changed);
// crate container that will be replaced on rerender
// !FIXME
// The following is the layout of ewwii. Due to the usage of a container during creation,
// the css styling has an issue where it doesnt apply correctly.
// I have to removing it and add a smarter system to update the gtk widgets
// instead of relying on replacing a container every time which resets the state.
// GtkWindow
// └── GtkBox (vertical)
// └── GtkBox (centerbox for example, with window_name as class)
let container = gtk::Box::new(gtk::Orientation::Vertical, 0);
container.set_hexpand(true);
container.set_vexpand(true);

View File

@@ -640,8 +640,8 @@ pub(super) fn build_gtk_button(props: Map) -> Result<gtk::Button> {
})
);
if let Ok(button_text) = get_string_prop(&props, "text", None) {
gtk_widget.set_label(&button_text);
if let Ok(button_label) = get_string_prop(&props, "label", None) {
gtk_widget.set_label(&button_label);
}
Ok(gtk_widget)

View File

@@ -26,30 +26,37 @@ pub fn extract_poll_and_listen_vars(code: &str) -> Result<Vec<(String, Option<St
pub fn extract_poll_listen_exprs(code: &str) -> Vec<String> {
let mut exprs = Vec::new();
let mut i = 0;
let chars: Vec<_> = code.chars().collect();
let code_bytes = code.as_bytes();
let len = code.len();
while i < chars.len() {
while i < len {
if code[i..].starts_with("poll(") || code[i..].starts_with("listen(") {
let start = i;
let mut depth = 0;
let mut j = i;
while i < chars.len() {
if chars[i] == '(' {
depth += 1;
} else if chars[i] == ')' {
depth -= 1;
if depth == 0 {
i += 1;
break;
while j < len {
match code.as_bytes()[j] as char {
'(' => depth += 1,
')' => {
depth -= 1;
if depth == 0 {
j += 1;
break;
}
}
_ => {}
}
i += 1;
j += 1;
}
let end = i;
exprs.push(code[start..end].to_string());
let end = j;
if let Some(expr) = code.get(start..end) {
exprs.push(expr.to_string());
}
i = j;
} else {
i += 1;
i += code[i..].chars().next().unwrap().len_utf8();
}
}

View File

@@ -1,43 +0,0 @@
* {
all: unset; // Unsets everything so you can style everything from scratch
}
// Global Styles
.bar {
background-color: #3a3a3a;
color: #b0b4bc;
padding: 10px;
}
// Styles on classes (see eww.yuck for more information)
.sidestuff slider {
all: unset;
color: #ffd5cd;
}
.metric scale trough highlight {
all: unset;
background-color: #D35D6E;
color: #000000;
border-radius: 10px;
}
.metric scale trough {
all: unset;
background-color: #4e4e4e;
border-radius: 50px;
min-height: 3px;
min-width: 50px;
margin-left: 10px;
margin-right: 20px;
}
.label-ram {
font-size: large;
}
.workspaces button:hover {
color: #D35D6E;
}

View File

@@ -1,49 +1,102 @@
fn separator() {
return box(#{
class: "separator",
width: "1px",
height: "20px",
background_color: "#888",
margin: "0 8px"
}, []);
fn bar(music, time, volume) {
return centerbox(#{ orientation: "h" }, [workspaces(), music(music), sidestuff(volume, time)]);
}
fn widget1() {
return box(#{
class: "widget1",
orientation: "h",
space_evenly: false,
halign: "start",
spacing: 5
}, [
button(#{ onclick: "print('Hello there!')", text: "greet" }),
separator(),
button(#{ onclick: "print('Bye bye!')", text: "say bye" })
]);
fn sidestuff(volume, time) {
return box(#{ class: "sidestuff", orientation: "h", space_evenly: false, halign: "end"}, [
metric(#{
label: "🔊",
value: volume,
onchange: "amixer -D pulse sset Master {}%",
}),
label(#{ text: time })
]);
}
fn window_body() {
return centerbox(#{ orientation: "h" }, [
widget1(),
box(#{},[]),
box(#{},[]),
]);
fn workspaces() {
return box(#{
class: "workspaces",
orientation: "h",
space_evenly: true,
halign: "start",
spacing: 10,
}, [
button(#{ onclick: "wmctrl -s 0", label: "1" }),
button(#{ onclick: "wmctrl -s 1", label: "2" }),
button(#{ onclick: "wmctrl -s 1", label: "3" }),
button(#{ onclick: "wmctrl -s 3", label: "4" }),
button(#{ onclick: "wmctrl -s 4", label: "5" }),
button(#{ onclick: "wmctrl -s 5", label: "6" }),
button(#{ onclick: "wmctrl -s 6", label: "7" }),
button(#{ onclick: "wmctrl -s 7", label: "8" }),
button(#{ onclick: "wmctrl -s 8", label: "9" }),
]);
}
fn music(music) {
let label_text = if music != "" {
"🎵" + music
} else {
""
};
return box(#{
class: "music",
orientation: "h",
space_evenly: false,
halign: "center"
}, [
label(#{ text: label_text }),
]);
}
fn metric(props) {
let label_prop = props.label;
let value_prop = props.value;
let onchange_prop = props.onchange;
return box(#{
orientation: "h",
class: "metric",
space_evenly: false,
}, [
slider(#{
min: 0,
max: 101,
active: onchange_prop != "",
value: value_prop,
onchange: onchange_prop,
}),
]);
}
enter([
poll("cpu_usage", #{
interval: "1s",
cmd: "./test.sh",
initial: "initial"
}),
listen("net_speed", #{
signal: "./test.sh"
}),
listen("music", #{
initial: "",
cmd: "playerctl --follow metadata --format '{{ artist }} - {{ title }}' || true"
}),
defwindow("main_window", #{
monitor: 0,
windowtype: "dock",
geometry: #{ x: "0px", y: "0px", width: "30px", height: "30px" },
reserve: #{ top: "30", distance: "30" }
}, window_body())
]);
poll("volume", #{
interval: "1s",
cmd: "scripts/getvol",
initial: ""
}),
poll("time", #{
interval: "10s",
cmd: "date '+%H:%M %b %d, %Y'",
initial: ""
}),
defwindow("bar", #{
monitor: 0,
windowtype: "dock",
geometry: #{
x: "0%",
y: "0%",
width: "90%",
height: "10px",
anchor: "top center",
},
reserve: #{ side: "top", distance: "4%" }
}, bar(music, time, volume)),
])

View File

@@ -0,0 +1,38 @@
* {
all: unset; // Unsets everything so you can style everything from scratch
}
// Global Styles
.bar {
background-color: #3a3a3a;
color: #b0b4bc;
padding: 10px;
}
// Styles on classes (see ewwii.rhai for more information)
.sidestuff slider {
all: unset;
color: #ffd5cd;
}
.metric scale trough highlight {
all: unset;
background-color: #d35d6e;
color: #000000;
border-radius: 10px;
}
.metric scale trough {
all: unset;
background-color: #4e4e4e;
border-radius: 50px;
min-height: 3px;
min-width: 50px;
margin-left: 10px;
margin-right: 20px;
}
.workspaces button:hover {
color: #d35d6e;
}

View File

@@ -0,0 +1,49 @@
fn separator() {
return box(#{
class: "separator",
width: "1px",
height: "20px",
background_color: "#888",
margin: "0 8px"
}, []);
}
fn widget1() {
return box(#{
class: "widget1",
orientation: "h",
space_evenly: false,
halign: "start",
spacing: 5
}, [
button(#{ onclick: "print('Hello there!')", text: "greet" }),
separator(),
button(#{ onclick: "print('Bye bye!')", text: "say bye" })
]);
}
fn window_body() {
return centerbox(#{ orientation: "h" }, [
widget1(),
box(#{},[]),
box(#{},[]),
]);
}
enter([
poll("cpu_usage", #{
interval: "1s",
cmd: "./test.sh",
initial: "initial"
}),
listen("net_speed", #{
signal: "./test.sh"
}),
defwindow("main_window", #{
monitor: 0,
windowtype: "dock",
geometry: #{ x: "0px", y: "0px", width: "30px", height: "30px" },
reserve: #{ top: "30", distance: "30" }
}, window_body())
]);