mirror of
https://github.com/Trensa-Organization/hy3.git
synced 2025-03-15 10:43: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();
|
||||
}
|
||||
|
||||
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) {
|
||||
auto window = pWindow ? pWindow : g_pCompositor->m_pLastWindow;
|
||||
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_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
|
||||
if(corner == CORNER_NONE) { // It's probably a keyboard event.
|
||||
target_edge_x = display_right ? ShiftDirection::Left : ShiftDirection::Right;
|
||||
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
|
||||
// Resize against the edges corresponding to the selected corner
|
||||
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;
|
||||
}
|
||||
|
||||
auto sibling_node_x = node->findSibling(target_edge_x);
|
||||
auto sibling_node_y = node->findSibling(target_edge_y);
|
||||
// Find the neighboring node in each axis, which will be either above or at the
|
||||
// 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) {
|
||||
sibling_node_x->resize(resize_delta.x, target_edge_x);
|
||||
const auto animate =
|
||||
&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) {
|
||||
sibling_node_y->resize(resize_delta.y, target_edge_y);
|
||||
if(vertical_neighbor) {
|
||||
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
|
||||
if(window->m_bIsFloating) {
|
||||
const auto required_size = Vector2D(
|
||||
std::max((window->m_vRealSize.goalv() + delta).x, 20.0),
|
||||
std::max((window->m_vRealSize.goalv() + delta).y, 20.0)
|
||||
);
|
||||
window->m_vRealSize = required_size;
|
||||
}
|
||||
const auto required_size = Vector2D(
|
||||
std::max((window->m_vRealSize.goalv() + delta).x, 20.0),
|
||||
std::max((window->m_vRealSize.goalv() + delta).y, 20.0)
|
||||
);
|
||||
window->m_vRealSize = required_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "Hy3Node.hpp"
|
||||
#include "globals.hpp"
|
||||
|
||||
const float MIN_RATIO = 0.02f;
|
||||
const float MIN_WINDOW_SIZE = 20;
|
||||
|
||||
// Hy3GroupData //
|
||||
|
||||
|
@ -879,7 +879,7 @@ Axis getAxis(ShiftDirection direction) {
|
|||
}
|
||||
}
|
||||
|
||||
Hy3Node* Hy3Node::findSibling(ShiftDirection direction) {
|
||||
Hy3Node* Hy3Node::findNeighbor(ShiftDirection direction) {
|
||||
auto current_node = this;
|
||||
Hy3Node* sibling = nullptr;
|
||||
|
||||
|
@ -901,40 +901,57 @@ Hy3Node* Hy3Node::findSibling(ShiftDirection direction) {
|
|||
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(
|
||||
double resize_delta,
|
||||
ShiftDirection target_edge_x
|
||||
ShiftDirection direction,
|
||||
double delta,
|
||||
bool no_animation
|
||||
) {
|
||||
auto& parent_node = this->parent;
|
||||
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)) {
|
||||
double parent_size = getAxis(target_edge_x) == Axis::Horizontal ? parent_node->size.x
|
||||
if(containing_group.layout != Hy3GroupLayout::Tabbed && getAxis(direction) == getAxis(containing_group.layout)) {
|
||||
double parent_size = getAxis(direction) == Axis::Horizontal ? parent_node->size.x
|
||||
: 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 (this != containing_group.children.back()) {
|
||||
iter = std::next(iter);
|
||||
if(iter != end_of_children) {
|
||||
const auto outermost_node_in_group = getOuterChild(containing_group, direction);
|
||||
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()) {
|
||||
iter = std::prev(iter);
|
||||
ratio_mod = -ratio_mod;
|
||||
|
||||
if(iter != end_of_children) {
|
||||
auto* neighbor = *iter;
|
||||
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 raiseToTop();
|
||||
Hy3Node* getFocusedNode(bool ignore_group_focus = false, bool stop_at_expanded = false);
|
||||
Hy3Node* findSibling(ShiftDirection);
|
||||
Hy3Node* findNeighbor(ShiftDirection);
|
||||
Hy3Node* getImmediateSibling(ShiftDirection);
|
||||
void resize(double, ShiftDirection);
|
||||
void resize(ShiftDirection, double, bool no_animation = false);
|
||||
bool isIndirectlyFocused();
|
||||
Hy3Node& getExpandActor();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue