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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to