Skip to content

Commit

Permalink
Add Group View mode
Browse files Browse the repository at this point in the history
Shows the parent group of the current layer in isolation.
  • Loading branch information
askmeaboutlo0m committed Sep 29, 2024
1 parent f6ec802 commit fe9928b
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 17 deletions.
2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Unreleased Version 2.2.2-pre
* Feature: Extended touch tap gestures, among them two-finger tap to undo, three-finger tap to redo and tap-and-hold to summon the color picker. Can be configured in the preferences under the Touch tab. Thanks InconsolableCellist and many others for suggesting.
* Feature: Snap canvas rotation around 0° by default. If you don't want this, you can set the canvas shortcut or touch rotation to "free rotate canvas" instead.
* Feature: Show a color preview when picking a color from the canvas. Can be toggled in the tool preferences.
* Fix: In layer view mode, render the layer truly in isolation instead of applying opacities, visibilities or alpha preserve to it. Thanks MachKerman and incoheart for reporting.
* Feature: Add Layer > Group View to show the parent group of the current layer in isolation. Thanks Rylan for suggesting.

2024-08-09 Version 2.2.2-beta.3
* Fix: Use more accurate timers for performance profiles if the platform supports it.
Expand Down
6 changes: 6 additions & 0 deletions src/desktop/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,7 @@ void MainWindow::toggleLayerViewMode()
// pressing the shortcut again would have no useful effect anyway.
QAction *actions[] = {
getAction("layerviewcurrentlayer"),
getAction("layerviewcurrentgroup"),
getAction("layerviewcurrentframe"),
};
for (QAction *action : actions) {
Expand All @@ -881,6 +882,8 @@ void MainWindow::updateLayerViewMode()
QAction *action;
if((action = getAction("layerviewcurrentlayer"))->isChecked()) {
mode = DP_VIEW_MODE_LAYER;
} else if((action = getAction("layerviewcurrentgroup"))->isChecked()) {
mode = DP_VIEW_MODE_GROUP;
} else if((action = getAction("layerviewcurrentframe"))->isChecked()) {
mode = DP_VIEW_MODE_FRAME;
} else {
Expand Down Expand Up @@ -4573,6 +4576,7 @@ void MainWindow::setupActions()

QAction *layerViewNormal = makeAction("layerviewnormal", tr("Normal View")).statusTip(tr("Show all layers normally")).noDefaultShortcut().checkable().checked();
QAction *layerViewCurrentLayer = makeAction("layerviewcurrentlayer", tr("Layer View")).statusTip(tr("Show only the current layer")).shortcut("Home").checkable();
QAction *layerViewCurrentGroup = makeAction("layerviewcurrentgroup", tr("Group View")).statusTip(tr("Show only the current parent layer group")).shortcut("Ctrl+Home").checkable();
QAction *layerViewCurrentFrame = makeAction("layerviewcurrentframe", tr("Frame View")).statusTip(tr("Show only layers in the current frame")).shortcut("Shift+Home").checkable();
QAction *layerUncensor = makeAction("layerviewuncensor", tr("Show Censored Layers")).noDefaultShortcut().checkable();
m_lastLayerViewMode = layerViewNormal;
Expand All @@ -4581,11 +4585,13 @@ void MainWindow::setupActions()
layerViewModeGroup->setExclusive(true);
layerViewModeGroup->addAction(layerViewNormal);
layerViewModeGroup->addAction(layerViewCurrentLayer);
layerViewModeGroup->addAction(layerViewCurrentGroup);
layerViewModeGroup->addAction(layerViewCurrentFrame);

QMenu *layerViewMenu = viewmenu->addMenu(tr("Layer View Mode"));
layerViewMenu->addAction(layerViewNormal);
layerViewMenu->addAction(layerViewCurrentLayer);
layerViewMenu->addAction(layerViewCurrentGroup);
layerViewMenu->addAction(layerViewCurrentFrame);
viewmenu->addAction(layerUncensor);

Expand Down
36 changes: 30 additions & 6 deletions src/drawdance/libengine/dpengine/layer_routes.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ typedef struct DP_LayerRoutesEntry {
UT_hash_handle hh;
bool is_group;
int layer_id;
DP_LayerRoutesEntry *parent_lre;
int index_count;
int indexes[];
} DP_LayerRoutesEntry;
Expand All @@ -56,8 +57,9 @@ DP_LayerRoutes *DP_layer_routes_new(void)
return lr;
}

static void insert(DP_LayerRoutes *lr, DP_DrawContext *dc, DP_LayerProps *lp,
bool is_group)
static DP_LayerRoutesEntry *insert(DP_LayerRoutes *lr, DP_DrawContext *dc,
DP_LayerProps *lp, bool is_group,
DP_LayerRoutesEntry *parent_lre)
{
int index_count;
int *indexes = DP_draw_context_layer_indexes(dc, &index_count);
Expand All @@ -66,26 +68,29 @@ static void insert(DP_LayerRoutes *lr, DP_DrawContext *dc, DP_LayerProps *lp,
DP_LayerRoutesEntry, indexes, DP_int_to_size(index_count)));
lre->layer_id = DP_layer_props_id(lp);
lre->is_group = is_group;
lre->parent_lre = parent_lre;
lre->index_count = index_count;
for (int i = 0; i < index_count; ++i) {
lre->indexes[i] = indexes[i];
}

HASH_ADD_INT(lr->entries, layer_id, lre);
return lre;
}

