2023-08-16 00:20:26 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2009 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2009-02-04 11:52:16 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup edinterface
|
2011-02-27 20:29:51 +00:00
|
|
|
*/
|
|
|
|
|
|
2025-01-26 20:08:00 +01:00
|
|
|
#include <algorithm>
|
2022-04-02 16:17:48 -05:00
|
|
|
#include <cctype>
|
|
|
|
|
#include <cstdio>
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <cstring>
|
2024-02-14 17:08:58 -05:00
|
|
|
#include <fmt/format.h>
|
2009-02-04 11:52:16 +00:00
|
|
|
|
2.5
Smaller jobs, all in one commit!
- Moved object_do_update out of view3d drawing, into
the event system (currently after notifiers).
Depsgraph calls for setting update flags will have to
keep track of each Screen's needs, so a UI showing only
a Sequencer doesn't do objects.
- Added button in "Properties region" in 3D window to set
or disable 4-split, including the 3 options it has.
(lock, box, clip)
- Restored legacy code for UI, to make things work like
bone rename, autocomplete.
- Node editor now shows Curves widgets again
- Bugfix: composite job increased Viewer user id count
- Bugfix: Node editor, not "Enable nodes" still called
a Job, which didn't do anything
- Various code cleaning, unused vars and prototypes.
2009-02-11 16:54:55 +00:00
|
|
|
#include "DNA_object_types.h"
|
2014-02-08 09:03:25 +11:00
|
|
|
#include "DNA_screen_types.h"
|
2009-06-10 11:43:21 +00:00
|
|
|
|
2023-08-04 23:11:22 +02:00
|
|
|
#include "ED_screen.hh"
|
2021-07-13 17:06:15 +02:00
|
|
|
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_listbase.h"
|
2011-09-26 16:53:04 +00:00
|
|
|
#include "BLI_string.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_utildefines.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
|
2024-02-09 18:59:42 +01:00
|
|
|
#include "BLT_translation.hh"
|
2011-06-15 11:41:15 +00:00
|
|
|
|
2023-11-16 11:41:55 +01:00
|
|
|
#include "BKE_context.hh"
|
2024-02-10 18:25:14 +01:00
|
|
|
#include "BKE_global.hh"
|
2024-03-26 12:57:30 -04:00
|
|
|
#include "BKE_idprop.hh"
|
2024-01-15 12:44:04 -05:00
|
|
|
#include "BKE_lib_id.hh"
|
2023-09-25 17:48:21 -04:00
|
|
|
#include "BKE_screen.hh"
|
2011-01-07 19:18:31 +00:00
|
|
|
|
2014-02-08 09:03:25 +11:00
|
|
|
#include "MEM_guardedalloc.h"
|
2009-02-04 11:52:16 +00:00
|
|
|
|
2023-08-10 22:40:27 +02:00
|
|
|
#include "RNA_access.hh"
|
2024-07-25 17:20:27 +02:00
|
|
|
#include "RNA_prototypes.hh"
|
2009-02-04 11:52:16 +00:00
|
|
|
|
2023-08-05 02:57:52 +02:00
|
|
|
#include "UI_interface.hh"
|
|
|
|
|
#include "UI_interface_icons.hh"
|
|
|
|
|
#include "UI_resources.hh"
|
2023-09-25 10:56:12 +02:00
|
|
|
#include "UI_string_search.hh"
|
2023-08-05 02:57:52 +02:00
|
|
|
#include "UI_view2d.hh"
|
2009-02-04 11:52:16 +00:00
|
|
|
|
2023-08-04 23:11:22 +02:00
|
|
|
#include "WM_api.hh"
|
|
|
|
|
#include "WM_types.hh"
|
2015-04-27 01:17:51 +10:00
|
|
|
|
2022-11-26 00:21:17 -06:00
|
|
|
#include "interface_intern.hh"
|
2014-02-08 09:03:25 +11:00
|
|
|
|
2025-05-19 17:25:52 +02:00
|
|
|
using blender::StringRef;
|
2024-12-06 14:08:10 +01:00
|
|
|
using blender::StringRefNull;
|
|
|
|
|
|
2009-02-04 11:52:16 +00:00
|
|
|
/*************************** RNA Utilities ******************************/
|
|
|
|
|
|
2010-12-03 17:05:21 +00:00
|
|
|
uiBut *uiDefAutoButR(uiBlock *block,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
PropertyRNA *prop,
|
|
|
|
|
int index,
|
2025-05-19 17:25:52 +02:00
|
|
|
const std::optional<StringRef> name,
|
2010-12-03 17:05:21 +00:00
|
|
|
int icon,
|
2021-03-19 20:22:37 +01:00
|
|
|
int x,
|
|
|
|
|
int y,
|
|
|
|
|
int width,
|
|
|
|
|
int height)
|
2009-02-04 11:52:16 +00:00
|
|
|
{
|
2022-04-02 16:17:48 -05:00
|
|
|
uiBut *but = nullptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-30 01:51:25 +00:00
|
|
|
switch (RNA_property_type(prop)) {
|
2011-08-06 16:00:00 +00:00
|
|
|
case PROP_BOOLEAN: {
|
2019-03-25 10:15:20 +11:00
|
|
|
if (RNA_property_array_check(prop) && index == -1) {
|
2022-04-02 16:17:48 -05:00
|
|
|
return nullptr;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-06 14:08:10 +01:00
|
|
|
if (icon && name && name->is_empty()) {
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefIconButR_prop(block,
|
|
|
|
|
UI_BTYPE_ICON_TOGGLE,
|
|
|
|
|
0,
|
|
|
|
|
icon,
|
2021-03-19 20:22:37 +01:00
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
2014-11-09 21:20:40 +01:00
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
index,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2025-02-14 15:12:48 -05:00
|
|
|
std::nullopt);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
else if (icon) {
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefIconTextButR_prop(block,
|
|
|
|
|
UI_BTYPE_ICON_TOGGLE,
|
|
|
|
|
0,
|
|
|
|
|
icon,
|
|
|
|
|
name,
|
2021-03-19 20:22:37 +01:00
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
2014-11-09 21:20:40 +01:00
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
index,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2025-02-14 15:12:48 -05:00
|
|
|
std::nullopt);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
else {
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_CHECKBOX,
|
|
|
|
|
0,
|
|
|
|
|
name,
|
2021-03-19 20:22:37 +01:00
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
2014-11-09 21:20:40 +01:00
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
index,
|
|
|
|
|
0,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2025-02-14 15:12:48 -05:00
|
|
|
std::nullopt);
|
2009-02-04 11:52:16 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2009-02-04 11:52:16 +00:00
|
|
|
case PROP_INT:
|
|
|
|
|
case PROP_FLOAT: {
|
2019-03-18 19:56:14 +01:00
|
|
|
if (RNA_property_array_check(prop) && index == -1) {
|
2014-12-30 07:37:59 +11:00
|
|
|
if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) {
|
2025-02-14 15:12:48 -05:00
|
|
|
but = uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_COLOR,
|
|
|
|
|
0,
|
|
|
|
|
name,
|
|
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
std::nullopt);
|
2014-12-30 07:37:59 +11:00
|
|
|
}
|
|
|
|
|
else {
|
2022-04-02 16:17:48 -05:00
|
|
|
return nullptr;
|
2009-02-04 11:52:16 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-03-25 10:15:20 +11:00
|
|
|
else if (RNA_property_subtype(prop) == PROP_PERCENTAGE ||
|
|
|
|
|
RNA_property_subtype(prop) == PROP_FACTOR)
|
|
|
|
|
{
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_NUM_SLIDER,
|
|
|
|
|
0,
|
|
|
|
|
name,
|
2021-03-19 20:22:37 +01:00
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
2014-11-09 21:20:40 +01:00
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
index,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2025-02-14 15:12:48 -05:00
|
|
|
std::nullopt);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
else {
|
2025-02-14 15:12:48 -05:00
|
|
|
but = uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_NUM,
|
|
|
|
|
0,
|
|
|
|
|
name,
|
|
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
index,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
std::nullopt);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-12-25 12:53:13 +01:00
|
|
|
if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
|
|
|
|
|
UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE);
|
|
|
|
|
}
|
2009-02-04 11:52:16 +00:00
|
|
|
break;
|
2011-08-06 16:00:00 +00:00
|
|
|
}
|
2009-02-04 11:52:16 +00:00
|
|
|
case PROP_ENUM:
|
2024-12-06 14:08:10 +01:00
|
|
|
if (icon && name && name->is_empty()) {
|
2025-02-14 15:12:48 -05:00
|
|
|
but = uiDefIconButR_prop(block,
|
|
|
|
|
UI_BTYPE_MENU,
|
|
|
|
|
0,
|
|
|
|
|
icon,
|
|
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
index,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
std::nullopt);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-03-25 10:15:20 +11:00
|
|
|
else if (icon) {
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefIconTextButR_prop(block,
|
|
|
|
|
UI_BTYPE_MENU,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
icon,
|
2024-12-06 14:08:10 +01:00
|
|
|
std::nullopt,
|
2021-03-19 20:22:37 +01:00
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
2019-04-17 06:17:24 +02:00
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
index,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2025-02-14 15:12:48 -05:00
|
|
|
std::nullopt);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
else {
|
2025-02-14 15:12:48 -05:00
|
|
|
but = uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_MENU,
|
|
|
|
|
0,
|
|
|
|
|
name,
|
|
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
index,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
std::nullopt);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2009-02-04 11:52:16 +00:00
|
|
|
break;
|
|
|
|
|
case PROP_STRING:
|
2024-12-06 14:08:10 +01:00
|
|
|
if (icon && name && name->is_empty()) {
|
2025-02-14 15:12:48 -05:00
|
|
|
but = uiDefIconButR_prop(block,
|
|
|
|
|
UI_BTYPE_TEXT,
|
|
|
|
|
0,
|
|
|
|
|
icon,
|
|
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
index,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
std::nullopt);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
else if (icon) {
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefIconTextButR_prop(block,
|
|
|
|
|
UI_BTYPE_TEXT,
|
|
|
|
|
0,
|
|
|
|
|
icon,
|
|
|
|
|
name,
|
2021-03-19 20:22:37 +01:00
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
2014-11-09 21:20:40 +01:00
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
index,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2025-02-14 15:12:48 -05:00
|
|
|
std::nullopt);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2018-09-27 15:35:22 +02:00
|
|
|
else {
|
2025-02-14 15:12:48 -05:00
|
|
|
but = uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_TEXT,
|
|
|
|
|
0,
|
|
|
|
|
name,
|
|
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
index,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
std::nullopt);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2014-12-25 12:53:13 +01:00
|
|
|
if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
|
2018-09-27 15:35:22 +02:00
|
|
|
/* TEXTEDIT_UPDATE is usually used for search buttons. For these we also want
|
2017-01-11 22:11:13 +01:00
|
|
|
* the 'x' icon to clear search string, so setting VALUE_CLEAR flag, too. */
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE | UI_BUT_VALUE_CLEAR);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
break;
|
2012-09-08 08:59:47 +00:00
|
|
|
case PROP_POINTER: {
|
2017-03-31 12:13:34 +02:00
|
|
|
if (icon == 0) {
|
2020-08-26 10:11:13 +10:00
|
|
|
const PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
|
2014-11-09 21:20:40 +01:00
|
|
|
icon = RNA_struct_ui_icon(pptr.type ? pptr.type : RNA_property_pointer_type(ptr, prop));
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-03-25 10:15:20 +11:00
|
|
|
if (icon == ICON_DOT) {
|
2012-03-30 01:51:25 +00:00
|
|
|
icon = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefIconTextButR_prop(block,
|
|
|
|
|
UI_BTYPE_SEARCH_MENU,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2014-11-09 21:20:40 +01:00
|
|
|
icon,
|
2019-04-17 06:17:24 +02:00
|
|
|
name,
|
2021-03-19 20:22:37 +01:00
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
2019-04-17 06:17:24 +02:00
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
index,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2025-02-14 15:12:48 -05:00
|
|
|
std::nullopt);
|
2022-04-04 03:50:55 +02:00
|
|
|
ui_but_add_search(but, ptr, prop, nullptr, nullptr, false);
|
2009-02-04 11:52:16 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2012-09-08 08:59:47 +00:00
|
|
|
case PROP_COLLECTION: {
|
2009-02-04 11:52:16 +00:00
|
|
|
char text[256];
|
2023-05-09 12:50:37 +10:00
|
|
|
SNPRINTF(text, IFACE_("%d items"), RNA_property_collection_length(ptr, prop));
|
2025-02-14 15:12:48 -05:00
|
|
|
but = uiDefBut(
|
|
|
|
|
block, UI_BTYPE_LABEL, 0, text, x, y, width, height, nullptr, 0, 0, std::nullopt);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
2009-02-04 11:52:16 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
2022-04-02 16:17:48 -05:00
|
|
|
but = nullptr;
|
2009-02-04 11:52:16 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-02-04 11:52:16 +00:00
|
|
|
return but;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-15 18:43:26 +01:00
|
|
|
void uiDefAutoButsArrayR(uiBlock *block,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
PropertyRNA *prop,
|
|
|
|
|
const int icon,
|
|
|
|
|
const int x,
|
|
|
|
|
const int y,
|
|
|
|
|
const int tot_width,
|
|
|
|
|
const int height)
|
|
|
|
|
{
|
|
|
|
|
const int len = RNA_property_array_length(ptr, prop);
|
|
|
|
|
if (len == 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const int item_width = tot_width / len;
|
|
|
|
|
|
|
|
|
|
UI_block_align_begin(block);
|
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
|
uiDefAutoButR(block, ptr, prop, i, "", icon, x + i * item_width, y, item_width, height);
|
|
|
|
|
}
|
|
|
|
|
UI_block_align_end(block);
|
|
|
|
|
}
|
|
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
|
2015-05-05 03:13:47 +10:00
|
|
|
PointerRNA *ptr,
|
2018-07-26 09:59:56 +10:00
|
|
|
bool (*check_prop)(PointerRNA *ptr,
|
|
|
|
|
PropertyRNA *prop,
|
|
|
|
|
void *user_data),
|
|
|
|
|
void *user_data,
|
2019-03-22 00:30:17 +11:00
|
|
|
PropertyRNA *prop_activate_init,
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
const eButLabelAlign label_align,
|
|
|
|
|
const bool compact)
|
2009-02-04 11:52:16 +00:00
|
|
|
{
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
eAutoPropButsReturn return_info = UI_PROP_BUTS_NONE_ADDED;
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
uiLayout *col;
|
2024-12-06 14:44:08 -05:00
|
|
|
std::optional<StringRefNull> name;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-30 16:22:40 +00:00
|
|
|
RNA_STRUCT_BEGIN (ptr, prop) {
|
2019-03-22 00:30:17 +11:00
|
|
|
const int flag = RNA_property_flag(prop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
if (flag & PROP_HIDDEN) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2018-07-26 13:50:56 +10:00
|
|
|
if (check_prop && check_prop(ptr, prop, user_data) == 0) {
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
return_info |= UI_PROP_BUTS_ANY_FAILED_CHECK;
|
2009-02-04 11:52:16 +00:00
|
|
|
continue;
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-22 00:30:17 +11:00
|
|
|
const PropertyType type = RNA_property_type(prop);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
switch (label_align) {
|
|
|
|
|
case UI_BUT_LABEL_ALIGN_COLUMN:
|
|
|
|
|
case UI_BUT_LABEL_ALIGN_SPLIT_COLUMN: {
|
|
|
|
|
const bool is_boolean = (type == PROP_BOOLEAN && !RNA_property_array_check(prop));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
name = RNA_property_ui_name(prop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
if (label_align == UI_BUT_LABEL_ALIGN_COLUMN) {
|
2025-04-26 21:07:34 +02:00
|
|
|
col = &layout->column(true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!is_boolean) {
|
2025-05-08 17:21:08 +02:00
|
|
|
col->label(*name, ICON_NONE);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_assert(label_align == UI_BUT_LABEL_ALIGN_SPLIT_COLUMN);
|
2025-04-26 21:07:34 +02:00
|
|
|
col = &layout->column(true);
|
2025-05-10 03:39:31 +02:00
|
|
|
/* Let uiLayout::prop() create the split layout. */
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
uiLayoutSetPropSep(col, true);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case UI_BUT_LABEL_ALIGN_NONE:
|
2018-05-02 10:32:01 +02:00
|
|
|
default:
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
col = layout;
|
2024-12-06 14:44:08 -05:00
|
|
|
name = std::nullopt; /* no smart label alignment, show default name with button */
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
break;
|
2009-06-24 21:27:10 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-22 00:30:17 +11:00
|
|
|
/* Only buttons that can be edited as text. */
|
|
|
|
|
const bool use_activate_init = ((prop == prop_activate_init) &&
|
2022-09-25 22:41:22 +10:00
|
|
|
ELEM(type, PROP_STRING, PROP_INT, PROP_FLOAT));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-22 00:30:17 +11:00
|
|
|
if (use_activate_init) {
|
|
|
|
|
uiLayoutSetActivateInit(col, true);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-05-10 03:39:31 +02:00
|
|
|
col->prop(ptr, prop, -1, 0, compact ? UI_ITEM_R_COMPACT : UI_ITEM_NONE, name, ICON_NONE);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
return_info &= ~UI_PROP_BUTS_NONE_ADDED;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-22 00:30:17 +11:00
|
|
|
if (use_activate_init) {
|
|
|
|
|
uiLayoutSetActivateInit(col, false);
|
|
|
|
|
}
|
2.5
Summary of ain features:
- Themes and Styles are now editable.
- CTRL+U "Save user defaults" now goes to new .B25.blend, so you
can use 2.4x and 2.5x next to each other. If B25 doesn't exist, it
reads the regular .B.blend
- Press Tkey in 3d window for (unfinished) toolbar WIP. It now only
shows the last operator, if appropriate.
Nkey properties moved to the other side.
A lot of work was done on removing old themes for good and properly
getting it work with the 2.5 region system. Here's some notes;
- Buttons now all have a complete set of colors, based on button classifications
(See outliner -> user prefs -> Interface
- Theme colors have been extended with basic colors for region types.
Currently colors are defined for Window, Header, List/Channels and
for Button/Tool views.
The screen manager handles this btw, so a TH_BACK will always pick the
right backdrop color.
- Menu backdrops are in in Button theme colors. Floating Panels will be in
the per-space type Themes.
- Styles were added in RNA too, but only for the font settings now.
Only Panel font, widget font and widget-label work now. The 'group label'
will be for templates mostly.
Style settings will be expanded with spacing defaults, label conventions,
etc.
- Label text colors are stored in per-space Theme too, to make sure they fit.
Same goes for Panel title color.
Note that 'shadow' for fonts can conflict with text colors; shadow color is
currently stored in Style... shadow code needs a bit of work still.
2009-04-27 13:44:11 +00:00
|
|
|
}
|
2009-06-24 21:27:10 +00:00
|
|
|
RNA_STRUCT_END;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
return return_info;
|
2.5
Summary of ain features:
- Themes and Styles are now editable.
- CTRL+U "Save user defaults" now goes to new .B25.blend, so you
can use 2.4x and 2.5x next to each other. If B25 doesn't exist, it
reads the regular .B.blend
- Press Tkey in 3d window for (unfinished) toolbar WIP. It now only
shows the last operator, if appropriate.
Nkey properties moved to the other side.
A lot of work was done on removing old themes for good and properly
getting it work with the 2.5 region system. Here's some notes;
- Buttons now all have a complete set of colors, based on button classifications
(See outliner -> user prefs -> Interface
- Theme colors have been extended with basic colors for region types.
Currently colors are defined for Window, Header, List/Channels and
for Button/Tool views.
The screen manager handles this btw, so a TH_BACK will always pick the
right backdrop color.
- Menu backdrops are in in Button theme colors. Floating Panels will be in
the per-space type Themes.
- Styles were added in RNA too, but only for the font settings now.
Only Panel font, widget font and widget-label work now. The 'group label'
will be for templates mostly.
Style settings will be expanded with spacing defaults, label conventions,
etc.
- Label text colors are stored in per-space Theme too, to make sure they fit.
Same goes for Panel title color.
Note that 'shadow' for fonts can conflict with text colors; shadow color is
currently stored in Style... shadow code needs a bit of work still.
2009-04-27 13:44:11 +00:00
|
|
|
}
|
2017-05-13 19:48:04 +02:00
|
|
|
|
2022-04-26 22:26:15 +02:00
|
|
|
void UI_but_func_identity_compare_set(uiBut *but, uiButIdentityCompareFunc cmp_fn)
|
|
|
|
|
{
|
|
|
|
|
but->identity_cmp_func = cmp_fn;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
/* *** RNA collection search menu *** */
|
|
|
|
|
|
2022-04-02 16:17:48 -05:00
|
|
|
struct CollItemSearch {
|
2017-05-13 19:48:04 +02:00
|
|
|
void *data;
|
2024-02-14 17:08:58 -05:00
|
|
|
std::string name;
|
2017-05-12 01:42:42 +02:00
|
|
|
int index;
|
|
|
|
|
int iconid;
|
2020-07-23 17:24:17 +10:00
|
|
|
int name_prefix_offset;
|
2024-02-14 17:08:58 -05:00
|
|
|
bool is_id;
|
|
|
|
|
bool has_sep_char;
|
2022-04-02 16:17:48 -05:00
|
|
|
};
|
2017-05-12 01:42:42 +02:00
|
|
|
|
2024-02-14 17:08:58 -05:00
|
|
|
static bool add_collection_search_item(CollItemSearch &cis,
|
2021-02-19 17:56:24 +01:00
|
|
|
const bool requires_exact_data_name,
|
|
|
|
|
const bool has_id_icon,
|
|
|
|
|
uiSearchItems *items)
|
2017-05-12 01:42:42 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-07 16:20:36 -05:00
|
|
|
/* If no item has its own icon to display, libraries can use the library icons rather than the
|
2021-02-19 17:56:24 +01:00
|
|
|
* name prefix for showing the library status. */
|
2024-02-14 17:08:58 -05:00
|
|
|
int name_prefix_offset = cis.name_prefix_offset;
|
|
|
|
|
if (!has_id_icon && cis.is_id && !requires_exact_data_name) {
|
|
|
|
|
cis.iconid = UI_icon_from_library(static_cast<const ID *>(cis.data));
|
|
|
|
|
char name_buf[UI_MAX_DRAW_STR];
|
2022-04-02 16:17:48 -05:00
|
|
|
BKE_id_full_name_ui_prefix_get(
|
2024-02-14 17:08:58 -05:00
|
|
|
name_buf, static_cast<const ID *>(cis.data), false, UI_SEP_CHAR, &name_prefix_offset);
|
|
|
|
|
cis.name = name_buf;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2021-02-19 17:56:24 +01:00
|
|
|
|
|
|
|
|
return UI_search_item_add(items,
|
2025-02-05 18:21:02 -05:00
|
|
|
cis.name,
|
2024-02-14 17:08:58 -05:00
|
|
|
cis.data,
|
|
|
|
|
cis.iconid,
|
|
|
|
|
cis.has_sep_char ? int(UI_BUT_HAS_SEP_CHAR) : 0,
|
2021-02-19 17:56:24 +01:00
|
|
|
name_prefix_offset);
|
2017-05-12 01:42:42 +02:00
|
|
|
}
|
|
|
|
|
|
2022-04-02 16:17:48 -05:00
|
|
|
void ui_rna_collection_search_update_fn(
|
|
|
|
|
const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first)
|
2017-05-12 01:42:42 +02:00
|
|
|
{
|
2024-02-14 17:08:58 -05:00
|
|
|
using namespace blender;
|
2022-04-02 16:17:48 -05:00
|
|
|
uiRNACollectionSearch *data = static_cast<uiRNACollectionSearch *>(arg);
|
2020-06-15 18:32:51 +10:00
|
|
|
const int flag = RNA_property_flag(data->target_prop);
|
2020-05-11 16:55:33 +02:00
|
|
|
const bool is_ptr_target = (RNA_property_type(data->target_prop) == PROP_POINTER);
|
|
|
|
|
/* For non-pointer properties, UI code acts entirely based on the item's name. So the name has to
|
|
|
|
|
* match the RNA name exactly. So only for pointer properties, the name can be modified to add
|
|
|
|
|
* further UI hints. */
|
|
|
|
|
const bool requires_exact_data_name = !is_ptr_target;
|
UI: Expose an "is first search" boolean to search button callbacks
Currently when you open an RNA collection search button, like a
vertex group selector, the search filter isn't applied until you
start typing, in order to display every option at the start.
Otherwise they wouldn't be visible, since the search filter would
run for the current text.
Currently this check happens in one place, but it relies on the
`changed` value of `uiBut`. This is fine in the interface directory,
but anywhere else it would require exposing `uiBut.changed`, which
is probably too low-level to expose.
The solution is adding an `is_first` argument to the search callbacks,
which is nice for a few reasons:
- They work at a higher level of abstraction, meaning they don't
have to worry about how exactly to tell if this is the first
search.
- It makes it easier to do special behavior when the search menu
is first opened.
- Then, obviously, it makes that state accessible without including
`interface_intern.h`.
Needed for attribute search: T85658
Differential Revision: https://developer.blender.org/D10528
2021-03-02 11:42:05 -06:00
|
|
|
const bool skip_filter = is_first;
|
2020-04-10 20:07:11 +02:00
|
|
|
char name_buf[UI_MAX_DRAW_STR];
|
2020-06-29 17:19:43 +02:00
|
|
|
bool has_id_icon = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-02-14 17:08:58 -05:00
|
|
|
/* The string search API requires pointer stability. */
|
|
|
|
|
Vector<std::unique_ptr<CollItemSearch>> items_list;
|
2020-07-07 10:08:42 +02:00
|
|
|
|
2022-05-20 14:30:17 +10:00
|
|
|
if (data->search_prop != nullptr) {
|
|
|
|
|
/* build a temporary list of relevant items first */
|
|
|
|
|
RNA_PROP_BEGIN (&data->search_ptr, itemptr, data->search_prop) {
|
|
|
|
|
if (flag & PROP_ID_SELF_CHECK) {
|
|
|
|
|
if (itemptr.data == data->target_ptr.owner_id) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-20 14:30:17 +10:00
|
|
|
/* use filter */
|
|
|
|
|
if (is_ptr_target) {
|
|
|
|
|
if (RNA_property_pointer_poll(&data->target_ptr, data->target_prop, &itemptr) == 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-20 14:30:17 +10:00
|
|
|
int name_prefix_offset = 0;
|
|
|
|
|
int iconid = ICON_NONE;
|
|
|
|
|
bool has_sep_char = false;
|
|
|
|
|
const bool is_id = itemptr.type && RNA_struct_is_ID(itemptr.type);
|
2020-06-15 18:32:51 +10:00
|
|
|
|
2024-02-14 17:08:58 -05:00
|
|
|
char *name;
|
2022-05-20 14:30:17 +10:00
|
|
|
if (is_id) {
|
|
|
|
|
iconid = ui_id_icon_get(C, static_cast<ID *>(itemptr.data), false);
|
|
|
|
|
if (!ELEM(iconid, 0, ICON_BLANK1)) {
|
|
|
|
|
has_id_icon = true;
|
|
|
|
|
}
|
2020-04-10 20:07:11 +02:00
|
|
|
|
2022-05-20 14:30:17 +10:00
|
|
|
if (requires_exact_data_name) {
|
|
|
|
|
name = RNA_struct_name_get_alloc(&itemptr, name_buf, sizeof(name_buf), nullptr);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
const ID *id = static_cast<ID *>(itemptr.data);
|
|
|
|
|
BKE_id_full_name_ui_prefix_get(name_buf, id, true, UI_SEP_CHAR, &name_prefix_offset);
|
|
|
|
|
BLI_STATIC_ASSERT(sizeof(name_buf) >= MAX_ID_FULL_NAME_UI,
|
|
|
|
|
"Name string buffer should be big enough to hold full UI ID name");
|
|
|
|
|
name = name_buf;
|
|
|
|
|
has_sep_char = ID_IS_LINKED(id);
|
|
|
|
|
}
|
2020-05-11 16:55:33 +02:00
|
|
|
}
|
2024-07-25 17:20:27 +02:00
|
|
|
else if (itemptr.type == &RNA_ActionSlot) {
|
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(&itemptr, "name_display");
|
|
|
|
|
name = RNA_property_string_get_alloc(&itemptr, prop, name_buf, sizeof(name_buf), nullptr);
|
|
|
|
|
}
|
2020-05-11 16:55:33 +02:00
|
|
|
else {
|
2022-05-20 14:30:17 +10:00
|
|
|
name = RNA_struct_name_get_alloc(&itemptr, name_buf, sizeof(name_buf), nullptr);
|
2020-05-11 16:55:33 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-20 14:30:17 +10:00
|
|
|
if (name) {
|
2024-02-14 17:08:58 -05:00
|
|
|
auto cis = std::make_unique<CollItemSearch>();
|
2022-05-20 14:30:17 +10:00
|
|
|
cis->data = itemptr.data;
|
2024-02-14 17:08:58 -05:00
|
|
|
cis->name = name;
|
|
|
|
|
cis->index = items_list.size();
|
2022-05-20 14:30:17 +10:00
|
|
|
cis->iconid = iconid;
|
|
|
|
|
cis->is_id = is_id;
|
|
|
|
|
cis->name_prefix_offset = name_prefix_offset;
|
|
|
|
|
cis->has_sep_char = has_sep_char;
|
2024-02-14 17:08:58 -05:00
|
|
|
items_list.append(std::move(cis));
|
2022-05-20 14:30:17 +10:00
|
|
|
if (name != name_buf) {
|
|
|
|
|
MEM_freeN(name);
|
|
|
|
|
}
|
2017-05-12 01:42:42 +02:00
|
|
|
}
|
2022-05-20 14:30:17 +10:00
|
|
|
}
|
|
|
|
|
RNA_PROP_END;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_assert(RNA_property_type(data->target_prop) == PROP_STRING);
|
|
|
|
|
const eStringPropertySearchFlag search_flag = RNA_property_string_search_flag(
|
|
|
|
|
data->target_prop);
|
|
|
|
|
BLI_assert(search_flag & PROP_STRING_SEARCH_SUPPORTED);
|
|
|
|
|
|
2024-02-14 17:08:58 -05:00
|
|
|
const bool show_extra_info = (G.debug_value == 102);
|
|
|
|
|
|
|
|
|
|
RNA_property_string_search(C,
|
|
|
|
|
&data->target_ptr,
|
|
|
|
|
data->target_prop,
|
|
|
|
|
str,
|
|
|
|
|
[&](StringPropertySearchVisitParams visit_params) {
|
|
|
|
|
auto cis = std::make_unique<CollItemSearch>();
|
|
|
|
|
|
|
|
|
|
cis->data = nullptr;
|
|
|
|
|
if (visit_params.info && show_extra_info) {
|
|
|
|
|
cis->name = fmt::format("{}" UI_SEP_CHAR_S "{}",
|
|
|
|
|
visit_params.text,
|
|
|
|
|
*visit_params.info);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
cis->name = std::move(visit_params.text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cis->index = items_list.size();
|
2024-05-01 11:16:23 -04:00
|
|
|
cis->iconid = visit_params.icon_id.value_or(ICON_NONE);
|
2024-02-14 17:08:58 -05:00
|
|
|
cis->is_id = false;
|
|
|
|
|
cis->name_prefix_offset = 0;
|
|
|
|
|
cis->has_sep_char = visit_params.info.has_value();
|
|
|
|
|
items_list.append(std::move(cis));
|
|
|
|
|
});
|
2022-05-20 14:30:17 +10:00
|
|
|
|
|
|
|
|
if (search_flag & PROP_STRING_SEARCH_SORT) {
|
2024-02-14 17:08:58 -05:00
|
|
|
std::sort(
|
|
|
|
|
items_list.begin(),
|
|
|
|
|
items_list.end(),
|
|
|
|
|
[](const std::unique_ptr<CollItemSearch> &a, const std::unique_ptr<CollItemSearch> &b) {
|
2024-03-11 16:31:08 +01:00
|
|
|
return BLI_strcasecmp_natural(a->name.c_str(), b->name.c_str()) < 0;
|
2024-02-14 17:08:58 -05:00
|
|
|
});
|
|
|
|
|
for (const int i : items_list.index_range()) {
|
|
|
|
|
items_list[i]->index = i;
|
2020-04-10 20:07:11 +02:00
|
|
|
}
|
2017-05-12 01:42:42 +02:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-19 17:56:24 +01:00
|
|
|
if (skip_filter) {
|
2024-02-14 17:08:58 -05:00
|
|
|
for (std::unique_ptr<CollItemSearch> &cis : items_list) {
|
|
|
|
|
if (!add_collection_search_item(*cis, requires_exact_data_name, has_id_icon, items)) {
|
2021-02-19 17:56:24 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2020-06-29 17:19:43 +02:00
|
|
|
}
|
2021-02-19 17:56:24 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2024-02-14 17:08:58 -05:00
|
|
|
ui::string_search::StringSearch<CollItemSearch> search;
|
|
|
|
|
for (std::unique_ptr<CollItemSearch> &cis : items_list) {
|
|
|
|
|
search.add(cis->name, cis.get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Vector<CollItemSearch *> filtered_items = search.query(str);
|
2023-08-05 10:54:23 +02:00
|
|
|
for (CollItemSearch *cis : filtered_items) {
|
2024-02-14 17:08:58 -05:00
|
|
|
if (!add_collection_search_item(*cis, requires_exact_data_name, has_id_icon, items)) {
|
2021-02-19 17:56:24 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2017-05-12 01:42:42 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-17 16:42:20 -06:00
|
|
|
int UI_icon_from_id(const ID *id)
|
2009-09-16 01:15:30 +00:00
|
|
|
{
|
2022-04-02 16:17:48 -05:00
|
|
|
if (id == nullptr) {
|
2011-02-27 18:03:19 +00:00
|
|
|
return ICON_NONE;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2009-09-16 19:36:17 +00:00
|
|
|
/* exception for objects */
|
2021-02-17 16:42:20 -06:00
|
|
|
if (GS(id->name) == ID_OB) {
|
|
|
|
|
Object *ob = (Object *)id;
|
2009-06-03 00:14:12 +00:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (ob->type == OB_EMPTY) {
|
2009-09-16 19:36:17 +00:00
|
|
|
return ICON_EMPTY_DATA;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2022-04-02 16:17:48 -05:00
|
|
|
return UI_icon_from_id(static_cast<const ID *>(ob->data));
|
2009-06-03 00:14:12 +00:00
|
|
|
}
|
|
|
|
|
|
2009-09-16 19:36:17 +00:00
|
|
|
/* otherwise get it through RNA, creating the pointer
|
2012-03-03 16:31:46 +00:00
|
|
|
* will set the right type, also with subclassing */
|
2023-09-06 00:48:50 +02:00
|
|
|
PointerRNA ptr = RNA_id_pointer_create((ID *)id);
|
2009-06-03 00:14:12 +00:00
|
|
|
|
2012-03-30 01:51:25 +00:00
|
|
|
return (ptr.type) ? RNA_struct_ui_icon(ptr.type) : ICON_NONE;
|
2009-06-03 00:14:12 +00:00
|
|
|
}
|
2014-01-08 17:04:10 +01:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
int UI_icon_from_report_type(int type)
|
2014-02-09 12:00:03 +11:00
|
|
|
{
|
2019-03-25 10:15:20 +11:00
|
|
|
if (type & RPT_ERROR_ALL) {
|
2021-02-08 08:19:23 -08:00
|
|
|
return ICON_CANCEL;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_WARNING_ALL) {
|
2014-02-09 12:00:03 +11:00
|
|
|
return ICON_ERROR;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_INFO_ALL) {
|
2014-02-09 12:00:03 +11:00
|
|
|
return ICON_INFO;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_DEBUG_ALL) {
|
2021-02-08 08:19:23 -08:00
|
|
|
return ICON_SYSTEM;
|
|
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_PROPERTY) {
|
2021-02-08 08:19:23 -08:00
|
|
|
return ICON_OPTIONS;
|
|
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_OPERATOR) {
|
2021-02-08 08:19:23 -08:00
|
|
|
return ICON_CHECKMARK;
|
|
|
|
|
}
|
|
|
|
|
return ICON_INFO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int UI_icon_colorid_from_report_type(int type)
|
|
|
|
|
{
|
|
|
|
|
if (type & RPT_ERROR_ALL) {
|
2025-02-12 20:59:47 +01:00
|
|
|
return TH_ERROR;
|
2021-02-08 08:19:23 -08:00
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_WARNING_ALL) {
|
2025-02-12 20:59:47 +01:00
|
|
|
return TH_WARNING;
|
2021-02-08 08:19:23 -08:00
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_INFO_ALL) {
|
2025-02-12 20:59:47 +01:00
|
|
|
return TH_INFO;
|
2021-02-08 08:19:23 -08:00
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_DEBUG_ALL) {
|
2021-02-08 08:19:23 -08:00
|
|
|
return TH_INFO_DEBUG;
|
|
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_PROPERTY) {
|
2021-02-08 08:19:23 -08:00
|
|
|
return TH_INFO_PROPERTY;
|
|
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_OPERATOR) {
|
2021-02-08 08:19:23 -08:00
|
|
|
return TH_INFO_OPERATOR;
|
|
|
|
|
}
|
2025-02-12 20:59:47 +01:00
|
|
|
return TH_WARNING;
|
2021-02-08 08:19:23 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int UI_text_colorid_from_report_type(int type)
|
|
|
|
|
{
|
|
|
|
|
if (type & RPT_ERROR_ALL) {
|
|
|
|
|
return TH_INFO_ERROR_TEXT;
|
|
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_WARNING_ALL) {
|
2021-02-08 08:19:23 -08:00
|
|
|
return TH_INFO_WARNING_TEXT;
|
|
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_INFO_ALL) {
|
2021-02-08 08:19:23 -08:00
|
|
|
return TH_INFO_INFO_TEXT;
|
|
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_DEBUG_ALL) {
|
2021-02-08 08:19:23 -08:00
|
|
|
return TH_INFO_DEBUG_TEXT;
|
|
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_PROPERTY) {
|
2021-02-08 08:19:23 -08:00
|
|
|
return TH_INFO_PROPERTY_TEXT;
|
|
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
if (type & RPT_OPERATOR) {
|
2021-02-08 08:19:23 -08:00
|
|
|
return TH_INFO_OPERATOR_TEXT;
|
|
|
|
|
}
|
2021-02-15 15:30:17 +01:00
|
|
|
return TH_INFO_WARNING_TEXT;
|
2014-02-09 12:00:03 +11:00
|
|
|
}
|
|
|
|
|
|
2014-01-08 17:04:10 +01:00
|
|
|
/********************************** Misc **************************************/
|
|
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
int UI_calc_float_precision(int prec, double value)
|
2014-01-08 17:04:10 +01:00
|
|
|
{
|
2017-07-21 10:52:36 +02:00
|
|
|
static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = {
|
|
|
|
|
1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6};
|
2014-01-08 17:04:10 +01:00
|
|
|
static const double max_pow = 10000000.0; /* pow(10, UI_PRECISION_FLOAT_MAX) */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-08 17:04:10 +01:00
|
|
|
BLI_assert(prec <= UI_PRECISION_FLOAT_MAX);
|
2014-06-18 13:13:22 +09:00
|
|
|
BLI_assert(fabs(pow10_neg[prec] - pow(10, -prec)) < 1e-16);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:44:38 +02:00
|
|
|
/* Check on the number of decimal places need to display the number,
|
|
|
|
|
* this is so 0.00001 is not displayed as 0.00,
|
2021-07-07 12:55:19 +10:00
|
|
|
* _but_, this is only for small values as 10.0001 will not get the same treatment.
|
2014-01-08 17:04:10 +01:00
|
|
|
*/
|
2020-03-06 17:18:10 +01:00
|
|
|
value = fabs(value);
|
2014-01-08 17:04:10 +01:00
|
|
|
if ((value < pow10_neg[prec]) && (value > (1.0 / max_pow))) {
|
2022-09-25 18:33:28 +10:00
|
|
|
int value_i = int(lround(value * max_pow));
|
2014-01-08 17:04:10 +01:00
|
|
|
if (value_i != 0) {
|
|
|
|
|
const int prec_span = 3; /* show: 0.01001, 5 would allow 0.0100001 for eg. */
|
|
|
|
|
int test_prec;
|
|
|
|
|
int prec_min = -1;
|
|
|
|
|
int dec_flag = 0;
|
|
|
|
|
int i = UI_PRECISION_FLOAT_MAX;
|
|
|
|
|
while (i && value_i) {
|
|
|
|
|
if (value_i % 10) {
|
|
|
|
|
dec_flag |= 1 << i;
|
|
|
|
|
prec_min = i;
|
|
|
|
|
}
|
|
|
|
|
value_i /= 10;
|
|
|
|
|
i--;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-08 17:04:10 +01:00
|
|
|
/* even though its a small value, if the second last digit is not 0, use it */
|
|
|
|
|
test_prec = prec_min;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-08 17:04:10 +01:00
|
|
|
dec_flag = (dec_flag >> (prec_min + 1)) & ((1 << prec_span) - 1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-08 17:04:10 +01:00
|
|
|
while (dec_flag) {
|
|
|
|
|
test_prec++;
|
|
|
|
|
dec_flag = dec_flag >> 1;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-26 20:08:00 +01:00
|
|
|
prec = std::max(test_prec, prec);
|
2014-01-08 17:04:10 +01:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-08 17:04:10 +01:00
|
|
|
CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-08 17:04:10 +01:00
|
|
|
return prec;
|
|
|
|
|
}
|
2014-02-08 09:03:25 +11:00
|
|
|
|
2024-02-19 12:17:52 +11:00
|
|
|
std::optional<std::string> UI_but_online_manual_id(const uiBut *but)
|
2015-04-27 01:17:51 +10:00
|
|
|
{
|
2024-02-19 02:07:47 -05:00
|
|
|
if (but->rnapoin.data && but->rnaprop) {
|
2024-02-19 12:17:52 +11:00
|
|
|
return fmt::format(
|
|
|
|
|
"{}.{}", RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop));
|
2015-04-27 01:17:51 +10:00
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (but->optype) {
|
2024-02-19 12:17:52 +11:00
|
|
|
char idname[OP_MAX_TYPENAME];
|
|
|
|
|
const size_t idname_len = WM_operator_py_idname(idname, but->optype->idname);
|
|
|
|
|
return std::string(idname, idname_len);
|
2015-04-27 01:17:51 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-02-19 12:17:52 +11:00
|
|
|
return std::nullopt;
|
2015-04-27 01:17:51 +10:00
|
|
|
}
|
|
|
|
|
|
2024-02-19 12:17:52 +11:00
|
|
|
std::optional<std::string> UI_but_online_manual_id_from_active(const bContext *C)
|
2015-04-27 01:17:51 +10:00
|
|
|
{
|
2024-02-19 12:17:52 +11:00
|
|
|
if (uiBut *but = UI_context_active_but_get(C)) {
|
|
|
|
|
return UI_but_online_manual_id(but);
|
2015-04-27 01:17:51 +10:00
|
|
|
}
|
2024-02-19 12:17:52 +11:00
|
|
|
return std::nullopt;
|
2015-04-27 01:17:51 +10:00
|
|
|
}
|
|
|
|
|
|
2021-07-13 17:06:15 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
static rctf ui_but_rect_to_view(const uiBut *but, const ARegion *region, const View2D *v2d)
|
|
|
|
|
{
|
|
|
|
|
rctf region_rect;
|
|
|
|
|
ui_block_to_region_rctf(region, but->block, ®ion_rect, &but->rect);
|
|
|
|
|
|
|
|
|
|
rctf view_rect;
|
|
|
|
|
UI_view2d_region_to_view_rctf(v2d, ®ion_rect, &view_rect);
|
|
|
|
|
|
|
|
|
|
return view_rect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* To get a margin (typically wanted), add the margin to \a rect directly.
|
|
|
|
|
*
|
|
|
|
|
* Based on #file_ensure_inside_viewbounds(), could probably share code.
|
|
|
|
|
*
|
|
|
|
|
* \return true if anything changed.
|
|
|
|
|
*/
|
|
|
|
|
static bool ui_view2d_cur_ensure_rect_in_view(View2D *v2d, const rctf *rect)
|
|
|
|
|
{
|
|
|
|
|
const float rect_width = BLI_rctf_size_x(rect);
|
|
|
|
|
const float rect_height = BLI_rctf_size_y(rect);
|
|
|
|
|
|
|
|
|
|
rctf *cur = &v2d->cur;
|
|
|
|
|
const float cur_width = BLI_rctf_size_x(cur);
|
|
|
|
|
const float cur_height = BLI_rctf_size_y(cur);
|
|
|
|
|
|
|
|
|
|
bool changed = false;
|
|
|
|
|
|
|
|
|
|
/* Snap to bottom edge. Also use if rect is higher than view bounds (could be a parameter). */
|
|
|
|
|
if ((cur->ymin > rect->ymin) || (rect_height > cur_height)) {
|
|
|
|
|
cur->ymin = rect->ymin;
|
|
|
|
|
cur->ymax = cur->ymin + cur_height;
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
/* Snap to upper edge. */
|
|
|
|
|
else if (cur->ymax < rect->ymax) {
|
|
|
|
|
cur->ymax = rect->ymax;
|
|
|
|
|
cur->ymin = cur->ymax - cur_height;
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
/* Snap to left edge. Also use if rect is wider than view bounds. */
|
|
|
|
|
else if ((cur->xmin > rect->xmin) || (rect_width > cur_width)) {
|
|
|
|
|
cur->xmin = rect->xmin;
|
|
|
|
|
cur->xmax = cur->xmin + cur_width;
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
/* Snap to right edge. */
|
|
|
|
|
else if (cur->xmax < rect->xmax) {
|
|
|
|
|
cur->xmax = rect->xmax;
|
|
|
|
|
cur->xmin = cur->xmax - cur_width;
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_assert(BLI_rctf_inside_rctf(cur, rect));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UI_but_ensure_in_view(const bContext *C, ARegion *region, const uiBut *but)
|
|
|
|
|
{
|
|
|
|
|
View2D *v2d = ®ion->v2d;
|
2021-07-16 11:45:51 +10:00
|
|
|
/* Uninitialized view or region that doesn't use View2D. */
|
2021-07-13 17:06:15 +02:00
|
|
|
if ((v2d->flag & V2D_IS_INIT) == 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rctf rect = ui_but_rect_to_view(but, region, v2d);
|
|
|
|
|
|
|
|
|
|
const int margin = UI_UNIT_X * 0.5f;
|
|
|
|
|
BLI_rctf_pad(&rect, margin, margin);
|
|
|
|
|
|
|
|
|
|
const bool changed = ui_view2d_cur_ensure_rect_in_view(v2d, &rect);
|
|
|
|
|
if (changed) {
|
|
|
|
|
UI_view2d_curRect_changed(C, v2d);
|
|
|
|
|
ED_region_tag_redraw_no_rebuild(region);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-08 09:03:25 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Button Store
|
2020-10-27 21:32:09 +11:00
|
|
|
*
|
2014-02-08 09:03:25 +11:00
|
|
|
* Modal Button Store API.
|
|
|
|
|
*
|
|
|
|
|
* Store for modal operators & handlers to register button pointers
|
2022-04-02 16:17:48 -05:00
|
|
|
* which are maintained while drawing or nullptr when removed.
|
2014-02-08 09:03:25 +11:00
|
|
|
*
|
|
|
|
|
* This is needed since button pointers are continuously freed and re-allocated.
|
|
|
|
|
*
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2014-02-09 13:56:49 +01:00
|
|
|
struct uiButStore {
|
2023-06-03 08:36:28 +10:00
|
|
|
uiButStore *next, *prev;
|
2014-02-08 09:03:25 +11:00
|
|
|
uiBlock *block;
|
|
|
|
|
ListBase items;
|
2014-02-09 13:56:49 +01:00
|
|
|
};
|
2014-02-08 09:03:25 +11:00
|
|
|
|
2014-02-09 13:56:49 +01:00
|
|
|
struct uiButStoreElem {
|
2023-06-03 08:36:28 +10:00
|
|
|
uiButStoreElem *next, *prev;
|
2014-02-08 09:03:25 +11:00
|
|
|
uiBut **but_p;
|
2014-02-09 13:56:49 +01:00
|
|
|
};
|
2014-02-08 09:03:25 +11:00
|
|
|
|
|
|
|
|
uiButStore *UI_butstore_create(uiBlock *block)
|
|
|
|
|
{
|
2025-03-05 16:35:09 +01:00
|
|
|
uiButStore *bs_handle = MEM_callocN<uiButStore>(__func__);
|
2014-02-08 09:03:25 +11:00
|
|
|
|
|
|
|
|
bs_handle->block = block;
|
|
|
|
|
BLI_addtail(&block->butstore, bs_handle);
|
|
|
|
|
|
|
|
|
|
return bs_handle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UI_butstore_free(uiBlock *block, uiButStore *bs_handle)
|
|
|
|
|
{
|
2024-01-14 11:48:51 +11:00
|
|
|
/* NOTE(@ideasman42): Workaround for button store being moved into new block,
|
2019-04-17 08:44:38 +02:00
|
|
|
* which then can't use the previous buttons state
|
2024-01-14 11:48:51 +11:00
|
|
|
* (#ui_but_update_from_old_block fails to find a match),
|
2019-04-17 08:44:38 +02:00
|
|
|
* keeping the active button in the old block holding a reference
|
2023-02-12 14:37:16 +11:00
|
|
|
* to the button-state in the new block: see #49034.
|
2017-07-11 19:07:37 +10:00
|
|
|
*
|
|
|
|
|
* Ideally we would manage moving the 'uiButStore', keeping a correct state.
|
2024-01-14 11:48:51 +11:00
|
|
|
* All things considered this is the most straightforward fix. */
|
2022-04-02 16:17:48 -05:00
|
|
|
if (block != bs_handle->block && bs_handle->block != nullptr) {
|
2017-07-11 19:07:37 +10:00
|
|
|
block = bs_handle->block;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-02-08 09:03:25 +11:00
|
|
|
BLI_freelistN(&bs_handle->items);
|
2020-04-08 22:36:58 +02:00
|
|
|
BLI_assert(BLI_findindex(&block->butstore, bs_handle) != -1);
|
2014-02-08 09:03:25 +11:00
|
|
|
BLI_remlink(&block->butstore, bs_handle);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-02-08 09:03:25 +11:00
|
|
|
MEM_freeN(bs_handle);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-27 13:20:43 +10:00
|
|
|
bool UI_butstore_is_valid(uiButStore *bs_handle)
|
2014-02-08 09:03:25 +11:00
|
|
|
{
|
2024-07-27 13:20:43 +10:00
|
|
|
return (bs_handle->block != nullptr);
|
2014-02-08 09:03:25 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool UI_butstore_is_registered(uiBlock *block, uiBut *but)
|
|
|
|
|
{
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) {
|
|
|
|
|
LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) {
|
2014-02-08 09:03:25 +11:00
|
|
|
if (*bs_elem->but_p == but) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p)
|
|
|
|
|
{
|
2025-03-05 16:35:09 +01:00
|
|
|
uiButStoreElem *bs_elem = MEM_callocN<uiButStoreElem>(__func__);
|
2014-02-08 09:03:25 +11:00
|
|
|
BLI_assert(*but_p);
|
|
|
|
|
bs_elem->but_p = but_p;
|
|
|
|
|
|
|
|
|
|
BLI_addtail(&bs_handle->items, bs_elem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p)
|
|
|
|
|
{
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH_MUTABLE (uiButStoreElem *, bs_elem, &bs_handle->items) {
|
2014-02-08 09:03:25 +11:00
|
|
|
if (bs_elem->but_p == but_p) {
|
|
|
|
|
BLI_remlink(&bs_handle->items, bs_elem);
|
|
|
|
|
MEM_freeN(bs_elem);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_assert(0);
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-01 23:30:54 +01:00
|
|
|
bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src)
|
|
|
|
|
{
|
|
|
|
|
bool found = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) {
|
|
|
|
|
LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) {
|
2014-12-01 23:30:54 +01:00
|
|
|
if (*bs_elem->but_p == but_src) {
|
|
|
|
|
*bs_elem->but_p = but_dst;
|
|
|
|
|
found = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-12-01 23:30:54 +01:00
|
|
|
return found;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-08 09:03:25 +11:00
|
|
|
void UI_butstore_clear(uiBlock *block)
|
|
|
|
|
{
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) {
|
2022-04-02 16:17:48 -05:00
|
|
|
bs_handle->block = nullptr;
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) {
|
2022-04-02 16:17:48 -05:00
|
|
|
*bs_elem->but_p = nullptr;
|
2014-02-08 09:03:25 +11:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UI_butstore_update(uiBlock *block)
|
|
|
|
|
{
|
|
|
|
|
/* move this list to the new block */
|
|
|
|
|
if (block->oldblock) {
|
|
|
|
|
if (block->oldblock->butstore.first) {
|
2020-04-08 22:36:58 +02:00
|
|
|
BLI_movelisttolist(&block->butstore, &block->oldblock->butstore);
|
2014-02-08 09:03:25 +11:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-04-02 16:17:48 -05:00
|
|
|
if (LIKELY(block->butstore.first == nullptr)) {
|
2014-02-08 09:03:25 +11:00
|
|
|
return;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-02-08 09:03:25 +11:00
|
|
|
/* warning, loop-in-loop, in practice we only store <10 buttons at a time,
|
|
|
|
|
* so this isn't going to be a problem, if that changes old-new mapping can be cached first */
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) {
|
2022-04-02 16:17:48 -05:00
|
|
|
BLI_assert(ELEM(bs_handle->block, nullptr, block) ||
|
2014-02-08 09:03:25 +11:00
|
|
|
(block->oldblock && block->oldblock == bs_handle->block));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-02-08 09:03:25 +11:00
|
|
|
if (bs_handle->block == block->oldblock) {
|
|
|
|
|
bs_handle->block = block;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) {
|
2014-02-08 09:03:25 +11:00
|
|
|
if (*bs_elem->but_p) {
|
|
|
|
|
uiBut *but_new = ui_but_find_new(block, *bs_elem->but_p);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-04-02 16:17:48 -05:00
|
|
|
/* can be nullptr if the buttons removed,
|
2021-07-03 23:08:40 +10:00
|
|
|
* NOTE: we could allow passing in a callback when buttons are removed
|
2014-02-08 09:03:25 +11:00
|
|
|
* so the caller can cleanup */
|
|
|
|
|
*bs_elem->but_p = but_new;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
2023-01-11 19:14:35 +11:00
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Key Event from UI
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Follow the logic from #wm_keymap_item_find_in_keymap.
|
|
|
|
|
*/
|
2024-12-06 14:08:10 +01:00
|
|
|
static bool ui_key_event_property_match(const StringRefNull opname,
|
2023-01-11 19:14:35 +11:00
|
|
|
IDProperty *properties,
|
|
|
|
|
const bool is_strict,
|
|
|
|
|
wmOperatorType *ui_optype,
|
|
|
|
|
PointerRNA *ui_opptr)
|
|
|
|
|
{
|
2024-12-06 14:08:10 +01:00
|
|
|
if (ui_optype->idname != opname) {
|
2023-01-11 19:14:35 +11:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool match = false;
|
|
|
|
|
if (properties) {
|
|
|
|
|
if (ui_opptr &&
|
|
|
|
|
IDP_EqualsProperties_ex(properties, static_cast<IDProperty *>(ui_opptr->data), is_strict))
|
|
|
|
|
{
|
|
|
|
|
match = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
match = true;
|
|
|
|
|
}
|
|
|
|
|
return match;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-07 14:22:54 +01:00
|
|
|
std::optional<std::string> UI_key_event_operator_string(const bContext *C,
|
2024-12-06 14:08:10 +01:00
|
|
|
const StringRefNull opname,
|
2024-02-07 14:22:54 +01:00
|
|
|
IDProperty *properties,
|
|
|
|
|
const bool is_strict)
|
2023-01-11 19:14:35 +11:00
|
|
|
{
|
|
|
|
|
/* NOTE: currently only actions on UI Lists are supported (for the asset manager).
|
|
|
|
|
* Other kinds of events can be supported as needed. */
|
|
|
|
|
|
|
|
|
|
ARegion *region = CTX_wm_region(C);
|
|
|
|
|
if (region == nullptr) {
|
2024-02-07 14:22:54 +01:00
|
|
|
return std::nullopt;
|
2023-01-11 19:14:35 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Early exit regions which don't have UI-Lists. */
|
2024-11-21 19:34:53 +01:00
|
|
|
if ((region->runtime->type->keymapflag & ED_KEYMAP_UI) == 0) {
|
2024-02-07 14:22:54 +01:00
|
|
|
return std::nullopt;
|
2023-01-11 19:14:35 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uiBut *but = UI_region_active_but_get(region);
|
|
|
|
|
if (but == nullptr) {
|
2024-02-07 14:22:54 +01:00
|
|
|
return std::nullopt;
|
2023-01-11 19:14:35 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (but->type != UI_BTYPE_PREVIEW_TILE) {
|
2024-02-07 14:22:54 +01:00
|
|
|
return std::nullopt;
|
2023-01-11 19:14:35 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
short event_val = KM_NOTHING;
|
|
|
|
|
short event_type = KM_NOTHING;
|
|
|
|
|
|
|
|
|
|
uiBut *listbox = nullptr;
|
2025-02-14 15:29:26 +01:00
|
|
|
for (int i = but->block->buttons.size() - 1; i >= 0; i--) {
|
|
|
|
|
uiBut *but_iter = but->block->buttons[i].get();
|
2023-01-11 19:14:35 +11:00
|
|
|
if ((but_iter->type == UI_BTYPE_LISTBOX) && ui_but_contains_rect(but_iter, &but->rect)) {
|
|
|
|
|
listbox = but_iter;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (listbox && listbox->custom_data) {
|
|
|
|
|
uiList *list = static_cast<uiList *>(listbox->custom_data);
|
|
|
|
|
uiListDyn *dyn_data = list->dyn_data;
|
|
|
|
|
if ((dyn_data->custom_activate_optype != nullptr) &&
|
|
|
|
|
ui_key_event_property_match(opname,
|
|
|
|
|
properties,
|
|
|
|
|
is_strict,
|
|
|
|
|
dyn_data->custom_activate_optype,
|
|
|
|
|
dyn_data->custom_activate_opptr))
|
|
|
|
|
{
|
|
|
|
|
event_val = KM_CLICK;
|
|
|
|
|
event_type = LEFTMOUSE;
|
|
|
|
|
}
|
|
|
|
|
else if ((dyn_data->custom_activate_optype != nullptr) &&
|
|
|
|
|
ui_key_event_property_match(opname,
|
|
|
|
|
properties,
|
|
|
|
|
is_strict,
|
|
|
|
|
dyn_data->custom_drag_optype,
|
|
|
|
|
dyn_data->custom_drag_opptr))
|
|
|
|
|
{
|
|
|
|
|
event_val = KM_CLICK_DRAG;
|
|
|
|
|
event_type = LEFTMOUSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((event_val != KM_NOTHING) && (event_type != KM_NOTHING)) {
|
2025-03-25 23:32:41 +00:00
|
|
|
return WM_keymap_item_raw_to_string(KM_NOTHING,
|
|
|
|
|
KM_NOTHING,
|
|
|
|
|
KM_NOTHING,
|
|
|
|
|
KM_NOTHING,
|
|
|
|
|
KM_NOTHING,
|
|
|
|
|
0,
|
|
|
|
|
event_val,
|
|
|
|
|
event_type,
|
|
|
|
|
false);
|
2023-01-11 19:14:35 +11:00
|
|
|
}
|
|
|
|
|
|
2024-02-07 14:22:54 +01:00
|
|
|
return std::nullopt;
|
2023-01-11 19:14:35 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|