mirror of
https://github.com/Trensa-Organization/hy3.git
synced 2025-03-15 18:53:40 +01:00
Improve iteration handling and validate results
This commit is contained in:
parent
f3e8d2ff9a
commit
dad1589d21
3 changed files with 81 additions and 42 deletions
|
@ -390,6 +390,17 @@ void Hy3Layout::recalculateWindow(CWindow* window) {
|
||||||
node->recalcSizePosRecursive();
|
node->recalcSizePosRecursive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShiftDirection reverse(ShiftDirection direction) {
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case ShiftDirection::Left: return ShiftDirection::Right;
|
||||||
|
case ShiftDirection::Right: return ShiftDirection::Left;
|
||||||
|
case ShiftDirection::Up: return ShiftDirection::Down;
|
||||||
|
case ShiftDirection::Down: return ShiftDirection::Up;
|
||||||
|
default: return direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CWindow* pWindow) {
|
void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CWindow* pWindow) {
|
||||||
auto window = pWindow ? pWindow : g_pCompositor->m_pLastWindow;
|
auto window = pWindow ? pWindow : g_pCompositor->m_pLastWindow;
|
||||||
if (!g_pCompositor->windowValidMapped(window)) return;
|
if (!g_pCompositor->windowValidMapped(window)) return;
|
||||||
|
@ -421,11 +432,15 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW
|
||||||
ShiftDirection target_edge_x;
|
ShiftDirection target_edge_x;
|
||||||
ShiftDirection target_edge_y;
|
ShiftDirection target_edge_y;
|
||||||
|
|
||||||
// Determine the direction in which we're going to look for the sibling node
|
// Determine the direction in which we're going to look for the neighbor node
|
||||||
// that will be resized
|
// that will be resized
|
||||||
if(corner == CORNER_NONE) { // It's probably a keyboard event.
|
if(corner == CORNER_NONE) { // It's probably a keyboard event.
|
||||||
target_edge_x = display_right ? ShiftDirection::Left : ShiftDirection::Right;
|
target_edge_x = display_right ? ShiftDirection::Left : ShiftDirection::Right;
|
||||||
target_edge_y = display_bottom ? ShiftDirection::Up : ShiftDirection::Down;
|
target_edge_y = display_bottom ? ShiftDirection::Up : ShiftDirection::Down;
|
||||||
|
|
||||||
|
// If the anchor is not at the top/left then reverse the delta
|
||||||
|
if(target_edge_x == ShiftDirection::Left) resize_delta.x = -resize_delta.x;
|
||||||
|
if(target_edge_y == ShiftDirection::Up) resize_delta.y = -resize_delta.y;
|
||||||
} else { // It's probably a mouse event
|
} else { // It's probably a mouse event
|
||||||
// Resize against the edges corresponding to the selected corner
|
// Resize against the edges corresponding to the selected corner
|
||||||
target_edge_x = corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT
|
target_edge_x = corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT
|
||||||
|
@ -434,25 +449,32 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW
|
||||||
? ShiftDirection::Up : ShiftDirection::Down;
|
? ShiftDirection::Up : ShiftDirection::Down;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sibling_node_x = node->findSibling(target_edge_x);
|
// Find the neighboring node in each axis, which will be either above or at the
|
||||||
auto sibling_node_y = node->findSibling(target_edge_y);
|
// same level as the initiating node in the layout hierarchy. These are the nodes
|
||||||
|
// which must get resized (rather than the initiator) because they are the
|
||||||
|
// highest point in the hierarchy
|
||||||
|
auto horizontal_neighbor = node->findNeighbor(target_edge_x);
|
||||||
|
auto vertical_neighbor = node->findNeighbor(target_edge_y);
|
||||||
|
|
||||||
if(sibling_node_x) {
|
const auto animate =
|
||||||
sibling_node_x->resize(resize_delta.x, target_edge_x);
|
&g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue;
|
||||||
|
|
||||||
|
// Note that the resize direction is reversed, because from the neighbor's perspective
|
||||||
|
// the edge to be moved is the opposite way round. However, the delta is still the same.
|
||||||
|
if(horizontal_neighbor) {
|
||||||
|
horizontal_neighbor->resize(reverse(target_edge_x), resize_delta.x, *animate == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sibling_node_y) {
|
if(vertical_neighbor) {
|
||||||
sibling_node_y->resize(resize_delta.y, target_edge_y);
|
vertical_neighbor->resize(reverse(target_edge_y), resize_delta.y, *animate == 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else if(window->m_bIsFloating) {
|
||||||
// No parent node - is this a floating window? If so, use the same logic as the `main` layout
|
// No parent node - is this a floating window? If so, use the same logic as the `main` layout
|
||||||
if(window->m_bIsFloating) {
|
const auto required_size = Vector2D(
|
||||||
const auto required_size = Vector2D(
|
std::max((window->m_vRealSize.goalv() + delta).x, 20.0),
|
||||||
std::max((window->m_vRealSize.goalv() + delta).x, 20.0),
|
std::max((window->m_vRealSize.goalv() + delta).y, 20.0)
|
||||||
std::max((window->m_vRealSize.goalv() + delta).y, 20.0)
|
);
|
||||||
);
|
window->m_vRealSize = required_size;
|
||||||
window->m_vRealSize = required_size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "Hy3Node.hpp"
|
#include "Hy3Node.hpp"
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
|
|
||||||
const float MIN_RATIO = 0.02f;
|
const float MIN_WINDOW_SIZE = 20;
|
||||||
|
|
||||||
// Hy3GroupData //
|
// Hy3GroupData //
|
||||||
|
|
||||||
|
@ -879,7 +879,7 @@ Axis getAxis(ShiftDirection direction) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hy3Node* Hy3Node::findSibling(ShiftDirection direction) {
|
Hy3Node* Hy3Node::findNeighbor(ShiftDirection direction) {
|
||||||
auto current_node = this;
|
auto current_node = this;
|
||||||
Hy3Node* sibling = nullptr;
|
Hy3Node* sibling = nullptr;
|
||||||
|
|
||||||
|
@ -901,40 +901,57 @@ Hy3Node* Hy3Node::findSibling(ShiftDirection direction) {
|
||||||
return sibling;
|
return sibling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int directionToIteratorIncrement(ShiftDirection direction) {
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case ShiftDirection::Left:
|
||||||
|
case ShiftDirection::Up:
|
||||||
|
return -1;
|
||||||
|
case ShiftDirection::Right:
|
||||||
|
case ShiftDirection::Down:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
hy3_log(WARN, "Unknown ShiftDirection enum value: {}", (int)direction);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Hy3Node::resize(
|
void Hy3Node::resize(
|
||||||
double resize_delta,
|
ShiftDirection direction,
|
||||||
ShiftDirection target_edge_x
|
double delta,
|
||||||
|
bool no_animation
|
||||||
) {
|
) {
|
||||||
auto& parent_node = this->parent;
|
auto& parent_node = this->parent;
|
||||||
auto& containing_group = parent_node->data.as_group;
|
auto& containing_group = parent_node->data.as_group;
|
||||||
const auto animate =
|
|
||||||
&g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue;
|
|
||||||
|
|
||||||
if(containing_group.layout != Hy3GroupLayout::Tabbed && getAxis(target_edge_x) == getAxis(containing_group.layout)) {
|
if(containing_group.layout != Hy3GroupLayout::Tabbed && getAxis(direction) == getAxis(containing_group.layout)) {
|
||||||
double parent_size = getAxis(target_edge_x) == Axis::Horizontal ? parent_node->size.x
|
double parent_size = getAxis(direction) == Axis::Horizontal ? parent_node->size.x
|
||||||
: parent_node->size.y;
|
: parent_node->size.y;
|
||||||
auto ratio_mod = resize_delta * (float) containing_group.children.size() / parent_size;
|
auto ratio_mod = delta * (float) containing_group.children.size() / parent_size;
|
||||||
|
|
||||||
auto iter = std::find(containing_group.children.begin(), containing_group.children.end(), this);
|
const auto end_of_children = containing_group.children.end();
|
||||||
|
auto iter = std::find(containing_group.children.begin(), end_of_children, this);
|
||||||
|
|
||||||
if (target_edge_x == ShiftDirection::Left || target_edge_x == ShiftDirection::Up) {
|
if(iter != end_of_children) {
|
||||||
if (this != containing_group.children.back()) {
|
const auto outermost_node_in_group = getOuterChild(containing_group, direction);
|
||||||
iter = std::next(iter);
|
if(this != outermost_node_in_group) {
|
||||||
|
auto inc = directionToIteratorIncrement(direction);
|
||||||
|
iter = std::next(iter, inc);
|
||||||
|
ratio_mod *= inc;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (this != containing_group.children.front()) {
|
if(iter != end_of_children) {
|
||||||
iter = std::prev(iter);
|
auto* neighbor = *iter;
|
||||||
ratio_mod = -ratio_mod;
|
auto requested_size_ratio = this->size_ratio + ratio_mod;
|
||||||
|
auto requested_neighbor_size_ratio = neighbor->size_ratio -ratio_mod;
|
||||||
|
|
||||||
|
if(requested_size_ratio * parent_size >= MIN_WINDOW_SIZE) {
|
||||||
|
this->size_ratio = requested_size_ratio;
|
||||||
|
neighbor->size_ratio = requested_neighbor_size_ratio;
|
||||||
|
parent_node->recalcSizePosRecursive(no_animation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* neighbor = *iter;
|
|
||||||
|
|
||||||
if(this->size_ratio + ratio_mod > MIN_RATIO && neighbor->size_ratio - ratio_mod > MIN_RATIO) {
|
|
||||||
this->size_ratio += ratio_mod;
|
|
||||||
neighbor->size_ratio -= ratio_mod;
|
|
||||||
parent_node->recalcSizePosRecursive(*animate == 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,9 +99,9 @@ struct Hy3Node {
|
||||||
void markFocused();
|
void markFocused();
|
||||||
void raiseToTop();
|
void raiseToTop();
|
||||||
Hy3Node* getFocusedNode(bool ignore_group_focus = false, bool stop_at_expanded = false);
|
Hy3Node* getFocusedNode(bool ignore_group_focus = false, bool stop_at_expanded = false);
|
||||||
Hy3Node* findSibling(ShiftDirection);
|
Hy3Node* findNeighbor(ShiftDirection);
|
||||||
Hy3Node* getImmediateSibling(ShiftDirection);
|
Hy3Node* getImmediateSibling(ShiftDirection);
|
||||||
void resize(double, ShiftDirection);
|
void resize(ShiftDirection, double, bool no_animation = false);
|
||||||
bool isIndirectlyFocused();
|
bool isIndirectlyFocused();
|
||||||
Hy3Node& getExpandActor();
|
Hy3Node& getExpandActor();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue