Skip to content

Commit

Permalink
Introduce BaseItem (#373)
Browse files Browse the repository at this point in the history
  • Loading branch information
lenemter authored Feb 16, 2025
1 parent b91be3b commit 02617cc
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 151 deletions.
1 change: 1 addition & 0 deletions po/POTFILES
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
src/Application.vala
src/BaseItem.vala
src/ItemManager.vala
src/MainWindow.vala
src/AppSystem/App.vala
Expand Down
133 changes: 8 additions & 125 deletions src/AppSystem/Launcher.vala
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
/*
* SPDX-License-Identifier: GPL-3.0
* SPDX-FileCopyrightText: 2022 elementary, Inc. (https://elementary.io)
* SPDX-FileCopyrightText: 2022-2025 elementary, Inc. (https://elementary.io)
*/

public class Dock.Launcher : Gtk.Box {
public class Dock.Launcher : BaseItem {
private const int DND_TIMEOUT = 1000;

private static Settings settings;
private static Settings? notify_settings;

static construct {
settings = new Settings ("io.elementary.dock");

if (SettingsSchemaSource.get_default ().lookup ("io.elementary.notifications", true) != null) {
notify_settings = new Settings ("io.elementary.notifications");
}
}

public signal void removed ();
public signal void revealed_done ();

// Matches icon size and padding in Launcher.css
public const int ICON_SIZE = 48;
public const int PADDING = 6;
Expand All @@ -31,8 +25,6 @@ public class Dock.Launcher : Gtk.Box {

public App app { get; construct; }

public double current_pos { get; set; }

private bool _moving = false;
public bool moving {
get {
Expand All @@ -57,20 +49,12 @@ public class Dock.Launcher : Gtk.Box {
private Gtk.Image image;
private Gtk.Revealer progress_revealer;
private Gtk.Revealer badge_revealer;
private Gtk.Revealer running_revealer;
private Adw.TimedAnimation bounce_up;
private Adw.TimedAnimation bounce_down;
private Adw.TimedAnimation timed_animation;

private Gtk.GestureClick gesture_click;
private Gtk.Overlay overlay;
private Gtk.PopoverMenu popover;

private Binding current_count_binding;

private Adw.TimedAnimation? fade;
private Adw.TimedAnimation? reveal;

private int drag_offset_x = 0;
private int drag_offset_y = 0;

Expand Down Expand Up @@ -119,32 +103,12 @@ public class Dock.Launcher : Gtk.Box {
transition_type = CROSSFADE
};

var running_indicator = new Gtk.Image.from_icon_name ("pager-checked-symbolic");
running_indicator.add_css_class ("running-indicator");

running_revealer = new Gtk.Revealer () {
can_target = false,
child = running_indicator,
overflow = VISIBLE,
transition_type = CROSSFADE,
valign = END
};

overlay = new Gtk.Overlay () {
child = image
};
overlay.child = image;
overlay.add_overlay (badge_revealer);
overlay.add_overlay (progress_revealer);

// Needed to work around DnD bug where it
// would stop working once the button got clicked
append (overlay);
append (running_revealer);
orientation = VERTICAL;
tooltip_text = app.app_info.get_display_name ();

var launcher_manager = ItemManager.get_default ();

insert_action_group (ACTION_GROUP_PREFIX, app.action_group);

// We have to destroy the progressbar when it is not needed otherwise it will
Expand Down Expand Up @@ -194,21 +158,6 @@ public class Dock.Launcher : Gtk.Box {
};
bounce_up.done.connect (bounce_down.play);

var animation_target = new Adw.CallbackAnimationTarget ((val) => {
launcher_manager.move (this, val, 0);
current_pos = val;
});

timed_animation = new Adw.TimedAnimation (
this,
0,
0,
200,
animation_target
) {
easing = EASE_IN_OUT_QUAD
};

var drag_source = new Gtk.DragSource () {
actions = MOVE
};
Expand All @@ -228,10 +177,7 @@ public class Dock.Launcher : Gtk.Box {
add_controller (drop_target);
drop_target.enter.connect (on_drop_enter);

gesture_click = new Gtk.GestureClick () {
button = 0
};
add_controller (gesture_click);
gesture_click.button = 0;
gesture_click.released.connect (on_click_released);

var scroll_controller = new Gtk.EventControllerScroll (VERTICAL);
Expand All @@ -241,7 +187,7 @@ public class Dock.Launcher : Gtk.Box {
return Gdk.EVENT_STOP;
});

settings.bind ("icon-size", image, "pixel-size", DEFAULT);
bind_property ("icon-size", image, "pixel-size", SYNC_CREATE);

app.notify["count-visible"].connect (update_badge_revealer);
update_badge_revealer ();
Expand Down Expand Up @@ -294,26 +240,6 @@ public class Dock.Launcher : Gtk.Box {
add_controller (drop_controller_motion);
drop_controller_motion.enter.connect (queue_dnd_cycle);
drop_controller_motion.leave.connect (remove_dnd_cycle);

fade = new Adw.TimedAnimation (
this, 0, 1,
Granite.TRANSITION_DURATION_OPEN,
new Adw.CallbackAnimationTarget ((val) => {
opacity = val;
})
) {
easing = EASE_IN_OUT_QUAD
};

reveal = new Adw.TimedAnimation (
overlay, image.pixel_size, 0,
Granite.TRANSITION_DURATION_OPEN,
new Adw.CallbackAnimationTarget ((val) => {
overlay.allocate (image.pixel_size, image.pixel_size, -1,
new Gsk.Transform ().translate (Graphene.Point () { y = (float) val }
));
})
);
}

~Launcher () {
Expand All @@ -322,14 +248,12 @@ public class Dock.Launcher : Gtk.Box {
}

/**
* If the launcher isn't needed anymore call this otherwise it won't be freed.
* {@inheritDoc}
*/
public void cleanup () {
timed_animation = null;
public override void cleanup () {
base.cleanup ();
bounce_down = null;
bounce_up = null;
fade = null;
reveal = null;
current_count_binding.unbind ();
remove_dnd_cycle ();
}
Expand Down Expand Up @@ -367,47 +291,6 @@ public class Dock.Launcher : Gtk.Box {
bounce_up.play ();
}

/**
* Makes the launcher animate a move to the given position. Make sure to
* always use this instead of manually calling Gtk.Fixed.move on the manager
* when moving a launcher so that its current_pos is always up to date.
*/
public void animate_move (double new_position) {
timed_animation.value_from = current_pos;
timed_animation.value_to = new_position;

timed_animation.play ();
}

public void set_revealed (bool revealed) {
fade.skip ();
reveal.skip ();

// Avoid a stutter at the beginning
opacity = 0;
// clip launcher to dock size until we finish animating
overflow = HIDDEN;

if (revealed) {
reveal.easing = EASE_OUT_BACK;
} else {
fade.duration = Granite.TRANSITION_DURATION_CLOSE;
fade.reverse = true;

reveal.duration = Granite.TRANSITION_DURATION_CLOSE;
reveal.easing = EASE_IN_OUT_QUAD;
reveal.reverse = true;
}

fade.play ();
reveal.play ();

reveal.done.connect (() => {
overflow = VISIBLE;
revealed_done ();
});
}

private Gdk.ContentProvider? on_drag_prepare (double x, double y) {
drag_offset_x = (int) x;
drag_offset_y = (int) y;
Expand Down
142 changes: 142 additions & 0 deletions src/BaseItem.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* SPDX-License-Identifier: GPL-3.0
* SPDX-FileCopyrightText: 2025 elementary, Inc. (https://elementary.io)
*/

public class Dock.BaseItem : Gtk.Box {
protected static GLib.Settings dock_settings;

static construct {
dock_settings = new GLib.Settings ("io.elementary.dock");
}

public signal void removed ();
public signal void revealed_done ();

public int icon_size { get; set; }
public double current_pos { get; set; }

protected Gtk.Overlay overlay;
protected Gtk.Revealer running_revealer;
protected Gtk.GestureClick gesture_click;

private Adw.TimedAnimation fade;
private Adw.TimedAnimation reveal;
private Adw.TimedAnimation timed_animation;

private BaseItem () {}

construct {
orientation = VERTICAL;

overlay = new Gtk.Overlay ();

var running_indicator = new Gtk.Image.from_icon_name ("pager-checked-symbolic");
running_indicator.add_css_class ("running-indicator");

running_revealer = new Gtk.Revealer () {
can_target = false,
child = running_indicator,
overflow = VISIBLE,
transition_type = CROSSFADE,
valign = END
};

append (overlay);
append (running_revealer);

icon_size = dock_settings.get_int ("icon-size");
dock_settings.changed["icon-size"].connect (() => {
icon_size = dock_settings.get_int ("icon-size");
});

fade = new Adw.TimedAnimation (
this, 0, 1,
Granite.TRANSITION_DURATION_OPEN,
new Adw.CallbackAnimationTarget ((val) => {
opacity = val;
})
) {
easing = EASE_IN_OUT_QUAD
};

reveal = new Adw.TimedAnimation (
overlay, icon_size, 0,
Granite.TRANSITION_DURATION_OPEN,
new Adw.CallbackAnimationTarget ((val) => {
overlay.allocate (icon_size, icon_size, -1,
new Gsk.Transform ().translate (Graphene.Point () { y = (float) val }
));
})
);

unowned var item_manager = ItemManager.get_default ();
var animation_target = new Adw.CallbackAnimationTarget ((val) => {
item_manager.move (this, val, 0);
current_pos = val;
});

timed_animation = new Adw.TimedAnimation (
this,
0,
0,
200,
animation_target
) {
easing = EASE_IN_OUT_QUAD
};

gesture_click = new Gtk.GestureClick ();
add_controller (gesture_click);
}

public void set_revealed (bool revealed) {
fade.skip ();
reveal.skip ();

// Avoid a stutter at the beginning
opacity = 0;
// clip launcher to dock size until we finish animating
overflow = HIDDEN;

if (revealed) {
reveal.easing = EASE_OUT_BACK;
} else {
fade.duration = Granite.TRANSITION_DURATION_CLOSE;
fade.reverse = true;

reveal.duration = Granite.TRANSITION_DURATION_CLOSE;
reveal.easing = EASE_IN_OUT_QUAD;
reveal.reverse = true;
}

fade.play ();
reveal.play ();

reveal.done.connect (() => {
overflow = VISIBLE;
revealed_done ();
});
}

/**
* Makes the launcher animate a move to the given position. Make sure to
* always use this instead of manually calling Gtk.Fixed.move on the manager
* when moving a launcher so that its current_pos is always up to date.
*/
public void animate_move (double new_position) {
timed_animation.value_from = current_pos;
timed_animation.value_to = new_position;

timed_animation.play ();
}

/**
* If the icon group isn't needed anymore call this otherwise it won't be freed.
*/
public virtual void cleanup () {
fade = null;
reveal = null;
timed_animation = null;
}
}
Loading

0 comments on commit 02617cc

Please sign in to comment.