UI Experiment: Named Undo Snapshots #118091

Closed
Harley Acheson wants to merge 4 commits from Harley/blender:UndoWaypoints into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 78 additions and 18 deletions

View File

@ -40,6 +40,7 @@ void ED_undo_pop(bContext *C);
void ED_undo_redo(bContext *C);
void ED_OT_undo(wmOperatorType *ot);
void ED_OT_undo_push(wmOperatorType *ot);
void ED_OT_undo_push_snapshot(wmOperatorType *ot);
void ED_OT_redo(wmOperatorType *ot);
void ED_OT_undo_redo(wmOperatorType *ot);
void ED_OT_undo_history(wmOperatorType *ot);

View File

@ -216,34 +216,30 @@ static void undo_history_draw_menu(const bContext *C, Menu *menu)
return;
}
int undo_step_count = 0;
int undo_step_count_all = 0;
LISTBASE_FOREACH_BACKWARD (UndoStep *, us, &wm->undo_stack->steps) {
undo_step_count_all += 1;
if (us->skip) {
continue;
}
undo_step_count += 1;
}
uiLayout *split = uiLayoutSplit(menu->layout, 0.0f, false);
uiLayout *column = nullptr;
uiLayout *column = uiLayoutColumn(split, false);
const int col_size = 20 + (undo_step_count / 12);
uiItemO(column, IFACE_("Add Snapshot"), ICON_ADD, "ED_OT_undo_push_snapshot");
uiItemS(column);
undo_step_count = 0;
int rows = 2;
int undo_steps = BLI_listbase_count(&wm->undo_stack->steps);
const int col_size = 20 + (undo_steps / 12);
/* Reverse the order so the most recent state is first in the menu. */
int i = undo_step_count_all - 1;
for (UndoStep *us = static_cast<UndoStep *>(wm->undo_stack->steps.last); us; us = us->prev, i--)
{
int i = undo_steps;
LISTBASE_FOREACH_BACKWARD (UndoStep *, us, &wm->undo_stack->steps) {
i--;
if (us->skip) {
continue;
}
if (!(undo_step_count % col_size)) {
if (rows > 0 && !(rows % col_size)) {
column = uiLayoutColumn(split, false);
}
const bool is_active = (us == wm->undo_stack->step_active);
uiLayout *row = uiLayoutRow(column, false);
uiLayoutSetEnabled(row, !is_active);
uiItemIntO(row,
@ -252,7 +248,7 @@ static void undo_history_draw_menu(const bContext *C, Menu *menu)
"ED_OT_undo_history",
"item",
i);
undo_step_count += 1;
rows += 1;
}
}

View File

@ -16,6 +16,7 @@
#include "DNA_scene_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLT_translation.hh"
@ -625,6 +626,67 @@ void ED_OT_undo_push(wmOperatorType *ot)
"");
}
static int ed_undo_push_snapshot_exec(bContext *C, wmOperator *op)
{
if (G.background) {
/* Exception for background mode, see: #60934.
* NOTE: since the undo stack isn't initialized on startup, background mode behavior
* won't match regular usage, this is just for scripts to do explicit undo pushes. */
wmWindowManager *wm = CTX_wm_manager(C);
if (wm->undo_stack == nullptr) {
wm->undo_stack = BKE_undosys_stack_create();
}
}
char str[BKE_UNDO_STR_MAX];
RNA_string_get(op->ptr, "message", str);
ED_undo_push(C, str);
RNA_string_set(op->ptr, "message", "");
return OPERATOR_FINISHED;
}
static int ed_undo_push_snapshot_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
return WM_operator_props_dialog_popup(C, op, 200, IFACE_("Add Undo Snapshot"), IFACE_("Add"));
}
static void ed_undo_push_snapshot_ui(bContext *C, wmOperator *op)
{
uiLayout *layout = op->layout;
wmWindowManager *wm = CTX_wm_manager(C);
char str[FILE_MAX];
RNA_string_get(op->ptr, "message", str);
if (!str[0]) {
time_t time_now = time(NULL);
struct tm *tm_local = localtime(&time_now);
char time_str[26];
strftime(time_str, 26, "%H:%M:%S", tm_local);
SNPRINTF_RLEN(str, "Snapshot at %s", time_str);
RNA_string_set(op->ptr, "message", str);
}
uiItemL(layout, "Description", ICON_NONE);
uiItemR(layout, op->ptr, "message", UI_ITEM_NONE, "", ICON_NONE);
}
void ED_OT_undo_push_snapshot(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Add Snapshot";
ot->description = "Add an undo snapshot";
ot->idname = "ED_OT_undo_push_snapshot";
/* api callbacks */
ot->invoke = ed_undo_push_snapshot_invoke;
ot->exec = ed_undo_push_snapshot_exec;
ot->poll = ED_operator_screenactive;
ot->ui = ed_undo_push_snapshot_ui;
/* properties */
RNA_def_string(ot->srna, "message", nullptr, BKE_UNDO_STR_MAX, "Snapshot description", "");
}
static bool ed_redo_poll(bContext *C)
{
if (!ed_undo_is_init_and_screenactive_poll(C)) {

View File

@ -415,6 +415,7 @@ void ED_operatortypes_edutils()
WM_operatortype_append(ED_OT_undo);
WM_operatortype_append(ED_OT_undo_push);
WM_operatortype_append(ED_OT_undo_push_snapshot);
WM_operatortype_append(ED_OT_redo);
WM_operatortype_append(ED_OT_undo_redo);
WM_operatortype_append(ED_OT_undo_history);