UI Experiment: Undo History Timestamps #118884
|
@ -81,6 +81,8 @@ struct UndoStep {
|
|||
bool use_old_bmain_data;
|
||||
/** For use by undo systems that accumulate changes (mesh-sculpt & image-painting). */
|
||||
bool is_applied;
|
||||
/** Time that this step was created. */
|
||||
time_t timestamp;
|
||||
/* Over alloc 'type->struct_size'. */
|
||||
};
|
||||
|
||||
|
|
|
@ -556,6 +556,8 @@ eUndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack,
|
|||
us->type = ut;
|
||||
/* True by default, code needs to explicitly set it to false if necessary. */
|
||||
us->use_old_bmain_data = true;
|
||||
us->timestamp = time(nullptr);
|
||||
|
||||
/* Initialized, not added yet. */
|
||||
|
||||
CLOG_INFO(&LOG, 1, "addr=%p, name='%s', type='%s'", us, us->name, us->type->name);
|
||||
|
|
|
@ -2677,6 +2677,7 @@ void uiTemplateColormanagedViewSettings(uiLayout *layout,
|
|||
|
||||
int uiTemplateRecentFiles(uiLayout *layout, int rows);
|
||||
void uiTemplateFileSelectPath(uiLayout *layout, bContext *C, FileSelectParams *params);
|
||||
int uiTemplateUndoHistory(uiLayout *layout, wmWindowManager *wm);
|
||||
|
||||
enum {
|
||||
UI_TEMPLATE_ASSET_DRAW_NO_NAMES = (1 << 0),
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#include "BKE_scene.hh"
|
||||
#include "BKE_screen.hh"
|
||||
#include "BKE_shader_fx.h"
|
||||
#include "BKE_undo_system.hh"
|
||||
|
||||
#include "BLO_readfile.hh"
|
||||
|
||||
|
@ -7207,6 +7208,64 @@ int uiTemplateRecentFiles(uiLayout *layout, int rows)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name History List Template
|
||||
* \{ */
|
||||
|
||||
int uiTemplateUndoHistory(uiLayout *layout, wmWindowManager *wm)
|
||||
{
|
||||
if (wm->undo_stack == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
|
||||
uiLayout *column = uiLayoutColumn(split, false);
|
||||
int rows = 0;
|
||||
|
||||
int undo_steps = BLI_listbase_count(&wm->undo_stack->steps);
|
||||
const int col_size = 20 + (undo_steps / 12);
|
||||
|
||||
struct tm *tm_local;
|
||||
char str[FILE_MAX];
|
||||
|
||||
/* Reverse the order so the most recent state is first in the menu. */
|
||||
int i = undo_steps;
|
||||
LISTBASE_FOREACH_BACKWARD (UndoStep *, us, &wm->undo_stack->steps) {
|
||||
i--;
|
||||
if (us->skip) {
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
|
||||
tm_local = localtime(&us->timestamp);
|
||||
SNPRINTF_RLEN(str,
|
||||
"%s|%02i:%02i:%02i",
|
||||
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, us->name),
|
||||
tm_local->tm_hour,
|
||||
tm_local->tm_min,
|
||||
tm_local->tm_sec);
|
||||
|
||||
uiItemIntO(
|
||||
row, str, is_active ? ICON_LAYER_ACTIVE : ICON_NONE, "ED_OT_undo_history", "item", i);
|
||||
|
||||
uiBlock *block = uiLayoutGetBlock(row);
|
||||
uiBut *but = ui_but_last(block);
|
||||
UI_but_flag_enable(but, UI_BUT_HAS_SEP_CHAR);
|
||||
|
||||
rows += 1;
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name FileSelectParams Path Button Template
|
||||
* \{ */
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_screen.hh"
|
||||
#include "BKE_undo_system.hh"
|
||||
|
||||
#include "ED_screen.hh"
|
||||
#include "ED_space_api.hh"
|
||||
|
@ -211,49 +210,7 @@ static void recent_files_menu_register()
|
|||
|
||||
static void undo_history_draw_menu(const bContext *C, Menu *menu)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
if (wm->undo_stack == nullptr) {
|
||||
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;
|
||||
|
||||
const int col_size = 20 + (undo_step_count / 12);
|
||||
|
||||
undo_step_count = 0;
|
||||
|
||||
/* 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--)
|
||||
{
|
||||
if (us->skip) {
|
||||
continue;
|
||||
}
|
||||
if (!(undo_step_count % 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,
|
||||
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, us->name),
|
||||
is_active ? ICON_LAYER_ACTIVE : ICON_NONE,
|
||||
"ED_OT_undo_history",
|
||||
"item",
|
||||
i);
|
||||
undo_step_count += 1;
|
||||
}
|
||||
uiTemplateUndoHistory(menu->layout, CTX_wm_manager(C));
|
||||
}
|
||||
|
||||
static void undo_history_menu_register()
|
||||
|
|
Loading…
Reference in New Issue