Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 27 additions & 36 deletions Exy-panel/src/components/tray.vala
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,18 @@ public class Tray {
private int screen_width;

private ITray[] trays;
private int base_width;

private int width;
private int height;
private int x;
private int y;
private bool hovered;

private Transition expand_animation;

public Tray(Context ctx, int screen_width){
this.ctx = ctx;
this.screen_width = screen_width;
this.y = TRAY_Y;
this.height = TRAY_HEIGHT;

//calc width
var wifi = new WifiTray();
var battery = new BatteryTray();
var clock = new Clock(ctx);
Expand All @@ -50,22 +45,8 @@ public class Tray {
trays += clock;
trays += exit;

foreach(var t in trays)
base_width += t.get_width();

base_width+=4*SPACING;
width = base_width;

//calc x's
this.x = screen_width - width - MARGIN_RIGHT;

var current_x = this.x + SPACING;
foreach (var tray in trays){
tray.set_position(current_x, TRAY_Y);
current_x += tray.get_width() + SPACING;
}

expand_animation = new TransitionEmpty();
// Initial layout (recalculate() will keep it up to date every frame).
recalculate();
}


Expand Down Expand Up @@ -102,31 +83,41 @@ public class Tray {
}

private void expand(){
expand_animation = new Transition1D(0, &width, 400, 1d);
var height_animation = new Transition1D(1, &height, TRAY_MAX_HEIGHT, 1d);
animations.add(expand_animation);
animations.add(height_animation);
animations.add(new Transition1D(1, &height, TRAY_MAX_HEIGHT, 1d));
}

private void contract(){
expand_animation = new Transition1D(0, &width, base_width, 1d);
var height_animation = new Transition1D(1, &height, TRAY_HEIGHT, 1d);
animations.add(expand_animation);
animations.add(height_animation);
animations.add(new Transition1D(1, &height, TRAY_HEIGHT, 1d));
}

public void on_mouse_leave(){
if(width > base_width){
contract();
}
contract();
redraw = true;
}

public void render(){
if(!expand_animation.finished){
this.x = screen_width - width - MARGIN_RIGHT;
this.y = HEIGHT - height - MARGIN_TOP;
// Recompute total width from current item widths and reposition all items.
// Called every render frame so item expansion and contraction are reflected instantly.
private void recalculate(){
int total = 0;
foreach(var t in trays)
total += t.get_width();
total += trays.length * SPACING;
width = total;

// Right-align the tray; left edge moves left as items expand.
x = screen_width - width - MARGIN_RIGHT;
// Tray container top; icons are always pinned to TRAY_Y.
y = HEIGHT - height - MARGIN_TOP;

var current_x = x + SPACING;
foreach(var t in trays){
t.set_position(current_x, TRAY_Y);
current_x += t.get_width() + SPACING;
}
}

public void render(){
recalculate();

ctx.draw_rect_rounded(this.x, this.y, width, height, 24, {0.15f,0.15f,0.15f,1});
foreach(var t in trays){
Expand Down
24 changes: 16 additions & 8 deletions Exy-panel/src/components/trays/battery.vala
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,31 @@ voltage_now, current_now → detailed info */

public class BatteryTray : TrayIcon {

private int bat_percent = -1;
private string bat_status_str = "";

public BatteryTray() {
base ("nobattery");
status();
}

public override void mouse_down(){
}
public override void mouse_up(){

protected override string get_detail_text() {
if(bat_percent < 0) return "";
return "%d%% (%s)".printf(bat_percent, bat_status_str);
}

private async void status(){
var status = exec("cat /sys/class/power_supply/BAT0/status");
var st = exec("cat /sys/class/power_supply/BAT0/status");

var new_icon = "nobattery";
if(status == "discharging" || status.contains("full")){
if(st == "discharging" || st.contains("full")){

var full = exec_int("cat /sys/class/power_supply/BAT0/charge_full");
var current = exec_int("cat /sys/class/power_supply/BAT0/charge_now");

var percent = (current/(float)full)*100;
bat_percent = (int)percent;
bat_status_str = st.contains("full") ? "Full" : "Discharging";
print("Battery: %f\n", percent);

if(percent >= 70)
Expand All @@ -38,10 +42,14 @@ public class BatteryTray : TrayIcon {
else
new_icon = "mid";

} else if (status == "charging"){
} else if (st == "charging"){
new_icon = "charging";
bat_status_str = "Charging";
var full = exec_int("cat /sys/class/power_supply/BAT0/charge_full");
var current = exec_int("cat /sys/class/power_supply/BAT0/charge_now");
bat_percent = (int)((current/(float)full)*100);
} else {
print("battery: status unknown: >%s<\n", status);
print("battery: status unknown: >%s<\n", st);
return;
}

Expand Down
114 changes: 108 additions & 6 deletions Exy-panel/src/components/trays/exit.vala
Original file line number Diff line number Diff line change
@@ -1,15 +1,117 @@

public class ExitTray : TrayIcon {

// Wider slot to fit two labelled option buttons side-by-side.
private const int EXIT_EXPANDED_WIDTH = 260;
// Pixel offset where the option area begins (past the icon + a small gap).
private const int OPT_OFFSET = ICON_SIZE + 8;

// Which option area the cursor is currently over: 0=none, 1=Close App, 2=Shutdown
private int option_hovered = 0;

public ExitTray() {
base ("close");
base("close");
}

protected override int get_expanded_width() {
return EXIT_EXPANDED_WIDTH;
}

// Non-empty return enables the base expand mechanics; the actual content is
// rendered by our render() override, so this text is never drawn directly.
protected override string get_detail_text() {
return "exit";
}

public override void mouse_down(){
if(base.hovered)
Process.spawn_command_line_async("pkill wayfire");
public override void mouse_motion(int mouse_x, int mouse_y) {
base.mouse_motion(mouse_x, mouse_y);

int prev = option_hovered;
option_hovered = 0;

// Track which option button the cursor is over while the slot is open.
if (expanded && current_width > COLLAPSED_WIDTH + MIN_EXPAND_THRESHOLD) {
int opt_start = render_x + OPT_OFFSET;
int opt_total = current_width - OPT_OFFSET;
int half = opt_total / 2;

if (mouse_x >= opt_start && mouse_x < opt_start + half)
option_hovered = 1;
else if (mouse_x >= opt_start + half && mouse_x < render_x + current_width)
option_hovered = 2;
}

if (option_hovered != prev)
redraw = true;
}
public override void mouse_up(){

public override void mouse_down() {
if (!expanded) {
// Expand on icon click.
if (hovered) {
expanded = true;
animations.add(new Transition1D(anim_id, &current_width, EXIT_EXPANDED_WIDTH, 0.4));
redraw = true;
}
} else {
if (option_hovered == 1) {
// Close the currently focused application.
try {
Process.spawn_command_line_async("wlrctl window focus kill");
} catch (Error e) {
warning("ExitTray: close app failed: %s", e.message);
}
collapse();
} else if (option_hovered == 2) {
// Shut down the system.
try {
Process.spawn_command_line_async("systemctl poweroff");
} catch (Error e) {
warning("ExitTray: shutdown failed: %s", e.message);
}
} else if (hovered) {
// Clicking the icon while expanded collapses the prompt.
collapse();
}
}
}

public override void mouse_up() {}

private void collapse() {
expanded = false;
option_hovered = 0;
animations.add(new Transition1D(anim_id, &current_width, COLLAPSED_WIDTH, 0.4));
redraw = true;
}

public override void render(Context ctx) {
render_icon(ctx);

if (current_width > COLLAPSED_WIDTH + MIN_EXPAND_THRESHOLD) {
float progress = float.min(
(float)(current_width - COLLAPSED_WIDTH) / (float)(EXIT_EXPANDED_WIDTH - COLLAPSED_WIDTH),
1.0f);

int opt_start = render_x + OPT_OFFSET;
int opt_total = current_width - OPT_OFFSET;
int half = opt_total / 2;
int btn_h = ICON_SIZE + 4;
int text_y = render_y + ICON_SIZE / 2 + 4;

// Option hover highlight backgrounds.
if (option_hovered == 1) {
ctx.draw_rect_rounded(opt_start, render_y - 2, half, btn_h, 8,
{0.3f, 0.3f, 0.3f, progress});
}
if (option_hovered == 2) {
ctx.draw_rect_rounded(opt_start + half, render_y - 2, half, btn_h, 8,
{0.65f, 0.12f, 0.12f, progress});
}

// Centred labels for each option.
ctx.draw_text("Close App", opt_start + half / 2, text_y, 13, {1, 1, 1, progress});
ctx.draw_text("Shutdown", opt_start + half + half / 2, text_y, 13, {1, 1, 1, progress});
}
}
}
}
Loading