static void index_layers(DP_LayerRoutes *lr, DP_DrawContext *dc,
DP_LayerPropsList *lpl)
DP_LayerPropsList *lpl,
DP_LayerRoutesEntry *parent_lre)
{
int count = DP_layer_props_list_count(lpl);
DP_draw_context_layer_indexes_push(dc);
for (int i = 0; i < count; ++i) {
DP_draw_context_layer_indexes_set(dc, i);
DP_LayerProps *lp = DP_layer_props_list_at_noinc(lpl, i);
DP_LayerPropsList *child_lpl = DP_layer_props_children_noinc(lp);
insert(lr, dc, lp, child_lpl);
DP_LayerRoutesEntry *lre = insert(lr, dc, lp, child_lpl, parent_lre);
if (child_lpl) {
index_layers(lr, dc, child_lpl);
index_layers(lr, dc, child_lpl, lre);
}
}
DP_draw_context_layer_indexes_pop(dc);
Expand All @@ -98,7 +103,7 @@ DP_LayerRoutes *DP_layer_routes_new_index(DP_LayerPropsList *lpl,
DP_ASSERT(dc);
DP_LayerRoutes *lr = DP_layer_routes_new();
DP_draw_context_layer_indexes_clear(dc);
index_layers(lr, dc, lpl);
index_layers(lr, dc, lpl, NULL);
return lr;
}

Expand Down Expand Up @@ -145,6 +150,19 @@ DP_LayerRoutesEntry *DP_layer_routes_search(DP_LayerRoutes *lr, int layer_id)
return lre;
}

int DP_layer_routes_search_parent_id(DP_LayerRoutes *lr, int layer_id)
{
DP_ASSERT(lr);
DP_LayerRoutesEntry *child_lre = DP_layer_routes_search(lr, layer_id);
if (child_lre) {
DP_LayerRoutesEntry *lre = DP_layer_routes_entry_parent(child_lre);
if (lre) {
return lre->layer_id;
}
}
return 0;
}


struct DP_MakeLayerOrderContext {
int source_id;
Expand Down Expand Up @@ -457,6 +475,12 @@ void DP_layer_routes_entry_children(DP_LayerRoutesEntry *lre,
get_children(lre->index_count, lre->indexes, cs, out_ll, out_lpl);
}

DP_LayerRoutesEntry *DP_layer_routes_entry_parent(DP_LayerRoutesEntry *lre)
{
DP_ASSERT(lre);
return lre->parent_lre;
}

uint16_t DP_layer_routes_entry_parent_opacity(DP_LayerRoutesEntry *lre,
DP_CanvasState *cs)
{
Expand Down
4 changes: 4 additions & 0 deletions src/drawdance/libengine/dpengine/layer_routes.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ void DP_layer_routes_decref_nullable(DP_LayerRoutes *lr_or_null);

DP_LayerRoutesEntry *DP_layer_routes_search(DP_LayerRoutes *lr, int layer_id);

int DP_layer_routes_search_parent_id(DP_LayerRoutes *lr, int layer_id);

DP_Message *DP_layer_routes_layer_order_make(DP_CanvasState *cs,
unsigned int context_id,
int source_id, int target_id,
Expand Down Expand Up @@ -105,6 +107,8 @@ void DP_layer_routes_entry_children(DP_LayerRoutesEntry *lre,
DP_CanvasState *cs, DP_LayerList **out_ll,
DP_LayerPropsList **out_lpl);

DP_LayerRoutesEntry *DP_layer_routes_entry_parent(DP_LayerRoutesEntry *lre);

uint16_t DP_layer_routes_entry_parent_opacity(DP_LayerRoutesEntry *lre,
DP_CanvasState *cs);

Expand Down
8 changes: 7 additions & 1 deletion src/drawdance/libengine/dpengine/local_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ static void handle_view_mode(DP_LocalState *ls, DP_MsgLocalChange *mlc)
switch (value) {
case DP_VIEW_MODE_NORMAL:
case DP_VIEW_MODE_LAYER:
case DP_VIEW_MODE_GROUP:
case DP_VIEW_MODE_FRAME: {
DP_ViewMode view_mode = (DP_ViewMode)value;
if (view_mode != ls->view_mode) {
Expand All @@ -311,8 +312,13 @@ static void handle_active_layer(DP_LocalState *ls, DP_MsgLocalChange *mlc)
if (read_int_message(mlc, "active layer", &layer_id)) {
if (ls->active_layer_id != layer_id) {
ls->active_layer_id = layer_id;
if (ls->view_mode == DP_VIEW_MODE_LAYER) {
switch (ls->view_mode) {
case DP_VIEW_MODE_LAYER:
case DP_VIEW_MODE_GROUP:
notify_view_invalidated(ls, true, 0);
break;
default:
break;
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/drawdance/libengine/dpengine/paint_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -1697,11 +1697,16 @@ static DP_CanvasState *apply_local_background_tile(DP_PaintEngine *pe,
}
}

static int get_only_layer_id(DP_LocalState *ls)
static int get_only_layer_id(DP_LocalState *ls, DP_CanvasState *cs)
{
switch (DP_local_state_view_mode(ls)) {
case DP_VIEW_MODE_LAYER:
return DP_local_state_active_layer_id(ls);
case DP_VIEW_MODE_GROUP: {
DP_LayerRoutes *lr = DP_canvas_state_layer_routes_noinc(cs);
return DP_layer_routes_search_parent_id(
lr, DP_local_state_active_layer_id(ls));
}
default:
return 0;
}
Expand All @@ -1719,7 +1724,8 @@ emit_changes(DP_PaintEngine *pe, DP_CanvasState *prev, DP_CanvasState *cs,
DP_PaintEngineCursorMovedFn cursor_moved, void *user)
{
DP_CanvasDiff *diff = pe->diff;
DP_canvas_state_diff(cs, prev, diff, get_only_layer_id(pe->local_state));
DP_canvas_state_diff(cs, prev, diff,
get_only_layer_id(pe->local_state, cs));
DP_renderer_apply(pe->renderer, cs, pe->local_state, diff,
pe->local_view.layers_can_decrease_opacity,
pe->local_view.checker_color1,
Expand Down
11 changes: 8 additions & 3 deletions src/drawdance/libengine/dpengine/renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,10 @@ DP_Renderer *DP_renderer_new(int thread_count, bool checker,
renderer->checker_color1 = checker_color1;
renderer->checker_color2 = checker_color2;
renderer->checker =
checker ? DP_transient_tile_new_checker(
0, DP_pixel8_to_15(checker_color1), DP_pixel8_to_15(checker_color2))
: NULL;
checker
? DP_transient_tile_new_checker(0, DP_pixel8_to_15(checker_color1),
DP_pixel8_to_15(checker_color2))
: NULL;
renderer->cs = DP_canvas_state_new();
renderer->checkers_visible = false;
renderer->xtiles = 0;
Expand Down Expand Up @@ -465,6 +466,7 @@ static bool local_state_params_differ(DP_RendererLocalState *rls,
case DP_VIEW_MODE_NORMAL:
return false;
case DP_VIEW_MODE_LAYER:
case DP_VIEW_MODE_GROUP:
return rls->active != DP_local_state_active_layer_id(ls);
case DP_VIEW_MODE_FRAME:
return rls->active != DP_local_state_active_frame_index(ls)
Expand All @@ -487,6 +489,9 @@ static DP_RendererLocalState clone_local_state(DP_LocalState *ls)
case DP_VIEW_MODE_LAYER:
return (DP_RendererLocalState){
DP_VIEW_MODE_LAYER, DP_local_state_active_layer_id(ls), NULL};
case DP_VIEW_MODE_GROUP:
return (DP_RendererLocalState){
DP_VIEW_MODE_GROUP, DP_local_state_active_layer_id(ls), NULL};
case DP_VIEW_MODE_FRAME:
return (DP_RendererLocalState){
DP_VIEW_MODE_FRAME, DP_local_state_active_frame_index(ls),
Expand Down
40 changes: 36 additions & 4 deletions src/drawdance/libengine/dpengine/view_mode.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,12 @@ DP_ViewModeFilter DP_view_mode_filter_make(DP_ViewModeBuffer *vmb,
return make_normal_filter();
case DP_VIEW_MODE_LAYER:
return make_layer_filter(layer_id);
case DP_VIEW_MODE_GROUP: {
DP_LayerRoutes *lr = DP_canvas_state_layer_routes_noinc(cs);
int group_id = DP_layer_routes_search_parent_id(lr, layer_id);
return group_id > 0 ? make_layer_filter(group_id)
: make_normal_filter();
}
case DP_VIEW_MODE_FRAME:
return make_frame_filter(vmb, cs, frame_index, oss, TYPE_FRAME_MANUAL);
default:
Expand Down Expand Up @@ -687,16 +693,37 @@ static bool pick_normal(DP_CanvasState *cs, int x, int y,
out_pick);
}

static bool pick_lre(DP_LayerRoutesEntry *lre, DP_CanvasState *cs, int x, int y,
DP_ViewModePick *out_pick)
{
if (lre) {
DP_LayerListEntry *lle = DP_layer_routes_entry_layer(lre, cs);
DP_LayerProps *lp = DP_layer_routes_entry_props(lre, cs);
return pick_entry(lle, lp, x, y, out_pick);
}
else {
return false;
}
}

static bool pick_layer(DP_CanvasState *cs, DP_LocalState *ls, int x, int y,
DP_ViewModePick *out_pick)
{
DP_LayerRoutes *lr = DP_canvas_state_layer_routes_noinc(cs);
DP_LayerRoutesEntry *lre =
DP_layer_routes_search(lr, DP_local_state_active_layer_id(ls));
if (lre) {
DP_LayerListEntry *lle = DP_layer_routes_entry_layer(lre, cs);
DP_LayerProps *lp = DP_layer_routes_entry_props(lre, cs);
return pick_entry(lle, lp, x, y, out_pick);
return pick_lre(lre, cs, x, y, out_pick);
}

static bool pick_group(DP_CanvasState *cs, DP_LocalState *ls, int x, int y,
DP_ViewModePick *out_pick)
{
DP_LayerRoutes *lr = DP_canvas_state_layer_routes_noinc(cs);
DP_LayerRoutesEntry *child_lre =
DP_layer_routes_search(lr, DP_local_state_active_layer_id(ls));
if (child_lre) {
DP_LayerRoutesEntry *lre = DP_layer_routes_entry_parent(child_lre);
return pick_lre(lre, cs, x, y, out_pick);
}
else {
return false;
Expand Down Expand Up @@ -754,6 +781,11 @@ DP_ViewModePick DP_view_mode_pick(DP_CanvasState *cs, DP_LocalState *ls, int x,
return pick;
}
break;
case DP_VIEW_MODE_GROUP:
if (pick_group(cs, ls, x, y, &pick)) {
return pick;
}
break;
case DP_VIEW_MODE_FRAME:
if (pick_frame(cs, ls, x, y, &pick)) {
return pick;
Expand Down
1 change: 1 addition & 0 deletions src/drawdance/libengine/dpengine/view_mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ typedef struct DP_LocalState DP_LocalState;
typedef enum DP_ViewMode {
DP_VIEW_MODE_NORMAL,
DP_VIEW_MODE_LAYER,
DP_VIEW_MODE_GROUP,
DP_VIEW_MODE_FRAME,
} DP_ViewMode;

Expand Down
3 changes: 2 additions & 1 deletion src/drawdance/rust/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5088,7 +5088,8 @@ pub struct DP_LocalState {
}
pub const DP_VIEW_MODE_NORMAL: DP_ViewMode = 0;
pub const DP_VIEW_MODE_LAYER: DP_ViewMode = 1;
pub const DP_VIEW_MODE_FRAME: DP_ViewMode = 2;
pub const DP_VIEW_MODE_GROUP: DP_ViewMode = 2;
pub const DP_VIEW_MODE_FRAME: DP_ViewMode = 3;
pub type DP_ViewMode = ::std::os::raw::c_uint;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
Expand Down

0 comments on commit fe9928b

Please sign in to comment.