Propagate selection to visible descendant nodes when a move drag is started with folder selected.
This commit is contained in:
parent
dee0cb0380
commit
59ea55ef3d
|
@ -1363,7 +1363,8 @@ struct treeview_selection_walk_data {
|
||||||
TREEVIEW_WALK_CLEAR_SELECTION,
|
TREEVIEW_WALK_CLEAR_SELECTION,
|
||||||
TREEVIEW_WALK_SELECT_ALL,
|
TREEVIEW_WALK_SELECT_ALL,
|
||||||
TREEVIEW_WALK_COMMIT_SELECT_DRAG,
|
TREEVIEW_WALK_COMMIT_SELECT_DRAG,
|
||||||
TREEVIEW_WALK_DELETE_SELECTION
|
TREEVIEW_WALK_DELETE_SELECTION,
|
||||||
|
TREEVIEW_WALK_PROPAGATE_SELECTION
|
||||||
} purpose;
|
} purpose;
|
||||||
union {
|
union {
|
||||||
bool has_selection;
|
bool has_selection;
|
||||||
|
@ -1411,6 +1412,15 @@ static nserror treeview_node_selection_walk_cb(treeview_node *n,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TREEVIEW_WALK_PROPAGATE_SELECTION:
|
||||||
|
if (n->parent != NULL &&
|
||||||
|
n->parent->flags & TREE_NODE_SELECTED &&
|
||||||
|
!(n->flags & TREE_NODE_SELECTED)) {
|
||||||
|
n->flags ^= TREE_NODE_SELECTED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case TREEVIEW_WALK_CLEAR_SELECTION:
|
case TREEVIEW_WALK_CLEAR_SELECTION:
|
||||||
if (n->flags & TREE_NODE_SELECTED) {
|
if (n->flags & TREE_NODE_SELECTED) {
|
||||||
n->flags ^= TREE_NODE_SELECTED;
|
n->flags ^= TREE_NODE_SELECTED;
|
||||||
|
@ -1577,6 +1587,38 @@ static bool treeview_delete_selection(treeview *tree, struct rect *rect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Propagate selection to visible descendants of selected nodes.
|
||||||
|
*
|
||||||
|
* \param tree Treeview object to propagate selection in
|
||||||
|
* \param rect Redraw rectangle (if redraw required)
|
||||||
|
* \return true iff redraw required
|
||||||
|
*/
|
||||||
|
static bool treeview_propagate_selection(treeview *tree, struct rect *rect)
|
||||||
|
{
|
||||||
|
struct treeview_selection_walk_data sw;
|
||||||
|
|
||||||
|
assert(tree != NULL);
|
||||||
|
assert(tree->root != NULL);
|
||||||
|
|
||||||
|
rect->x0 = 0;
|
||||||
|
rect->y0 = 0;
|
||||||
|
rect->x1 = REDRAW_MAX;
|
||||||
|
rect->y1 = 0;
|
||||||
|
|
||||||
|
sw.purpose = TREEVIEW_WALK_PROPAGATE_SELECTION;
|
||||||
|
sw.data.redraw.required = false;
|
||||||
|
sw.data.redraw.rect = rect;
|
||||||
|
sw.current_y = 0;
|
||||||
|
sw.tree = tree;
|
||||||
|
|
||||||
|
treeview_walk_internal(tree->root, false, NULL,
|
||||||
|
treeview_node_selection_walk_cb, &sw);
|
||||||
|
|
||||||
|
return sw.data.redraw.required;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct treeview_launch_walk_data {
|
struct treeview_launch_walk_data {
|
||||||
int selected_depth;
|
int selected_depth;
|
||||||
treeview *tree;
|
treeview *tree;
|
||||||
|
@ -1785,6 +1827,7 @@ static bool treeview_keyboard_navigation(treeview *tree, uint32_t key,
|
||||||
* Set the drag&drop drop indicator
|
* Set the drag&drop drop indicator
|
||||||
*
|
*
|
||||||
* \param tree Treeview object to set node indicator in
|
* \param tree Treeview object to set node indicator in
|
||||||
|
* \param need_redraw True iff we already have a redraw region
|
||||||
* \param target The treeview node with mouse pointer over it
|
* \param target The treeview node with mouse pointer over it
|
||||||
* \param node_height The height of node
|
* \param node_height The height of node
|
||||||
* \param node_y The Y coord of the top of target node
|
* \param node_y The Y coord of the top of target node
|
||||||
|
@ -1792,14 +1835,13 @@ static bool treeview_keyboard_navigation(treeview *tree, uint32_t key,
|
||||||
* \param rect Redraw rectangle (if redraw required)
|
* \param rect Redraw rectangle (if redraw required)
|
||||||
* \return true iff redraw required
|
* \return true iff redraw required
|
||||||
*/
|
*/
|
||||||
static bool treeview_set_move_indicator(treeview *tree,
|
static bool treeview_set_move_indicator(treeview *tree, bool need_redraw,
|
||||||
treeview_node *target, int node_height,
|
treeview_node *target, int node_height,
|
||||||
int node_y, int mouse_y, struct rect *rect)
|
int node_y, int mouse_y, struct rect *rect)
|
||||||
{
|
{
|
||||||
enum treeview_target_pos target_pos;
|
enum treeview_target_pos target_pos;
|
||||||
int mouse_pos = mouse_y - node_y;
|
int mouse_pos = mouse_y - node_y;
|
||||||
int x;
|
int x;
|
||||||
bool need_redraw;
|
|
||||||
|
|
||||||
assert(tree != NULL);
|
assert(tree != NULL);
|
||||||
assert(tree->root != NULL);
|
assert(tree->root != NULL);
|
||||||
|
@ -1836,13 +1878,24 @@ static bool treeview_set_move_indicator(treeview *tree,
|
||||||
if (target_pos == tree->move.target_pos &&
|
if (target_pos == tree->move.target_pos &&
|
||||||
target == tree->move.target) {
|
target == tree->move.target) {
|
||||||
/* No change */
|
/* No change */
|
||||||
return false;
|
return need_redraw;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree->move.target_pos != TV_TARGET_NONE) {
|
if (tree->move.target_pos != TV_TARGET_NONE) {
|
||||||
/* Need to clear old indicator position */
|
/* Need to clear old indicator position */
|
||||||
*rect = tree->move.target_area;
|
if (need_redraw) {
|
||||||
need_redraw = true;
|
if (rect->x0 > tree->move.target_area.x0)
|
||||||
|
rect->x0 = tree->move.target_area.x0;
|
||||||
|
if (tree->move.target_area.x1 > rect->x1)
|
||||||
|
rect->x1 = tree->move.target_area.x1;
|
||||||
|
if (rect->y0 > tree->move.target_area.y0)
|
||||||
|
rect->y0 = tree->move.target_area.y0;
|
||||||
|
if (tree->move.target_area.y1 > rect->y1)
|
||||||
|
rect->y1 = tree->move.target_area.y1;
|
||||||
|
} else {
|
||||||
|
*rect = tree->move.target_area;
|
||||||
|
need_redraw = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_pos == TV_TARGET_ABOVE) {
|
if (target_pos == TV_TARGET_ABOVE) {
|
||||||
|
@ -1868,12 +1921,10 @@ static bool treeview_set_move_indicator(treeview *tree,
|
||||||
if (target_pos != TV_TARGET_NONE) {
|
if (target_pos != TV_TARGET_NONE) {
|
||||||
/* Need to draw new indicator position */
|
/* Need to draw new indicator position */
|
||||||
if (need_redraw) {
|
if (need_redraw) {
|
||||||
if (rect->x0 != tree->move.target_area.x0) {
|
if (rect->x0 > tree->move.target_area.x0)
|
||||||
if (rect->x0 > tree->move.target_area.x0)
|
rect->x0 = tree->move.target_area.x0;
|
||||||
rect->x0 = tree->move.target_area.x0;
|
if (tree->move.target_area.x1 > rect->x1)
|
||||||
if (tree->move.target_area.x1 > rect->x1)
|
rect->x1 = tree->move.target_area.x1;
|
||||||
rect->x1 = tree->move.target_area.x1;
|
|
||||||
}
|
|
||||||
if (rect->y0 > tree->move.target_area.y0)
|
if (rect->y0 > tree->move.target_area.y0)
|
||||||
rect->y0 = tree->move.target_area.y0;
|
rect->y0 = tree->move.target_area.y0;
|
||||||
if (tree->move.target_area.y1 > rect->y1)
|
if (tree->move.target_area.y1 > rect->y1)
|
||||||
|
@ -2065,6 +2116,7 @@ static nserror treeview_node_mouse_action_cb(treeview_node *node, void *ctx,
|
||||||
ma->tree->drag.type = TV_DRAG_MOVE;
|
ma->tree->drag.type = TV_DRAG_MOVE;
|
||||||
ma->tree->cw_t->drag_status(ma->tree->cw_h,
|
ma->tree->cw_t->drag_status(ma->tree->cw_h,
|
||||||
CORE_WINDOW_DRAG_MOVE);
|
CORE_WINDOW_DRAG_MOVE);
|
||||||
|
redraw |= treeview_propagate_selection(ma->tree, &r);
|
||||||
|
|
||||||
} else if (ma->mouse & BROWSER_MOUSE_DRAG_2) {
|
} else if (ma->mouse & BROWSER_MOUSE_DRAG_2) {
|
||||||
ma->tree->drag.type = TV_DRAG_SELECTION;
|
ma->tree->drag.type = TV_DRAG_SELECTION;
|
||||||
|
@ -2100,7 +2152,7 @@ static nserror treeview_node_mouse_action_cb(treeview_node *node, void *ctx,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TV_DRAG_MOVE:
|
case TV_DRAG_MOVE:
|
||||||
redraw |= treeview_set_move_indicator(ma->tree,
|
redraw |= treeview_set_move_indicator(ma->tree, redraw,
|
||||||
node, height, ma->current_y, ma->y, &r);
|
node, height, ma->current_y, ma->y, &r);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue