mirror of
https://github.com/Trensa-Organization/hy3.git
synced 2025-03-15 18:53:40 +01:00
Tab removal animation
Requires Hyprland#2389 (tracked in flake)
This commit is contained in:
parent
d78601b5c8
commit
8715516d93
6 changed files with 79 additions and 34 deletions
11
flake.lock
generated
11
flake.lock
generated
|
@ -8,16 +8,17 @@
|
|||
"xdph": "xdph"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1685105343,
|
||||
"narHash": "sha256-ypXKGzTQWJqbHHrPnSHLo4b2vNtfOFyh6sDdNPi7/WQ=",
|
||||
"owner": "hyprwm",
|
||||
"lastModified": 1685317265,
|
||||
"narHash": "sha256-Bv/ksFWpm2RSRCY40pIJddNEn5G3yjLs9NUHbpVDGy0=",
|
||||
"owner": "outfoxxed",
|
||||
"repo": "Hyprland",
|
||||
"rev": "5f4659afef5856c509d53957e62b7f6c38d39f41",
|
||||
"rev": "51441d5b9de13335e5723cdbb78e372ebe36490e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"owner": "outfoxxed",
|
||||
"repo": "Hyprland",
|
||||
"rev": "51441d5b9de13335e5723cdbb78e372ebe36490e",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
inputs = {
|
||||
hyprland.url = "github:hyprwm/Hyprland";
|
||||
#hyprland.url = "github:hyprwm/Hyprland";
|
||||
hyprland.url = "github:outfoxxed/Hyprland?rev=51441d5b9de13335e5723cdbb78e372ebe36490e";
|
||||
};
|
||||
|
||||
outputs = { self, hyprland, ... }: let
|
||||
|
|
|
@ -1523,7 +1523,7 @@ void renderTabs(Hy3Node& node) {
|
|||
auto& group = node.data.as_group;
|
||||
|
||||
if (!group.tab_bar) {
|
||||
group.tab_bar = std::unique_ptr<Hy3TabGroup>(new Hy3TabGroup(node));
|
||||
group.tab_bar = Hy3TabGroup::new_(node);
|
||||
} else {
|
||||
group.tab_bar->updateWithGroup(node);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ struct Hy3GroupData {
|
|||
std::list<Hy3Node*> children;
|
||||
bool group_focused = true;
|
||||
Hy3Node* focused_child = nullptr;
|
||||
std::unique_ptr<Hy3TabGroup> tab_bar;
|
||||
std::shared_ptr<Hy3TabGroup> tab_bar;
|
||||
|
||||
bool hasChild(Hy3Node* child);
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <hyprland/src/Compositor.hpp>
|
||||
#include <cairo/cairo.h>
|
||||
|
||||
Hy3TabBarEntry::Hy3TabBarEntry(Hy3TabBar& tab_bar, Hy3Node& node): tab_bar(tab_bar), node(node) {
|
||||
Hy3TabBarEntry::Hy3TabBarEntry(std::shared_ptr<Hy3TabGroup> tab_group, Hy3Node& node): tab_group(tab_group), node(node) {
|
||||
this->offset.create(AVARTYPE_FLOAT, -1.0f, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), nullptr, AVARDAMAGE_NONE);
|
||||
this->width.create(AVARTYPE_FLOAT, -1.0f, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), nullptr, AVARDAMAGE_NONE);
|
||||
|
||||
|
@ -20,6 +20,10 @@ bool Hy3TabBarEntry::operator==(const Hy3Node& node) const {
|
|||
return this->node == node;
|
||||
}
|
||||
|
||||
bool Hy3TabBarEntry::operator==(const Hy3TabBarEntry& entry) const {
|
||||
return this->node == entry.node;
|
||||
}
|
||||
|
||||
void Hy3TabBarEntry::prepareTexture(float scale, Vector2D size) {
|
||||
static const auto* rounding_setting = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:rounding")->intValue;
|
||||
|
||||
|
@ -91,6 +95,16 @@ void Hy3TabBarEntry::prepareTexture(float scale, Vector2D size) {
|
|||
}
|
||||
}
|
||||
|
||||
void Hy3TabBarEntry::animateRemoval() {
|
||||
if (this->width.goalf() == 0.0) return;
|
||||
this->width = 0.0;
|
||||
|
||||
// not removing the callback is required for soundness, as the animation will
|
||||
// be deleted once the callback ends.
|
||||
this->width.setCallbackOnEnd([this](void*) {
|
||||
this->tab_group->bar.entries.remove(*this);
|
||||
}, false);
|
||||
}
|
||||
|
||||
Hy3TabBar::Hy3TabBar() {
|
||||
this->vertical_pos.create(AVARTYPE_FLOAT, 1.0f, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), nullptr, AVARDAMAGE_NONE);
|
||||
|
@ -123,7 +137,7 @@ void Hy3TabBar::focusNode(Hy3Node* node) {
|
|||
}
|
||||
|
||||
void Hy3TabBar::updateNodeList(std::list<Hy3Node*>& nodes) {
|
||||
std::list<Hy3TabBarEntry> removed_entries;
|
||||
std::list<std::list<Hy3TabBarEntry>::iterator> removed_entries;
|
||||
|
||||
auto entry = this->entries.begin();
|
||||
auto node = nodes.begin();
|
||||
|
@ -133,7 +147,8 @@ void Hy3TabBar::updateNodeList(std::list<Hy3Node*>& nodes) {
|
|||
while (true) {
|
||||
if (entry == this->entries.end()) goto exitloop;
|
||||
if (*entry == **node) break;
|
||||
removed_entries.splice(removed_entries.end(), this->entries, entry++);
|
||||
removed_entries.push_back(entry);
|
||||
entry = std::next(entry);
|
||||
}
|
||||
|
||||
node = std::next(node);
|
||||
|
@ -143,7 +158,10 @@ void Hy3TabBar::updateNodeList(std::list<Hy3Node*>& nodes) {
|
|||
exitloop:
|
||||
|
||||
// move any extra entries to removed_entries
|
||||
removed_entries.splice(removed_entries.end(), this->entries, entry, this->entries.end());
|
||||
while (entry != this->entries.end()) {
|
||||
removed_entries.push_back(entry);
|
||||
entry = std::next(entry);
|
||||
}
|
||||
|
||||
entry = this->entries.begin();
|
||||
node = nodes.begin();
|
||||
|
@ -151,13 +169,24 @@ void Hy3TabBar::updateNodeList(std::list<Hy3Node*>& nodes) {
|
|||
// add missing entries, taking first from removed_entries
|
||||
while (node != nodes.end()) {
|
||||
if (entry == this->entries.end() || *entry != **node) {
|
||||
auto moved = std::find(removed_entries.begin(), removed_entries.end(), **node);
|
||||
if (moved != removed_entries.end()) {
|
||||
this->entries.splice(entry, removed_entries, moved);
|
||||
entry = moved;
|
||||
} else {
|
||||
entry = this->entries.emplace(entry, *this, **node);
|
||||
if (std::find(removed_entries.begin(), removed_entries.end(), entry) != removed_entries.end()) {
|
||||
entry = std::next(entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto moved = std::find_if(removed_entries.begin(), removed_entries.end(), [&node](auto entry) { return **node == *entry; });
|
||||
if (moved != removed_entries.end()) {
|
||||
this->entries.splice(entry, this->entries, *moved);
|
||||
entry = *moved;
|
||||
removed_entries.erase(moved);
|
||||
} else {
|
||||
entry = this->entries.emplace(entry, this->group.lock(), **node);
|
||||
}
|
||||
}
|
||||
|
||||
if (entry->width.goalf() == 0.0) {
|
||||
entry->width.setCallbackOnEnd(nullptr);
|
||||
entry->width = -1.0;
|
||||
}
|
||||
|
||||
// set stats from node data
|
||||
|
@ -173,8 +202,7 @@ void Hy3TabBar::updateNodeList(std::list<Hy3Node*>& nodes) {
|
|||
|
||||
// initiate remove animations for any removed entries
|
||||
for (auto& entry: removed_entries) {
|
||||
// TODO: working entry remove anim
|
||||
entry.width = 0.0;
|
||||
entry->animateRemoval();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,10 +238,10 @@ void Hy3TabBar::updateAnimations(bool warp) {
|
|||
}
|
||||
|
||||
if (entry->offset.goalf() != offset) entry->offset = offset;
|
||||
if (entry->width.goalf() != entry_width) entry->width = entry_width;
|
||||
if ((warp_init || entry->width.goalf() != 0.0) && entry->width.goalf() != entry_width) entry->width = entry_width;
|
||||
}
|
||||
|
||||
offset += entry_width;
|
||||
offset += entry->width.goalf();
|
||||
entry = std::next(entry);
|
||||
}
|
||||
}
|
||||
|
@ -223,17 +251,24 @@ void Hy3TabBar::setSize(Vector2D size) {
|
|||
this->size = size;
|
||||
}
|
||||
|
||||
Hy3TabGroup::Hy3TabGroup(Hy3Node& node) {
|
||||
Hy3TabGroup::Hy3TabGroup() {
|
||||
this->pos.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), nullptr, AVARDAMAGE_NONE);
|
||||
this->size.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), nullptr, AVARDAMAGE_NONE);
|
||||
Debug::log(LOG, "registered anims");
|
||||
this->pos.registerVar();
|
||||
this->size.registerVar();
|
||||
}
|
||||
|
||||
this->updateWithGroup(node);
|
||||
this->bar.updateAnimations(true);
|
||||
this->pos.warp();
|
||||
this->size.warp();
|
||||
std::shared_ptr<Hy3TabGroup> Hy3TabGroup::new_(Hy3Node& node) {
|
||||
auto ptr = std::shared_ptr<Hy3TabGroup>(new Hy3TabGroup());
|
||||
ptr->self = ptr;
|
||||
ptr->bar.group = ptr;
|
||||
|
||||
ptr->updateWithGroup(node);
|
||||
ptr->bar.updateAnimations(true);
|
||||
ptr->pos.warp();
|
||||
ptr->size.warp();
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void Hy3TabGroup::updateWithGroup(Hy3Node& node) {
|
||||
|
@ -291,7 +326,7 @@ void Hy3TabGroup::renderTabBar() {
|
|||
wlr_box window_box = { wpos.x, wpos.y, wsize.x, wsize.y };
|
||||
scaleBox(&window_box, scale);
|
||||
|
||||
g_pHyprOpenGL->renderRect(&window_box, CColor(0, 0, 0, 0), *window_rounding);
|
||||
if (window_box.width > 0 && window_box.height > 0) g_pHyprOpenGL->renderRect(&window_box, CColor(0, 0, 0, 0), *window_rounding);
|
||||
}
|
||||
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <hyprland/src/helpers/AnimatedVariable.hpp>
|
||||
#include <hyprland/src/helpers/Vector2D.hpp>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class Hy3TabGroup;
|
||||
|
@ -19,16 +20,19 @@ struct Hy3TabBarEntry {
|
|||
CTexture texture;
|
||||
CAnimatedVariable offset; // offset 0, 0.0-1.0 of total bar
|
||||
CAnimatedVariable width; // 0.0-1.0 of total bar
|
||||
Hy3TabBar& tab_bar;
|
||||
std::shared_ptr<Hy3TabGroup> tab_group;
|
||||
Hy3Node& node; // only used for comparioson. do not deref.
|
||||
Vector2D last_render_size;
|
||||
float last_render_scale = 0.0;
|
||||
float last_render_rounding = 0.0;
|
||||
|
||||
Hy3TabBarEntry(Hy3TabBar&, Hy3Node&);
|
||||
bool operator==(const Hy3Node& node) const;
|
||||
Hy3TabBarEntry(std::shared_ptr<Hy3TabGroup>, Hy3Node&);
|
||||
bool operator==(const Hy3Node&) const;
|
||||
bool operator==(const Hy3TabBarEntry&) const;
|
||||
|
||||
void prepareTexture(float scale, Vector2D size);
|
||||
void prepareTexture(float, Vector2D);
|
||||
|
||||
void animateRemoval();
|
||||
};
|
||||
|
||||
class Hy3TabBar {
|
||||
|
@ -44,6 +48,7 @@ public:
|
|||
void setSize(Vector2D);
|
||||
|
||||
std::list<Hy3TabBarEntry> entries;
|
||||
std::weak_ptr<Hy3TabGroup> group;
|
||||
private:
|
||||
Hy3Node* focused_node = nullptr;
|
||||
CAnimatedVariable focus_opacity;
|
||||
|
@ -60,7 +65,7 @@ public:
|
|||
CAnimatedVariable size;
|
||||
|
||||
// initialize a group with the given node. UB if node is not a group.
|
||||
Hy3TabGroup(Hy3Node&);
|
||||
static std::shared_ptr<Hy3TabGroup> new_(Hy3Node&);
|
||||
|
||||
// update tab bar with node position and data. UB if node is not a group.
|
||||
void updateWithGroup(Hy3Node&);
|
||||
|
@ -68,8 +73,11 @@ public:
|
|||
void renderTabBar();
|
||||
|
||||
private:
|
||||
std::weak_ptr<Hy3TabGroup> self;
|
||||
std::vector<CWindow*> stencil_windows;
|
||||
|
||||
Hy3TabGroup();
|
||||
|
||||
// moving a Hy3TabGroup will unregister any active animations
|
||||
Hy3TabGroup(Hy3TabGroup&&) = delete;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue