Index: trunk/src_plugins/gui/layersel.c =================================================================== --- trunk/src_plugins/gui/layersel.c (revision 758) +++ trunk/src_plugins/gui/layersel.c (revision 759) @@ -499,19 +499,77 @@ } } -static void layer_move(int dst) +/* return whether the layer at idx is a sub-layer */ +static int is_sub(int idx) { - int step, n, src = layersel.camv->lysel; camv_design_t *camv = layersel.camv; + return ((camv_layer_t *)camv->layers.array[idx])->sub; +} + +/* low level move a layer from src to dst, in 'step' direction. Returns new dst. */ +static int layer_move_(int src, int dst, int step) +{ + int n; + camv_design_t *camv = layersel.camv; camv_layer_t *dst_ly = camv->layers.array[src]; - step = dst > src ? 1 : -1; for(n = src; step > 0 ? (n < dst) : (n > dst); n += step) camv->layers.array[n] = camv->layers.array[n+step]; camv->layers.array[dst] = dst_ly; + return dst - step; +} + +static void layer_move(int dst) +{ + int step, sn, snv, src = layersel.camv->lysel, dst_fin; + camv_design_t *camv = layersel.camv; + + step = dst > src ? 1 : -1; + + /* we may need to move multiple sublayers; determine how many */ + for(snv = src+1; (snv > 0) && (snv < camv->layers.used) && is_sub(snv); snv++); + +/*rnd_trace("dst1=%d step=%d snv=%d blocklen=%d\n", dst, step, snv, snv-src);*/ + + if (step > 0) { + if (snv-src > 1) + dst+=(snv-src); + if (dst >= camv->layers.used) + dst = camv->layers.used-1; + + /* move dst to jump over own sub-layers when moving up */ + if (((dst+1) < camv->layers.used) && is_sub(dst+1)) { + for(dst++; ((dst+1) < camv->layers.used) && is_sub(dst+1); dst++) ; + if (dst >= camv->layers.used) + return; + } + } + else { + /* move dst to jump over sub-layers of the target when moving down */ + for(; (dst > 0) && is_sub(dst); dst--) ; + } + +/*rnd_trace("dst2=%d\n", dst);*/ + + + if (step > 0) { + for(sn = snv-1; sn >= src; sn--) { +/*rnd_trace("move+ %d to %d\n", sn, dst);*/ + dst = layer_move_(sn, dst, step); + } + dst_fin = dst + step; + } + else { + dst_fin = dst; + for(sn = src; sn < snv; sn++) { +/*rnd_trace("move- %d to %d\n", sn, dst);*/ + dst = layer_move_(sn, dst, step); + } + } + rnd_event(&layersel.camv->hidlib, CAMV_EVENT_LAYERS_CHANGED, NULL); - layer_select(layersel.layers.array[dst]); + layer_select(layersel.layers.array[dst_fin]); camv_hid_redraw(camv); }