[Bf-blender-cvs] [e1d43df] soc-2016-layer_manager: Layer drag & drop reordering
Julian Eisel
noreply at git.blender.org
Thu Jun 16 01:56:40 CEST 2016
Commit: e1d43df90bf76c051770e1123d78c53f097acf59
Author: Julian Eisel
Date: Thu Jun 16 01:44:58 2016 +0200
Branches: soc-2016-layer_manager
https://developer.blender.org/rBe1d43df90bf76c051770e1123d78c53f097acf59
Layer drag & drop reordering
Took some time to get logic to work like user's would expect it, but seems to work now.
===================================================================
M release/datafiles/brushicons/snake_hook.png
M source/blender/blenkernel/BKE_layer.h
M source/blender/blenkernel/intern/layer.c
M source/blender/editors/space_layers/layers_draw.c
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
===================================================================
diff --git a/release/datafiles/brushicons/snake_hook.png b/release/datafiles/brushicons/snake_hook.png
index 961c54e..908a7f1 100644
Binary files a/release/datafiles/brushicons/snake_hook.png and b/release/datafiles/brushicons/snake_hook.png differ
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 81cd051..cc30933 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -90,6 +90,7 @@ void BKE_layeritem_register(
const LayerItemPollFunc poll, LayerItemDrawFunc draw, LayerItemDrawSettingsFunc draw_settings);
void BKE_layeritem_remove(LayerTreeItem *litem, const bool remove_children);
+void BKE_layeritem_move(LayerTreeItem *litem, const int newidx);
void BKE_layeritem_group_assign(LayerTreeItem *group, LayerTreeItem *item);
bool BKE_layeritem_iterate_childs(
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 4b346c7..da3c4ef 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -229,6 +229,28 @@ void BKE_layeritem_remove(LayerTreeItem *litem, const bool remove_children)
}
/**
+ * Move \a litem that's already in the layer tree to slot \a newidx.
+ */
+void BKE_layeritem_move(LayerTreeItem *litem, const int newidx)
+{
+ const bool is_higher = litem->index < newidx;
+
+ for (int i = is_higher ? litem->index + 1 : litem->index - 1;
+ i < litem->tree->tot_items && i >= 0;
+ is_higher ? i++ : i--)
+ {
+ const int iter_new_idx = i + (is_higher ? -1 : 1);
+ litem->tree->items_all[iter_new_idx] = litem->tree->items_all[i];
+ litem->tree->items_all[iter_new_idx]->index = iter_new_idx;
+ if (i == newidx) {
+ litem->tree->items_all[i] = litem;
+ litem->index = i;
+ break;
+ }
+ }
+}
+
+/**
* Assign \a item to \a group.
*/
void BKE_layeritem_group_assign(LayerTreeItem *group, LayerTreeItem *item)
diff --git a/source/blender/editors/space_layers/layers_draw.c b/source/blender/editors/space_layers/layers_draw.c
index 29498a9..ce805fd 100644
--- a/source/blender/editors/space_layers/layers_draw.c
+++ b/source/blender/editors/space_layers/layers_draw.c
@@ -22,6 +22,7 @@
* \ingroup splayers
*/
+#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BLI_utildefines.h"
@@ -67,24 +68,23 @@ static int layer_tile_indent_level_get(const LayerTreeItem *litem)
}
/**
- * Draw the tile for \a litem.
* \return the height of the drawn tile.
*/
static float layer_tile_draw(
- LayerTreeItem *litem,
- const bContext *C, ARegion *ar, SpaceLayers *slayer, uiBlock *block, uiStyle *style,
- float ofs_y, int idx)
+ LayerTile *tile,
+ const bContext *C, ARegion *ar, uiBlock *block, uiStyle *style,
+ float row_ofs_y, int idx)
{
- LayerTile *tile = BLI_ghash_lookup(slayer->tiles, litem);
+ LayerTreeItem *litem = tile->litem;
const bool expanded = litem->draw_settings && (tile->flag & LAYERTILE_EXPANDED);
const float pad_x = 4.0f * UI_DPI_FAC;
const float header_y = LAYERTILE_HEADER_HEIGHT;
- const float ofs_x = layer_tile_indent_level_get(litem) * LAYERITEM_INDENT_SIZE;
+ const float ofs_x = layer_tile_indent_level_get(litem) * LAYERITEM_INDENT_SIZE + tile->ofs[0];
+ const float ofs_y = row_ofs_y + tile->ofs[1];
const rctf rect = {-ar->v2d.cur.xmin + ofs_x, ar->winx,
-ar->v2d.cur.ymin - ofs_y - header_y, -ar->v2d.cur.ymin - ofs_y};
- int size_y = 0;
int tile_size_y = 0;
/* draw item itself */
@@ -120,14 +120,23 @@ static float layer_tile_draw(
rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), 0, 0, style);
litem->draw_settings(C, litem, layout);
+ int size_y = 0;
UI_block_layout_resolve(block, NULL, &size_y);
tile_size_y = -(ofs_y + size_y + ar->v2d.cur.ymin);
}
- /* draw background */
- if (idx % 2) {
- UI_ThemeColorShade(TH_BACK, 10);
+ /* draw background, this is done after defining buttons so we can get real layout height */
+ if ((idx % 2) || (tile->flag & LAYERTILE_FLOATING)) {
+ if (tile->flag & LAYERTILE_FLOATING) {
+ UI_ThemeColorShadeAlpha(TH_BACK, idx % 2 ? 10 : 0, -100);
+ }
+ else {
+ UI_ThemeColorShade(TH_BACK, 10);
+ }
+
+ glEnable(GL_BLEND);
fdrawbox_filled(0, rect.ymax - tile_size_y, rect.xmax, rect.ymax);
+ glDisable(GL_BLEND);
}
/* draw selection */
if (tile->flag & LAYERTILE_SELECTED) {
@@ -137,31 +146,88 @@ static float layer_tile_draw(
}
idx++;
+ BLI_rcti_rctf_copy(&tile->rect, &rect);
/* set tile height */
tile->tot_height = tile_size_y;
return tile_size_y;
}
-void layers_tiles_draw(const bContext *C, ARegion *ar)
+struct FloatingTileDrawInfo {
+ LayerTile *tile;
+ int idx;
+ float pos_y;
+};
+
+static void layers_tiles_draw_floating(const bContext *C, struct FloatingTileDrawInfo *floating)
{
- SpaceLayers *slayer = CTX_wm_space_layers(C);
+ ARegion *ar = CTX_wm_region(C);
+ uiStyle *style = UI_style_get_dpi();
+
+ BLI_assert(floating->tile->flag & LAYERTILE_FLOATING);
+ /* Own block for both draw steps because otherwise buttons from
+ * fixed tiles are drawn over background of floating ones. */
uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+
+ if (floating->tile->litem->draw) {
+ layer_tile_draw(floating->tile, C, ar, block, style, floating->pos_y, floating->idx);
+ }
+
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
+}
+
+static void layers_tiles_draw_fixed(
+ const bContext *C,
+ float *r_ofs_y, int *r_idx,
+ struct FloatingTileDrawInfo *r_floating)
+{
+ SpaceLayers *slayer = CTX_wm_space_layers(C);
+ ARegion *ar = CTX_wm_region(C);
uiStyle *style = UI_style_get_dpi();
- /* draw tiles */
- int idx = 0;
- float ofs_y = 0.0f;
+ /* Own block for both draw steps because otherwise buttons from
+ * fixed tiles are drawn over background of floating ones. */
+ uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+
BKE_LAYERTREE_ITER_START(slayer->act_tree, 0, i, litem)
{
+ LayerTile *tile = BLI_ghash_lookup(slayer->tiles, litem);
+ BLI_assert(tile->litem == litem);
+
+ /* skip floating buts but return some info for drawing them later */
+ if (tile->flag & LAYERTILE_FLOATING) {
+ BLI_assert(r_floating->tile == NULL); /* only one floating tile allowed */
+ r_floating->tile = tile;
+ r_floating->idx = *r_idx;
+ r_floating->pos_y = *r_ofs_y;
+ /* use tot_height from last draw, we can assume it hasn't changed */
+ *r_ofs_y += tile->tot_height;
+ (*r_idx)++;
+ continue;
+ }
+
if (litem->draw) {
- ofs_y += layer_tile_draw(litem, C, ar, slayer, block, style, ofs_y, idx);
- idx++;
+ *r_ofs_y += layer_tile_draw(tile, C, ar, block, style, *r_ofs_y, *r_idx);
+ (*r_idx)++;
}
}
BKE_LAYERTREE_ITER_END;
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
+}
+
+void layers_tiles_draw(const bContext *C, ARegion *ar)
+{
+ struct FloatingTileDrawInfo floating = {NULL};
+ float ofs_y = 0.0f;
+ int idx = 0;
+
+ /* draw fixed (not floating) tiles first */
+ layers_tiles_draw_fixed(C, &ofs_y, &idx, &floating);
+
/* fill remaining space with empty boxes */
const float tot_fill_tiles = (-ar->v2d.cur.ymin - ofs_y) / LAYERTILE_HEADER_HEIGHT + 1;
for (int i = 0; i < tot_fill_tiles; i++) {
@@ -172,8 +238,10 @@ void layers_tiles_draw(const bContext *C, ARegion *ar)
}
}
- UI_block_end(C, block);
- UI_block_draw(C, block);
+ /* draw floating tile last */
+ if (floating.tile) {
+ layers_tiles_draw_floating(C, &floating);
+ }
/* update size of tot-rect (extents of data/viewable area) */
UI_view2d_totRect_set(&ar->v2d, ar->winx - BLI_rcti_size_x(&ar->v2d.vert), ofs_y);
diff --git a/source/blender/editors/space_layers/layers_intern.h b/source/blender/editors/space_layers/layers_intern.h
index dc5d029..d4e8f1f 100644
--- a/source/blender/editors/space_layers/layers_intern.h
+++ b/source/blender/editors/space_layers/layers_intern.h
@@ -35,6 +35,9 @@ typedef enum eLayerTileFlag {
LAYERTILE_SELECTED = (1 << 0),
LAYERTILE_RENAME = (1 << 1),
LAYERTILE_EXPANDED = (1 << 2),
+ /* Draw the tile as if it was floating above others (for drag and drop).
+ * Note: Currently only one floating tile at a time allowed. */
+ LAYERTILE_FLOATING = (1 << 3),
} eLayerTileFlag;
/**
@@ -48,6 +51,10 @@ typedef struct LayerTile {
/* The height of this item. Set right after drawing,
* so should always reflect what's on the screen */
int tot_height;
+ struct rcti rect;
+
+ /* Offset applied for drawing, used for drag and drop preview */
+ int ofs[2];
} LayerTile;
/* layers_draw.c */
diff --git a/source/blender/editors/space_layers/layers_ops.c b/source/blender/editors/space_layers/layers_ops.c
index d5ba3d6..8bbbd09 100644
--- a/source/blender/editors/space_layers/layers_ops.c
+++ b/source/blender/editors/space_layers/layers_ops.c
@@ -34,12 +34,15 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
+#include "BLI_rect.h"
#include "DNA_windowmanager_types.h"
#include "ED_object.h"
#include "ED_screen.h"
+#include "MEM_guardedalloc.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -49,6 +52,36 @@
#include "layers_intern.h" /* own include */
+/**
+ * LayerTile wrapper for additional information needed for
+ * offsetting and animating tiles during drag & drop reordering.
+ */
+typedef struct {
+ LayerTile *tile;
+ /* With this we can substract the added offset when done. If we simply
+ * set it to 0 LayerTile.ofs can't be reliably used elsewhere. */
+ int ofs_added;
+} LayerDragTile;
+
+/**
+ * Data for layer tile drag and drop reordering.
+ */
+typedef struct {
+ LayerDragTile dragged; /* info for the tile that's being dragged */
+ /* LayerDragTile hash table for all items that need special info while dragging */
+ GHash *tiledrags;
+ int insert_idx;
+ int init_mval_y;
+} LayerDragData;
+
+enum {
+ LAYERDRAG_CANCEL = 1,
+ LAYERDRAG_CONFIRM,
+};
+
+/* -------------------------------------------------------------------- */
+
+
static int layer_add_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
SpaceLayers *slayer = CTX_wm_space_layers(C);
@@ -227,6 +260,160 @@ static void LAYERS_OT_group_add(wmOperatorType *ot)
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list