UI: Improved Operator Confirmations #104670
|
@ -511,6 +511,13 @@ static PathUsersMap bake_simulation_get_path_users(bContext *C, const Span<Objec
|
|||
return path_users;
|
||||
}
|
||||
|
||||
static void bake_simulation_warning(bContext * /*C*/,
|
||||
wmOperator * /*op*/,
|
||||
wmWarningDetails *warning)
|
||||
{
|
||||
STRNCPY(warning->message, "Overwrite existing bake data");
|
||||
}
|
||||
|
||||
static int bake_simulation_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
|
||||
{
|
||||
Vector<Object *> objects;
|
||||
|
@ -554,7 +561,7 @@ static int bake_simulation_invoke(bContext *C, wmOperator *op, const wmEvent * /
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
if (has_existing_bake_data) {
|
||||
return WM_operator_confirm_message(C, op, "Overwrite existing bake data");
|
||||
return WM_operator_confirm(C, op, nullptr);
|
||||
}
|
||||
return bake_simulation_exec(C, op);
|
||||
}
|
||||
|
@ -651,6 +658,7 @@ void OBJECT_OT_simulation_nodes_cache_bake(wmOperatorType *ot)
|
|||
ot->invoke = bake_simulation_invoke;
|
||||
ot->modal = bake_simulation_modal;
|
||||
ot->poll = bake_simulation_poll;
|
||||
ot->warning = bake_simulation_warning;
|
||||
|
||||
RNA_def_boolean(ot->srna, "selected", false, "Selected", "Bake cache on all selected objects");
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_armature.h"
|
||||
|
@ -1804,6 +1806,14 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
|
|||
return modifier_apply_exec_ex(C, op, MODIFIER_APPLY_DATA, false);
|
||||
}
|
||||
|
||||
static void modifier_apply_warning(bContext * /*C*/,
|
||||
wmOperator * /*op*/,
|
||||
wmWarningDetails *warning)
|
||||
{
|
||||
STRNCPY(warning->message, IFACE_("Make object data single-user and apply modifier"));
|
||||
STRNCPY(warning->confirm_button, IFACE_("Apply"));
|
||||
}
|
||||
|
||||
static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
int retval;
|
||||
|
@ -1817,8 +1827,7 @@ static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *eve
|
|||
RNA_property_boolean_set(op->ptr, prop, true);
|
||||
}
|
||||
if (RNA_property_boolean_get(op->ptr, prop)) {
|
||||
return WM_operator_confirm_message(
|
||||
C, op, "Make object data single-user and apply modifier");
|
||||
return WM_operator_confirm(C, op, nullptr);
|
||||
}
|
||||
}
|
||||
return modifier_apply_exec(C, op);
|
||||
|
@ -1835,6 +1844,7 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
|
|||
ot->invoke = modifier_apply_invoke;
|
||||
ot->exec = modifier_apply_exec;
|
||||
ot->poll = modifier_apply_poll;
|
||||
ot->warning = modifier_apply_warning;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_curve.h"
|
||||
|
@ -1153,6 +1155,14 @@ static int object_transform_apply_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void object_transform_apply_warning(bContext * /*C*/,
|
||||
wmOperator * /*op*/,
|
||||
wmWarningDetails *warning)
|
||||
{
|
||||
STRNCPY(warning->message, IFACE_("Create new object-data users and apply transformation"));
|
||||
STRNCPY(warning->confirm_button, IFACE_("Apply"));
|
||||
}
|
||||
|
||||
static int object_transform_apply_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
|
||||
{
|
||||
Object *ob = ED_object_active_context(C);
|
||||
|
@ -1166,8 +1176,7 @@ static int object_transform_apply_invoke(bContext *C, wmOperator *op, const wmEv
|
|||
RNA_property_boolean_set(op->ptr, prop, true);
|
||||
}
|
||||
if (RNA_property_boolean_get(op->ptr, prop)) {
|
||||
return WM_operator_confirm_message(
|
||||
C, op, "Create new object-data users and apply transformation");
|
||||
return WM_operator_confirm(C, op, nullptr);
|
||||
}
|
||||
}
|
||||
return object_transform_apply_exec(C, op);
|
||||
|
@ -1184,6 +1193,7 @@ void OBJECT_OT_transform_apply(wmOperatorType *ot)
|
|||
ot->exec = object_transform_apply_exec;
|
||||
ot->invoke = object_transform_apply_invoke;
|
||||
ot->poll = ED_operator_objectmode;
|
||||
ot->warning = object_transform_apply_warning;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
|
|
@ -87,10 +87,13 @@ static int unpack_libraries_exec(bContext *C, wmOperator *op)
|
|||
/** \name Unpack Blend File Libraries Operator
|
||||
* \{ */
|
||||
|
||||
static int unpack_libraries_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
|
||||
static void unpack_libraries_warning(bContext * /* C */,
|
||||
wmOperator * /* op */,
|
||||
wmWarningDetails *warning)
|
||||
{
|
||||
return WM_operator_confirm_message(
|
||||
C, op, "Unpack Linked Libraries - creates directories, all new paths should work");
|
||||
STRNCPY(warning->message, IFACE_("Creates directories, all new paths should work"));
|
||||
STRNCPY(warning->confirm_button, IFACE_("Unpack"));
|
||||
warning->icon = ALERT_ICON_INFO;
|
||||
}
|
||||
|
||||
void FILE_OT_unpack_libraries(wmOperatorType *ot)
|
||||
|
@ -101,8 +104,9 @@ void FILE_OT_unpack_libraries(wmOperatorType *ot)
|
|||
ot->description = "Restore all packed linked data-blocks to their original locations";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = unpack_libraries_invoke;
|
||||
ot->invoke = WM_operator_confirm;
|
||||
ot->exec = unpack_libraries_exec;
|
||||
ot->warning = unpack_libraries_warning;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
@ -158,7 +162,14 @@ static int pack_all_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int pack_all_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
|
||||
static void pack_all_warning(bContext * /* C */, wmOperator * /* op */, wmWarningDetails *warning)
|
||||
{
|
||||
STRNCPY(warning->message,
|
||||
IFACE_("Some images are mofified. These changes will be lost. Continue?"));
|
||||
STRNCPY(warning->confirm_button, IFACE_("Pack"));
|
||||
}
|
||||
|
||||
static int pack_all_invoke(bContext *C, wmOperator *op, const wmEvent * /* event */)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Image *ima;
|
||||
|
@ -173,8 +184,7 @@ static int pack_all_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*
|
|||
}
|
||||
|
||||
if (ima) {
|
||||
return WM_operator_confirm_message(
|
||||
C, op, "Some images are painted on. These changes will be lost. Continue?");
|
||||
return WM_operator_confirm(C, op, nullptr);
|
||||
}
|
||||
|
||||
return pack_all_exec(C, op);
|
||||
|
@ -190,6 +200,7 @@ void FILE_OT_pack_all(wmOperatorType *ot)
|
|||
/* api callbacks */
|
||||
ot->exec = pack_all_exec;
|
||||
ot->invoke = pack_all_invoke;
|
||||
ot->warning = pack_all_warning;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
|
|
@ -2131,6 +2131,43 @@ static bool ed_operator_outliner_id_orphans_active(bContext *C)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void orphans_purge_warning(bContext *C, wmOperator *op, wmWarningDetails *warning)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
int num_tagged[INDEX_ID_MAX] = {0};
|
||||
|
||||
const bool do_local_ids = RNA_boolean_get(op->ptr, "do_local_ids");
|
||||
const bool do_linked_ids = RNA_boolean_get(op->ptr, "do_linked_ids");
|
||||
const bool do_recursive_cleanup = RNA_boolean_get(op->ptr, "do_recursive");
|
||||
|
||||
/* Tag all IDs to delete. */
|
||||
BKE_lib_query_unused_ids_tag(
|
||||
bmain, LIB_TAG_DOIT, do_local_ids, do_linked_ids, do_recursive_cleanup, num_tagged);
|
||||
|
||||
DynStr *dyn_str = BLI_dynstr_new();
|
||||
bool is_first = true;
|
||||
for (int i = 0; i < INDEX_ID_MAX - 2; i++) {
|
||||
if (num_tagged[i] != 0) {
|
||||
if (!is_first) {
|
||||
BLI_dynstr_append(dyn_str, ", ");
|
||||
}
|
||||
else {
|
||||
is_first = false;
|
||||
}
|
||||
BLI_dynstr_appendf(dyn_str,
|
||||
"%d %s",
|
||||
num_tagged[i],
|
||||
TIP_(BKE_idtype_idcode_to_name_plural(BKE_idtype_idcode_from_index(i))));
|
||||
}
|
||||
}
|
||||
|
||||
STRNCPY(warning->title, IFACE_("Remove Unused Data"));
|
||||
STRNCPY(warning->message, BLI_dynstr_get_cstring(dyn_str));
|
||||
STRNCPY(warning->confirm_button, IFACE_("Purge"));
|
||||
|
||||
BLI_dynstr_free(dyn_str);
|
||||
}
|
||||
|
||||
static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
@ -2151,31 +2188,7 @@ static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEv
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
DynStr *dyn_str = BLI_dynstr_new();
|
||||
BLI_dynstr_appendf(dyn_str, TIP_("Purging %d unused data-blocks ("), num_tagged[INDEX_ID_NULL]);
|
||||
bool is_first = true;
|
||||
for (int i = 0; i < INDEX_ID_MAX - 2; i++) {
|
||||
if (num_tagged[i] != 0) {
|
||||
if (!is_first) {
|
||||
BLI_dynstr_append(dyn_str, ", ");
|
||||
}
|
||||
else {
|
||||
is_first = false;
|
||||
}
|
||||
BLI_dynstr_appendf(dyn_str,
|
||||
"%d %s",
|
||||
num_tagged[i],
|
||||
TIP_(BKE_idtype_idcode_to_name_plural(BKE_idtype_idcode_from_index(i))));
|
||||
}
|
||||
}
|
||||
BLI_dynstr_append(dyn_str, TIP_("). Click here to proceed..."));
|
||||
|
||||
char *message = BLI_dynstr_get_cstring(dyn_str);
|
||||
int ret = WM_operator_confirm_message(C, op, message);
|
||||
|
||||
MEM_freeN(message);
|
||||
BLI_dynstr_free(dyn_str);
|
||||
return ret;
|
||||
return WM_operator_confirm(C, op, nullptr);
|
||||
}
|
||||
|
||||
static int outliner_orphans_purge_exec(bContext *C, wmOperator *op)
|
||||
|
@ -2232,6 +2245,7 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot)
|
|||
ot->invoke = outliner_orphans_purge_invoke;
|
||||
ot->exec = outliner_orphans_purge_exec;
|
||||
ot->poll = ed_operator_outliner_id_orphans_active;
|
||||
ot->warning = orphans_purge_warning;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
|
|
@ -716,17 +716,6 @@ int WM_operator_props_dialog_popup(struct bContext *C, struct wmOperator *op, in
|
|||
int WM_operator_redo_popup(struct bContext *C, struct wmOperator *op);
|
||||
int WM_operator_ui_popup(struct bContext *C, struct wmOperator *op, int width);
|
||||
|
||||
/**
|
||||
* Can't be used as an invoke directly, needs message arg (can be NULL).
|
||||
*/
|
||||
int WM_operator_confirm_message_ex(struct bContext *C,
|
||||
struct wmOperator *op,
|
||||
const char *title,
|
||||
int icon,
|
||||
const char *message,
|
||||
wmOperatorCallContext opcontext);
|
||||
int WM_operator_confirm_message(struct bContext *C, struct wmOperator *op, const char *message);
|
||||
|
||||
/* Operator API. */
|
||||
|
||||
void WM_operator_free(struct wmOperator *op);
|
||||
|
|
|
@ -907,6 +907,30 @@ typedef struct wmTimer {
|
|||
bool sleep;
|
||||
} wmTimer;
|
||||
|
||||
typedef enum wmWarningSize {
|
||||
WM_WARNING_SIZE_SMALL = 0,
|
||||
WM_WARNING_SIZE_LARGE,
|
||||
} wmWarningSize;
|
||||
|
||||
typedef enum wmWarningPosition {
|
||||
WM_WARNING_POSITION_MOUSE = 0,
|
||||
WM_WARNING_POSITION_CENTER,
|
||||
} wmWarningPosition;
|
||||
|
||||
typedef struct wmWarningDetails {
|
||||
char title[1024];
|
||||
char message[1024];
|
||||
char confirm_button[256];
|
||||
char cancel_button[256];
|
||||
int icon;
|
||||
wmWarningSize size;
|
||||
wmWarningPosition position;
|
||||
bool confirm_default;
|
||||
bool cancel_default;
|
||||
bool mouse_move_quit;
|
||||
bool red_alert;
|
||||
} wmWarningDetails;
|
||||
|
||||
typedef struct wmOperatorType {
|
||||
/** Text for UI, undo (should not exceed #OP_MAX_TYPENAME). */
|
||||
const char *name;
|
||||
|
@ -990,6 +1014,11 @@ typedef struct wmOperatorType {
|
|||
*/
|
||||
char *(*get_description)(struct bContext *C, struct wmOperatorType *, struct PointerRNA *);
|
||||
|
||||
/**
|
||||
* If using WM_operator_confirm the following can override all parts of the dialog.
|
||||
*/
|
||||
void (*warning)(struct bContext *C, struct wmOperator *, wmWarningDetails *warning);
|
||||
|
||||
/** rna for properties */
|
||||
struct StructRNA *srna;
|
||||
|
||||
|
|
|
@ -2275,6 +2275,13 @@ static int wm_homefile_write_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
static void save_homefile_warning(bContext * /*C*/, wmOperator * /*op*/, wmWarningDetails *warning)
|
||||
{
|
||||
STRNCPY(warning->confirm_button, IFACE_("Save"));
|
||||
warning->size = WM_WARNING_SIZE_LARGE;
|
||||
warning->position = WM_WARNING_POSITION_CENTER;
|
||||
}
|
||||
|
||||
void WM_OT_save_homefile(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Save Startup File";
|
||||
|
@ -2283,6 +2290,7 @@ void WM_OT_save_homefile(wmOperatorType *ot)
|
|||
|
||||
ot->invoke = WM_operator_confirm;
|
||||
ot->exec = wm_homefile_write_exec;
|
||||
ot->warning = save_homefile_warning;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -2439,6 +2447,19 @@ void WM_OT_read_userpref(wmOperatorType *ot)
|
|||
ot->exec = wm_userpref_read_exec;
|
||||
}
|
||||
|
||||
static void wm_userpref_read_factory_warning(bContext * /*C*/,
|
||||
wmOperator * /*op*/,
|
||||
wmWarningDetails *warning)
|
||||
{
|
||||
STRNCPY(warning->title, IFACE_("Load factory default preferences"));
|
||||
STRNCPY(warning->message,
|
||||
IFACE_("To make changes to preferences permanent, use \"Save Preferences\""));
|
||||
STRNCPY(warning->confirm_button, IFACE_("Load"));
|
||||
warning->icon = ALERT_ICON_BLENDER;
|
||||
warning->size = WM_WARNING_SIZE_LARGE;
|
||||
warning->position = WM_WARNING_POSITION_CENTER;
|
||||
}
|
||||
|
||||
void WM_OT_read_factory_userpref(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Load Factory Preferences";
|
||||
|
@ -2449,6 +2470,7 @@ void WM_OT_read_factory_userpref(wmOperatorType *ot)
|
|||
|
||||
ot->invoke = WM_operator_confirm;
|
||||
ot->exec = wm_userpref_read_exec;
|
||||
ot->warning = wm_userpref_read_factory_warning;
|
||||
|
||||
read_factory_reset_props(ot);
|
||||
}
|
||||
|
@ -2648,16 +2670,26 @@ void WM_OT_read_homefile(wmOperatorType *ot)
|
|||
/* omit poll to run in background mode */
|
||||
}
|
||||
|
||||
static void read_factory_warning(bContext * /*C*/, wmOperator * /*op*/, wmWarningDetails *warning)
|
||||
{
|
||||
STRNCPY(warning->title, IFACE_("Load factory default startup file and preferences."));
|
||||
STRNCPY(warning->message,
|
||||
IFACE_("To make changes permanent, use \"Save Startup File\" and \"Save Preferences\""));
|
||||
STRNCPY(warning->confirm_button, IFACE_("Load"));
|
||||
warning->icon = ALERT_ICON_BLENDER;
|
||||
warning->size = WM_WARNING_SIZE_LARGE;
|
||||
warning->position = WM_WARNING_POSITION_CENTER;
|
||||
}
|
||||
|
||||
void WM_OT_read_factory_settings(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Load Factory Settings";
|
||||
ot->idname = "WM_OT_read_factory_settings";
|
||||
ot->description =
|
||||
"Load factory default startup file and preferences. "
|
||||
"To make changes permanent, use \"Save Startup File\" and \"Save Preferences\"";
|
||||
ot->description = "Load factory default startup file and preferences";
|
||||
|
||||
ot->invoke = WM_operator_confirm;
|
||||
ot->exec = wm_homefile_read_exec;
|
||||
ot->warning = read_factory_warning;
|
||||
/* Omit poll to run in background mode. */
|
||||
|
||||
read_factory_reset_props(ot);
|
||||
|
|
|
@ -1170,6 +1170,168 @@ int WM_enum_search_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(eve
|
|||
return OPERATOR_INTERFACE;
|
||||
}
|
||||
|
||||
static void wm_operator_block_cancel(bContext *C, void *arg_op, void *arg_block)
|
||||
{
|
||||
wmOperator *op = arg_op;
|
||||
uiBlock *block = arg_block;
|
||||
UI_popup_block_close(C, CTX_wm_window(C), block);
|
||||
WM_redraw_windows(C);
|
||||
if (op) {
|
||||
if (op->type->cancel) {
|
||||
op->type->cancel(C, op);
|
||||
}
|
||||
WM_operator_free(op);
|
||||
}
|
||||
}
|
||||
|
||||
static void wm_operator_block_confirm(bContext *C, void *arg_op, void *arg_block)
|
||||
{
|
||||
wmOperator *op = arg_op;
|
||||
uiBlock *block = arg_block;
|
||||
UI_popup_block_close(C, CTX_wm_window(C), block);
|
||||
WM_redraw_windows(C);
|
||||
if (op) {
|
||||
WM_operator_call_ex(C, op, true);
|
||||
}
|
||||
}
|
||||
|
||||
static uiBlock *wm_block_confirm_create(bContext *C, ARegion *region, void *arg_op)
|
||||
{
|
||||
wmOperator *op = arg_op;
|
||||
|
||||
wmWarningDetails warning = {0};
|
||||
|
||||
/* Operator description must be freed. */
|
||||
char *desc = WM_operatortype_description(C, op->type, op->ptr);
|
||||
STRNCPY_RLEN(warning.title, desc);
|
||||
MEM_freeN(desc);
|
||||
|
||||
STRNCPY_RLEN(warning.confirm_button, WM_operatortype_name(op->type, op->ptr));
|
||||
STRNCPY_RLEN(warning.cancel_button, IFACE_("Cancel"));
|
||||
warning.icon = ALERT_ICON_WARNING;
|
||||
warning.size = WM_WARNING_SIZE_SMALL;
|
||||
warning.position = WM_WARNING_POSITION_MOUSE;
|
||||
warning.confirm_default = true;
|
||||
warning.cancel_default = false;
|
||||
warning.mouse_move_quit = false;
|
||||
warning.red_alert = false;
|
||||
|
||||
/* uiBlock.flag */
|
||||
int block_flags = UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP | UI_BLOCK_NUMSELECT;
|
||||
|
||||
if (op->type->warning) {
|
||||
op->type->warning(C, op, &warning);
|
||||
}
|
||||
if (warning.mouse_move_quit) {
|
||||
block_flags |= UI_BLOCK_MOVEMOUSE_QUIT;
|
||||
}
|
||||
if (warning.icon < ALERT_ICON_WARNING || warning.icon >= ALERT_ICON_MAX) {
|
||||
warning.icon = ALERT_ICON_QUESTION;
|
||||
}
|
||||
|
||||
uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
|
||||
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
|
||||
UI_block_flag_enable(block, block_flags);
|
||||
|
||||
const uiStyle *style = UI_style_get_dpi();
|
||||
int text_width = MAX3(
|
||||
120 * UI_SCALE_FAC,
|
||||
BLF_width(style->widget.uifont_id, warning.title, ARRAY_SIZE(warning.title)),
|
||||
BLF_width(style->widget.uifont_id, warning.message, ARRAY_SIZE(warning.message)));
|
||||
|
||||
const bool small = warning.size == WM_WARNING_SIZE_SMALL;
|
||||
const int padding = (small ? 7 : 14) * UI_SCALE_FAC;
|
||||
const short icon_size = (small ? (warning.message[0] ? 48 : 32) : 64) * UI_SCALE_FAC;
|
||||
const int dialog_width = icon_size + text_width + (style->columnspace * 2.5);
|
||||
const float split_factor = (float)icon_size / (float)(dialog_width - style->columnspace);
|
||||
|
||||
uiLayout *block_layout = UI_block_layout(
|
||||
block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, dialog_width, UI_UNIT_Y, 0, style);
|
||||
|
||||
/* Split layout to put alert icon on left side. */
|
||||
uiLayout *split_block = uiLayoutSplit(block_layout, split_factor, false);
|
||||
|
||||
/* Alert icon on the left. */
|
||||
uiLayout *layout = uiLayoutRow(split_block, true);
|
||||
/* Using 'align_left' with 'row' avoids stretching the icon along the width of column. */
|
||||
uiLayoutSetAlignment(layout, UI_LAYOUT_ALIGN_LEFT);
|
||||
uiDefButAlert(block, warning.icon, 0, 0, icon_size, icon_size);
|
||||
|
||||
/* The rest of the content on the right. */
|
||||
layout = uiLayoutColumn(split_block, true);
|
||||
|
||||
if (warning.title[0]) {
|
||||
if (!warning.message[0]) {
|
||||
uiItemS(layout);
|
||||
}
|
||||
uiItemL_ex(layout, warning.title, ICON_NONE, true, false);
|
||||
}
|
||||
if (warning.message[0]) {
|
||||
uiItemL(layout, warning.message, ICON_NONE);
|
||||
}
|
||||
|
||||
uiItemS_ex(layout, small ? 0.5f : 4.0f);
|
||||
|
||||
/* Buttons. */
|
||||
|
||||
#ifdef _WIN32
|
||||
const bool windows_layout = true;
|
||||
#else
|
||||
const bool windows_layout = false;
|
||||
#endif
|
||||
|
||||
uiBut *confirm = NULL;
|
||||
uiBut *cancel = NULL;
|
||||
int height = UI_UNIT_Y;
|
||||
uiLayout *split = uiLayoutSplit(small ? block_layout : layout, 0.0f, true);
|
||||
uiLayoutSetScaleY(split, small ? 1.1f : 1.2f);
|
||||
uiLayoutColumn(split, false);
|
||||
|
||||
if (windows_layout) {
|
||||
confirm = uiDefIconTextBut(
|
||||
block, UI_BTYPE_BUT, 0, 0, warning.confirm_button, 0, 0, 0, height, 0, 0, 0, 0, 0, NULL);
|
||||
uiLayoutColumn(split, false);
|
||||
}
|
||||
|
||||
cancel = uiDefIconTextBut(
|
||||
block, UI_BTYPE_BUT, 0, 0, warning.cancel_button, 0, 0, 0, height, 0, 0, 0, 0, 0, NULL);
|
||||
|
||||
if (!windows_layout) {
|
||||
uiLayoutColumn(split, false);
|
||||
confirm = uiDefIconTextBut(
|
||||
block, UI_BTYPE_BUT, 0, 0, warning.confirm_button, 0, 0, 0, height, 0, 0, 0, 0, 0, NULL);
|
||||
}
|
||||
|
||||
UI_block_func_set(block, NULL, NULL, NULL);
|
||||
UI_but_func_set(confirm, wm_operator_block_confirm, op, block);
|
||||
UI_but_func_set(cancel, wm_operator_block_cancel, op, block);
|
||||
UI_but_drawflag_disable(confirm, UI_BUT_TEXT_LEFT);
|
||||
UI_but_drawflag_disable(cancel, UI_BUT_TEXT_LEFT);
|
||||
|
||||
if (warning.red_alert) {
|
||||
UI_but_flag_enable(confirm, UI_BUT_REDALERT);
|
||||
}
|
||||
else {
|
||||
if (warning.cancel_default) {
|
||||
UI_but_flag_enable(cancel, UI_BUT_ACTIVE_DEFAULT);
|
||||
}
|
||||
else if (warning.confirm_default) {
|
||||
UI_but_flag_enable(confirm, UI_BUT_ACTIVE_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
if (warning.position == WM_WARNING_POSITION_MOUSE) {
|
||||
int x = uiLayoutGetWidth(layout) * (windows_layout ? -0.33f : -0.66f);
|
||||
int y = UI_UNIT_Y * (warning.message[0] ? 3.1 : 2.5);
|
||||
UI_block_bounds_set_popup(block, padding, (const int[2]){x, y});
|
||||
}
|
||||
else if (warning.position == WM_WARNING_POSITION_CENTER) {
|
||||
UI_block_bounds_set_centered(block, padding);
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
int WM_operator_confirm_message_ex(bContext *C,
|
||||
wmOperator *op,
|
||||
const char *title,
|
||||
|
@ -1196,6 +1358,11 @@ int WM_operator_confirm_message_ex(bContext *C,
|
|||
|
||||
int WM_operator_confirm_message(bContext *C, wmOperator *op, const char *message)
|
||||
{
|
||||
if (op->type->warning) {
|
||||
UI_popup_block_invoke(C, wm_block_confirm_create, op, NULL);
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
return WM_operator_confirm_message_ex(
|
||||
C, op, IFACE_("OK?"), ICON_QUESTION, message, WM_OP_EXEC_REGION_WIN);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue