Commit: 030d228ca46b19b80d35ffd2ab986e4c6e54d55f
Author: Julian Eisel
Date: Wed May 25 14:58:22 2016 +0200
Branches: soc-2016-layer_manager
https://developer.blender.org/rB030d228ca46b19b80d35ffd2ab986e4c6e54d55f
More layer selection methods
Now supports shift, ctrl+shift and a-key selection.
===================================================================
M source/blender/editors/space_layers/layers_intern.h
M source/blender/editors/space_layers/layers_ops.c
M source/blender/editors/space_layers/layers_util.c
M source/blender/editors/space_layers/space_layers.c
M source/blender/makesdna/DNA_space_types.h
===================================================================
diff --git a/source/blender/editors/space_layers/layers_intern.h
b/source/blender/editors/space_layers/layers_intern.h
index f3c505b..fe5ccb2 100644
--- a/source/blender/editors/space_layers/layers_intern.h
+++ b/source/blender/editors/space_layers/layers_intern.h
@@ -49,7 +49,9 @@ void layers_tiles_draw(const struct bContext *C, struct
ARegion *ar);
/* layers_util.c */
LayerTile *layers_tile_add(struct SpaceLayers *slayer, struct LayerTreeItem
*litem);
-LayerTile *layers_tile_find_at_coordinate(const SpaceLayers *slayer, const
ARegion *ar, const int co[2]);
+LayerTile *layers_tile_find_at_coordinate(
+ const struct SpaceLayers *slayer, const ARegion *ar, const int co[2],
+ int *r_tile_idx);
/* layers_ops.c */
void layers_operatortypes(void);
diff --git a/source/blender/editors/space_layers/layers_ops.c
b/source/blender/editors/space_layers/layers_ops.c
index 01373d4..f28c00c 100644
--- a/source/blender/editors/space_layers/layers_ops.c
+++ b/source/blender/editors/space_layers/layers_ops.c
@@ -32,6 +32,9 @@
#include "ED_object.h"
#include "ED_screen.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -76,7 +79,7 @@ static int layer_rename_invoke(bContext *C, wmOperator
*UNUSED(op), const wmEven
{
SpaceLayers *slayer = CTX_wm_space_layers(C);
ARegion *ar = CTX_wm_region(C);
- LayerTile *tile = layers_tile_find_at_coordinate(slayer, ar,
event->mval);
+ LayerTile *tile = layers_tile_find_at_coordinate(slayer, ar,
event->mval, NULL);
if (tile) {
tile->flag |= LAYERTILE_RENAME;
@@ -101,21 +104,91 @@ static void LAYERS_OT_layer_rename(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static void layers_deselect_all(const SpaceLayers *slayer)
+BLI_INLINE void layer_selection_set(SpaceLayers *slayer, LayerTile *tile,
const int tile_idx, const bool enable)
{
- for (LayerTile *tile = slayer->layer_tiles.first; tile; tile =
tile->next) {
+ if (enable) {
+ (tile->flag |= LAYERTILE_SELECTED);
+ slayer->last_selected = tile_idx;
+ }
+ else {
tile->flag &= ~LAYERTILE_SELECTED;
}
}
-static int layer_select_invoke(bContext *C, wmOperator *UNUSED(op), const
wmEvent *event)
+/**
+ * Change the selection state of all layer tiles.
+ * \param enable: If true, tiles are selected, else they are deselected.
+ */
+static void layers_selection_set_all(SpaceLayers *slayer, const bool enable)
+{
+ int i = 0;
+ for (LayerTile *tile = slayer->layer_tiles.first; tile; tile =
tile->next, i++) {
+ layer_selection_set(slayer, tile, i, enable);
+ }
+}
+
+/**
+ * Select everything within the range of \a from to \a to.
+ * \return if anything got selected. Nothing is selected if from == to or one
of them is < 0.
+ */
+static bool layers_select_fill(SpaceLayers *slayer, const int from, const int
to)
+{
+ const int min = MIN2(from, to);
+ const int max = MAX2(from, to);
+
+ if (min < 0 || min == max)
+ return false;
+
+ int i = 0;
+ for (LayerTile *tile = slayer->layer_tiles.first; tile && i <= max;
tile = tile->next, i++) {
+ if (i >= min) {
+ layer_selection_set(slayer, tile, i, true);
+ }
+ }
+ return true;
+}
+
+static int layer_select_invoke(bContext *C, wmOperator *op, const wmEvent
*event)
{
SpaceLayers *slayer = CTX_wm_space_layers(C);
ARegion *ar = CTX_wm_region(C);
- LayerTile *tile = layers_tile_find_at_coordinate(slayer, ar,
event->mval);
+ const bool extend = RNA_boolean_get(op->ptr, "extend");
+ const bool deselect = RNA_boolean_get(op->ptr, "deselect");
+ const bool toggle = RNA_boolean_get(op->ptr, "toggle");
+ const bool fill = RNA_boolean_get(op->ptr, "fill");
+
+ int tile_idx;
+ LayerTile *tile = layers_tile_find_at_coordinate(slayer, ar,
event->mval, &tile_idx);
+
+ /* little helper for setting/unsetting selection flag */
+#define TILE_SET_SELECTION(enable) layer_selection_set(slayer, tile, tile_idx,
enable);
+
if (tile) {
- layers_deselect_all(slayer);
- tile->flag |= LAYERTILE_SELECTED;
+ /* deselect all, but only if extend, deselect and toggle are
false */
+ if (((extend == deselect) == toggle) == false) {
+ layers_selection_set_all(slayer, false);
+ }
+ if (extend) {
+ if (fill && layers_select_fill(slayer,
slayer->last_selected, tile_idx)) {
+ /* skip */
+ }
+ else {
+ TILE_SET_SELECTION(true);
+ }
+ }
+ else if (deselect) {
+ TILE_SET_SELECTION(false);
+ }
+ else {
+ if (!tile->flag & LAYERTILE_SELECTED) {
+ TILE_SET_SELECTION(true);
+ }
+ else if (toggle) {
+ TILE_SET_SELECTION(false);
+ }
+ }
+
+#undef TILE_SET_SELECTION
ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
@@ -123,16 +196,50 @@ static int layer_select_invoke(bContext *C, wmOperator
*UNUSED(op), const wmEven
return OPERATOR_CANCELLED;
}
-static void LAYERS_OT_layer_select(wmOperatorType *ot)
+static void LAYERS_OT_select(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select Layer";
- ot->idname = "LAYERS_OT_layer_select";
+ ot->idname = "LAYERS_OT_select";
ot->description = "Select/activate the layer under the cursor";
/* api callbacks */
ot->invoke = layer_select_invoke;
ot->poll = ED_operator_layers_active;
+
+ WM_operator_properties_mouse_select(ot);
+ PropertyRNA *prop = RNA_def_boolean(ot->srna, "fill", false, "Fill",
"Select everything beginning "
+
"with the last selection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+}
+
+static int layer_select_all_toggle_invoke(bContext *C, wmOperator *UNUSED(op),
const wmEvent *UNUSED(event))
+{
+ SpaceLayers *slayer = CTX_wm_space_layers(C);
+ LayerTile *tile;
+
+ for (tile = slayer->layer_tiles.first; tile; tile = tile->next) {
+ if (tile->flag & LAYERTILE_SELECTED) {
+ break;
+ }
+ }
+ /* if a tile was found we deselect all, else we select all */
+ layers_selection_set_all(slayer, tile == NULL);
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+}
+
+static void LAYERS_OT_select_all_toggle(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "(De)select All Layers";
+ ot->idname = "LAYERS_OT_select_all_toggle";
+ ot->description = "Select or deselect all layers";
+
+ /* api callbacks */
+ ot->invoke = layer_select_all_toggle_invoke;
+ ot->poll = ED_operator_layers_active;
}
@@ -145,13 +252,23 @@ void layers_operatortypes(void)
WM_operatortype_append(LAYERS_OT_layer_rename);
/* states (activating selecting, highlighting) */
- WM_operatortype_append(LAYERS_OT_layer_select);
+ WM_operatortype_append(LAYERS_OT_select);
+ WM_operatortype_append(LAYERS_OT_select_all_toggle);
}
void layers_keymap(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Layer Manager",
SPACE_LAYERS, 0);
- WM_keymap_add_item(keymap, "LAYERS_OT_layer_select", LEFTMOUSE,
KM_CLICK, 0, 0);
+ wmKeyMapItem *kmi;
+
+ /* selection */
+ WM_keymap_add_item(keymap, "LAYERS_OT_select", LEFTMOUSE, KM_CLICK, 0,
0);
+ kmi = WM_keymap_add_item(keymap, "LAYERS_OT_select", LEFTMOUSE,
KM_CLICK, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
+ kmi = WM_keymap_add_item(keymap, "LAYERS_OT_select", LEFTMOUSE,
KM_CLICK, KM_CTRL | KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "fill", true);
+ WM_keymap_add_item(keymap, "LAYERS_OT_select_all_toggle", AKEY,
KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "LAYERS_OT_layer_rename", LEFTMOUSE,
KM_DBL_CLICK, 0, 0);
WM_keymap_add_item(keymap, "LAYERS_OT_layer_rename", LEFTMOUSE,
KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/space_layers/layers_util.c
b/source/blender/editors/space_layers/layers_util.c
index dd32623..2a6fc23 100644
--- a/source/blender/editors/space_layers/layers_util.c
+++ b/source/blender/editors/space_layers/layers_util.c
@@ -51,16 +51,27 @@ LayerTile *layers_tile_add(SpaceLayers *slayer,
LayerTreeItem *litem)
/**
* Find the tile at coordinate \a co (regionspace).
+ * \param r_tile_idx: Returns the index of the result, -1 if no tile was found.
*/
-LayerTile *layers_tile_find_at_coordinate(const SpaceLayers *slayer, const
ARegion *ar, const int co[2])
+LayerTile *layers_tile_find_at_coordinate(
+ const SpaceLayers *slayer, const ARegion *ar, const int co[2],
+ int *r_tile_idx)
{
+ LayerTile *tile;
int ofsx = 0;
+ unsigned int idx = 0;
- for (LayerTile *tile = slayer->layer_tiles.first; tile; tile =
tile->next) {
+ for (tile = slayer->layer_tiles.first; tile; tile = tile->next, idx++) {
ofsx += tile->litem->height;
if (co[1] >= -ar->v2d.cur.ymin - ofsx) {
- return tile;
+ /* found tile */
+ break;
}
}
- return NULL;
+
+ /* return values */
+ if (r_tile_idx) {
+ (*r_tile_idx) = (tile != NULL) ? idx : -1;
+ }
+ return tile;
}
diff --git a/source/blender/editors/space_layers/space_layers.c
b/source/blender/editors/space_layers/space_layers.c
index c54ec96..854d54c 100644
--- a/source/blender/editors/space_layers/space_layers.c
+++ b/source/blender/editors/space_layers/space_layers.c
@@ -55,6 +55,7 @@ static SpaceLink *layers_new(const bContext *UNUSED(C))
slayer = MEM_callocN(sizeof(SpaceLayers), __func__);
slayer->spacetype = SPACE_LAYERS;
+ slayer->last_selected = -1;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for layer manager");
diff --git a/source/blender/makesdna/DNA_space_types.h
b/source/blender/makesdna/DNA_space_types.h
index 2c6d2f0..e8b6ade 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -1338,8 +1338,9 @@ typedef struct SpaceLayers {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
int spacetype;
- int pad;
+ /* index of last selected item, will likely become redundant when
active layers are supported */
+ int last_selected;
ListBase layer_tiles; /* LayerTile */
} SpaceLayers;
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs