WIP: Experiment: Drop import operator helper and file drop type #111242

Closed
Guillermo Venegas wants to merge 23 commits from guishe/blender:drop-helper into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
29 changed files with 401 additions and 100058 deletions
Showing only changes of commit ee28002ecd - Show all commits

View File

@ -29,8 +29,8 @@
15:Russian (Русский):ru_RU
18:Ukrainian (Українська):uk_UA
41:Vietnamese (Tiếng Việt):vi_VN
13:Simplified Chinese (简体中文):zh_CN
14:Traditional Chinese (繁體中文):zh_TW
13:Simplified Chinese (简体中文):zh_HANS
14:Traditional Chinese (繁體中文):zh_HANT
#
0:Starting:
45:Abkhaz (Аԥсуа бызшәа):ab
@ -39,7 +39,6 @@
# Skipped (see IMPORT_LANGUAGES_SKIP in settings.py). #22:Bulgarian (Български):bg_BG
# Skipped (see IMPORT_LANGUAGES_SKIP in settings.py). #23:Greek (Ελληνικά):el_GR
35:Esperanto (Esperanto):eo
# Skipped (see IMPORT_LANGUAGES_SKIP in settings.py). #36:Spanish from Spain (Español de España):es_ES
# Skipped (see IMPORT_LANGUAGES_SKIP in settings.py). #34:Estonian (Eesti keel):et_EE
42:Basque (Euskara):eu_EU
26:Persian (ﯽﺳﺭﺎﻓ):fa_IR
@ -61,5 +60,5 @@
7:Swedish (Svenska):sv_SE
46:Thai (ภาษาไทย):th_TH
30:Turkish (Türkçe):tr_TR
# Skipped (see IMPORT_LANGUAGES_SKIP in settings.py). #38:Uzbek (Oʻzbek):uz_UZ
# Skipped (see IMPORT_LANGUAGES_SKIP in settings.py). #39:Uzbek Cyrillic (Ўзбек):uz_UZ@cyrillic
# Skipped (see IMPORT_LANGUAGES_SKIP in settings.py). #38:Uzbek (Oʻzbek):uz_UZ@latin
# Skipped (see IMPORT_LANGUAGES_SKIP in settings.py). #39:Uzbek Cyrillic (Ўзбек):uz_UZ@cyrillic

File diff suppressed because it is too large Load Diff

View File

@ -853,7 +853,7 @@ def dump_src_messages(msgs, reports, settings):
elif l[0] != '#':
forced.add(l.rstrip('\n'))
for root, dirs, files in os.walk(settings.POTFILES_SOURCE_DIR):
if "/.svn" in root:
if "/.git" in root:
continue
for fname in files:
if os.path.splitext(fname)[1] not in settings.PYGETTEXT_ALLOWED_EXTS:

View File

@ -46,8 +46,8 @@ LANGUAGES = (
(10, "Catalan (Català)", "ca_AD"),
(11, "Czech (Čeština)", "cs_CZ"),
(12, "Portuguese (Português)", "pt_PT"),
(13, "Simplified Chinese (简体中文)", "zh_CN"),
(14, "Traditional Chinese (繁體中文)", "zh_TW"),
(13, "Simplified Chinese (简体中文)", "zh_HANS"),
(14, "Traditional Chinese (繁體中文)", "zh_HANT"),
(15, "Russian (Русский)", "ru_RU"),
(16, "Croatian (Hrvatski)", "hr_HR"),
(17, "Serbian (Српски)", "sr_RS"),
@ -72,9 +72,9 @@ LANGUAGES = (
(33, "Hebrew (תירִבְעִ)", "he_IL"),
(34, "Estonian (Eesti keel)", "et_EE"),
(35, "Esperanto (Esperanto)", "eo"),
(36, "Spanish from Spain (Español de España)", "es_ES"),
# 36 is free, used to be 'Spanish from Spain' (`es_ES`).
(37, "Amharic (አማርኛ)", "am_ET"),
(38, "Uzbek (Oʻzbek)", "uz_UZ"),
(38, "Uzbek (Oʻzbek)", "uz_UZ@latin"),
(39, "Uzbek Cyrillic (Ўзбек)", "uz_UZ@cyrillic"),
(40, "Hindi (हिन्दी)", "hi_IN"),
(41, "Vietnamese (Tiếng Việt)", "vi_VN"),
@ -95,12 +95,12 @@ DEFAULT_CONTEXT = "*"
# Name of language file used by Blender to generate translations' menu.
LANGUAGES_FILE = "languages"
# The min level of completeness for a po file to be imported from /branches into /trunk, as a percentage.
# The min level of completeness for a po file to be imported from the working repository to the Blender one, as a percentage.
IMPORT_MIN_LEVEL = 0.0
# Languages in /branches we do not want to import in /trunk currently...
# Languages in the working repository that should not be imported in the Blender one currently...
IMPORT_LANGUAGES_SKIP = {
'am_ET', 'bg_BG', 'el_GR', 'et_EE', 'ne_NP', 'ro_RO', 'uz_UZ', 'uz_UZ@cyrillic', 'kk_KZ', 'es_ES',
'am_ET', 'bg_BG', 'el_GR', 'et_EE', 'ne_NP', 'ro_RO', 'uz_UZ@latin', 'uz_UZ@cyrillic', 'kk_KZ',
}
# Languages that need RTL pre-processing.
@ -529,25 +529,15 @@ SOURCE_DIR = os.path.abspath(os.path.join("blender"))
# The bf-translation repository (you'll have to override this in your user_settings.py).
I18N_DIR = os.path.abspath(os.path.join("i18n"))
# The /branches path (relative to I18N_DIR).
REL_BRANCHES_DIR = os.path.join("branches")
# The /trunk path (relative to I18N_DIR).
REL_TRUNK_DIR = os.path.join("trunk")
# The /trunk/po path (relative to I18N_DIR).
REL_TRUNK_PO_DIR = os.path.join(REL_TRUNK_DIR, "po")
# The /trunk/mo path (relative to I18N_DIR).
REL_TRUNK_MO_DIR = os.path.join(REL_TRUNK_DIR, "locale")
# The 'work' path to PO files (relative to I18N_DIR).
REL_WORK_DIR = os.path.join("")
# The path to the *git* translation repository (relative to SOURCE_DIR).
REL_GIT_I18N_DIR = os.path.join("locale")
# The path to the Blender translation directory (relative to SOURCE_DIR).
REL_BLENDER_I18N_DIR = os.path.join("locale")
# The /po path of the *git* translation repository (relative to REL_GIT_I18N_DIR).
REL_GIT_I18N_PO_DIR = os.path.join("po")
# The /po path of the Blender translation directory (relative to REL_BLENDER_I18N_DIR).
REL_BLENDER_I18N_PO_DIR = os.path.join("po")
# The Blender source path to check for i18n macros (relative to SOURCE_DIR).
@ -563,13 +553,8 @@ REL_TEMPLATES_DIR = os.path.join("scripts", "startup", "bl_app_templates_system"
ASSET_CATALOG_FILE = "blender_assets.cats.txt"
# The template messages file (relative to I18N_DIR).
REL_FILE_NAME_POT = os.path.join(REL_BRANCHES_DIR, DOMAIN + ".pot")
REL_FILE_NAME_POT = os.path.join(REL_WORK_DIR, DOMAIN + ".pot")
# Mo root data-path.
REL_MO_PATH_ROOT = os.path.join(REL_TRUNK_DIR, "locale")
# Mo path generator for a given language.
REL_MO_PATH_TEMPLATE = os.path.join(REL_MO_PATH_ROOT, "{}", "LC_MESSAGES")
# Mo path generator for a given language (relative to any "locale" dir).
MO_PATH_ROOT_RELATIVE = os.path.join("locale")
@ -716,18 +701,13 @@ class I18nSettings:
else:
fname.write(self.to_json())
BRANCHES_DIR = property(*(_gen_get_set_path("I18N_DIR", "REL_BRANCHES_DIR")))
TRUNK_DIR = property(*(_gen_get_set_path("I18N_DIR", "REL_TRUNK_DIR")))
TRUNK_PO_DIR = property(*(_gen_get_set_path("I18N_DIR", "REL_TRUNK_PO_DIR")))
TRUNK_MO_DIR = property(*(_gen_get_set_path("I18N_DIR", "REL_TRUNK_MO_DIR")))
GIT_I18N_ROOT = property(*(_gen_get_set_path("SOURCE_DIR", "REL_GIT_I18N_DIR")))
GIT_I18N_PO_DIR = property(*(_gen_get_set_path("GIT_I18N_ROOT", "REL_GIT_I18N_PO_DIR")))
WORK_DIR = property(*(_gen_get_set_path("I18N_DIR", "REL_WORK_DIR")))
BLENDER_I18N_ROOT = property(*(_gen_get_set_path("SOURCE_DIR", "REL_BLENDER_I18N_DIR")))
BLENDER_I18N_PO_DIR = property(*(_gen_get_set_path("BLENDER_I18N_ROOT", "REL_BLENDER_I18N_PO_DIR")))
POTFILES_SOURCE_DIR = property(*(_gen_get_set_path("SOURCE_DIR", "REL_POTFILES_SOURCE_DIR")))
PRESETS_DIR = property(*(_gen_get_set_path("SOURCE_DIR", "REL_PRESETS_DIR")))
TEMPLATES_DIR = property(*(_gen_get_set_path("SOURCE_DIR", "REL_TEMPLATES_DIR")))
FILE_NAME_POT = property(*(_gen_get_set_path("I18N_DIR", "REL_FILE_NAME_POT")))
MO_PATH_ROOT = property(*(_gen_get_set_path("I18N_DIR", "REL_MO_PATH_ROOT")))
MO_PATH_TEMPLATE = property(*(_gen_get_set_path("I18N_DIR", "REL_MO_PATH_TEMPLATE")))
def _get_py_sys_paths(self):
return self.INTERN_PY_SYS_PATHS

View File

@ -55,7 +55,7 @@ def get_best_similar(data):
return key, tmp
_locale_explode_re = re.compile(r"^([a-z]{2,})(?:_([A-Z]{2,}))?(?:@([a-z]{2,}))?$")
_locale_explode_re = re.compile(r"^([a-z]{2,})(?:_([A-Za-z]{2,}))?(?:@([a-z]{2,}))?$")
def locale_explode(locale):

View File

@ -60,19 +60,19 @@ def language_menu(args, settings):
stats = {"DEFAULT": 1.0, "en_US": 1.0}
po_to_uid = {
os.path.basename(po_path_branch): uid
for can_use, uid, _num_id, _name, _isocode, po_path_branch
in utils_i18n.list_po_dir(settings.BRANCHES_DIR, settings)
os.path.basename(po_path_work): uid
for can_use, uid, _num_id, _name, _isocode, po_path_work
in utils_i18n.list_po_dir(settings.WORK_DIR, settings)
if can_use
}
for po_dir in os.listdir(settings.BRANCHES_DIR):
po_dir = os.path.join(settings.BRANCHES_DIR, po_dir)
for po_dir in os.listdir(settings.WORK_DIR):
po_dir = os.path.join(settings.WORK_DIR, po_dir)
if not os.path.isdir(po_dir):
continue
for po_path in os.listdir(po_dir):
uid = po_to_uid.get(po_path, None)
# print("Checking %s, found uid %s" % (po_path, uid))
po_path = os.path.join(settings.TRUNK_PO_DIR, po_path)
po_path = os.path.join(po_dir, po_path)
if uid is not None:
po = utils_i18n.I18nMessages(uid=uid, kind='PO', src=po_path, settings=settings)
stats[uid] = po.nbr_trans_msgs / po.nbr_msgs if po.nbr_msgs > 0 else 0

View File

@ -8433,7 +8433,7 @@ class VIEW3D_AST_sculpt_brushes(bpy.types.AssetShelf):
@classmethod
def asset_poll(cls, asset):
return asset.file_data.id_type == 'BRUSH'
return asset.id_type == 'BRUSH'
classes = (

View File

@ -11,7 +11,7 @@ class MyAssetShelf(bpy.types.AssetShelf):
@classmethod
def asset_poll(cls, asset):
return asset.file_data.id_type in {'MATERIAL', 'OBJECT'}
return asset.id_type in {'MATERIAL', 'OBJECT'}
def register():

View File

@ -13,6 +13,15 @@
#include "BKE_context.h"
#ifdef __cplusplus
namespace blender::asset_system {
class AssetRepresentation;
}
using AssetRepresentationHandle = blender::asset_system::AssetRepresentation;
#else
typedef struct AssetRepresentationHandle AssetRepresentationHandle;
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -464,12 +473,13 @@ typedef struct AssetShelfType {
/** Determine if an individual asset should be visible or not. May be a temporary design,
* visibility should first and foremost be controlled by asset traits. */
bool (*asset_poll)(const struct AssetShelfType *shelf_type, const struct AssetHandle *asset);
bool (*asset_poll)(const struct AssetShelfType *shelf_type,
const AssetRepresentationHandle *asset);
/** Asset shelves can define their own context menu via this layout definition callback. */
void (*draw_context_menu)(const struct bContext *C,
const struct AssetShelfType *shelf_type,
const struct AssetHandle *asset,
const AssetRepresentationHandle *asset,
struct uiLayout *layout);
/* RNA integration */

View File

@ -728,13 +728,13 @@ static blender::bke::GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph,
continue;
}
blender::bke::ScopedModifierTimer modifier_timer{*md};
if (md->type == eModifierType_Nodes) {
mti->modify_geometry_set(md, &mectx_apply, &geometry_set);
continue;
}
blender::bke::ScopedModifierTimer modifier_timer{*md};
if (!geometry_set.has_mesh()) {
geometry_set.replace_mesh(BKE_mesh_new_nomain(0, 0, 0, 0));
}

View File

@ -23,7 +23,7 @@ void BLT_lang_free(void);
/* Set the current locale. */
void BLT_lang_set(const char *);
/* Get the current locale ([partial] ISO code, e.g. es_ES). */
/* Get the current locale ([partial] ISO code, e.g. `pt_BR`). */
const char *BLT_lang_get(void);
/* Get locale's elements (if relevant pointer is not NULL and element actually exists, e.g.

View File

@ -18,7 +18,6 @@
#include "AS_asset_catalog_tree.hh"
struct AssetFilterSettings;
struct AssetHandle;
struct AssetLibraryReference;
struct bContext;
@ -55,7 +54,7 @@ struct AssetItemTree {
asset_system::AssetCatalogTree build_filtered_catalog_tree(
const asset_system::AssetLibrary &library,
const AssetLibraryReference &library_ref,
blender::FunctionRef<bool(const AssetHandle &)> is_asset_visible_fn);
blender::FunctionRef<bool(const asset_system::AssetRepresentation &)> is_asset_visible_fn);
AssetItemTree build_filtered_all_catalog_tree(
const AssetLibraryReference &library_ref,
const bContext &C,

View File

@ -55,17 +55,17 @@ namespace blender::ed::asset {
asset_system::AssetCatalogTree build_filtered_catalog_tree(
const asset_system::AssetLibrary &library,
const AssetLibraryReference &library_ref,
const blender::FunctionRef<bool(const AssetHandle &)> is_asset_visible_fn)
const blender::FunctionRef<bool(const asset_system::AssetRepresentation &)>
is_asset_visible_fn)
{
Set<StringRef> known_paths;
/* Collect paths containing assets. */
ED_assetlist_iterate(library_ref, [&](AssetHandle asset_handle) {
if (!is_asset_visible_fn(asset_handle)) {
ED_assetlist_iterate(library_ref, [&](asset_system::AssetRepresentation &asset) {
if (!is_asset_visible_fn(asset)) {
return true;
}
asset_system::AssetRepresentation &asset = *ED_asset_handle_get_representation(&asset_handle);
const AssetMetaData &meta_data = asset.get_metadata();
if (BLI_uuid_is_nil(meta_data.catalog_id)) {
return true;

View File

@ -104,12 +104,13 @@ void AssetView::build_items()
}
ED_assetlist_iterate(library_ref_, [&](AssetHandle asset_handle) {
if (shelf_.type->asset_poll && !shelf_.type->asset_poll(shelf_.type, &asset_handle)) {
const asset_system::AssetRepresentation *asset = ED_asset_handle_get_representation(
&asset_handle);
if (shelf_.type->asset_poll && !shelf_.type->asset_poll(shelf_.type, asset)) {
return true;
}
const asset_system::AssetRepresentation *asset = ED_asset_handle_get_representation(
&asset_handle);
const AssetMetaData &asset_data = asset->get_metadata();
if (catalog_filter_ && !catalog_filter_->contains(asset_data.catalog_id)) {
@ -213,7 +214,8 @@ void AssetViewItem::build_context_menu(bContext &C, uiLayout &column) const
const AssetView &asset_view = dynamic_cast<const AssetView &>(get_view());
const AssetShelfType &shelf_type = *asset_view.shelf_.type;
if (shelf_type.draw_context_menu) {
shelf_type.draw_context_menu(&C, &shelf_type, &asset_, &column);
asset_system::AssetRepresentation *asset = ED_asset_handle_get_representation(&asset_);
shelf_type.draw_context_menu(&C, &shelf_type, asset, &column);
}
}

View File

@ -45,8 +45,10 @@ class AssetCatalogSelectorTree : public ui::AbstractTreeView {
: shelf_(shelf), shelf_settings_(shelf_.settings)
{
catalog_tree_ = build_filtered_catalog_tree(
library, asset_system::all_library_reference(), [this](const AssetHandle asset_handle) {
return (!shelf_.type->asset_poll || shelf_.type->asset_poll(shelf_.type, &asset_handle));
library,
asset_system::all_library_reference(),
[this](const asset_system::AssetRepresentation &asset) {
return (!shelf_.type->asset_poll || shelf_.type->asset_poll(shelf_.type, &asset));
});
}

View File

@ -23,7 +23,6 @@
struct ARegion;
struct AssetFilterSettings;
struct AssetRepresentation;
struct AutoComplete;
struct EnumPropertyItem;
struct FileSelectParams;
@ -74,6 +73,7 @@ struct uiBut;
struct uiButExtraOpIcon;
struct uiLayout;
struct uiPopupBlockHandle;
struct uiTooltipData;
/* C handle for C++ #ui::AbstractView type. */
struct uiViewHandle;
/* C handle for C++ #ui::AbstractViewItem type. */
@ -582,6 +582,8 @@ using uiButSearchListenFn = void (*)(const wmRegionListenerParams *params, void
/** Must return an allocated string. */
using uiButToolTipFunc = char *(*)(bContext *C, void *argN, const char *tip);
using uiButToolTipCustomFunc = void (*)(bContext *C, uiTooltipData *data, void *argN);
using uiBlockHandleFunc = void (*)(bContext *C, void *arg, int event);
/* -------------------------------------------------------------------- */
@ -1749,6 +1751,41 @@ void UI_but_func_menu_step_set(uiBut *but, uiMenuStepFunc func);
void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *arg, uiFreeArgFunc free_arg);
void UI_but_func_tooltip_label_set(uiBut *but, std::function<std::string(const uiBut *but)> func);
typedef enum UiTooltipStyle {
UI_TIP_STYLE_NORMAL = 0, /* Regular text. */
UI_TIP_STYLE_HEADER, /* Header text. */
UI_TIP_STYLE_MONO, /* Monspaced text. */
UI_TIP_STYLE_IMAGE, /* Image field. */
} UiTooltipStyle;
typedef enum UiTooltipColor {
UI_TIP_LC_MAIN = 0, /* Color of primary text. */
UI_TIP_LC_VALUE, /* Color for the value of buttons (also shortcuts). */
UI_TIP_LC_ACTIVE, /* Color of titles of active enum values. */
UI_TIP_LC_NORMAL, /* Color of regular text. */
UI_TIP_LC_PYTHON, /* Color of python snippets. */
UI_TIP_LC_ALERT, /* Warning text color, eg: why operator can't run. */
UI_TIP_LC_MAX
} UiTooltipColor;
void UI_but_func_tooltip_custom_set(uiBut *but,
uiButToolTipCustomFunc func,
void *arg,
uiFreeArgFunc free_arg);
void UI_tooltip_text_field_add(struct uiTooltipData *data,
char *text,
char *suffix,
const UiTooltipStyle style,
const UiTooltipColor color,
const bool is_pad = false);
void UI_tooltip_image_field_add(struct uiTooltipData *data,
struct ImBuf *image,
short width,
short height);
/**
* Recreate tool-tip (use to update dynamic tips)
*/

View File

@ -6053,6 +6053,19 @@ void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *arg, uiFre
but->tip_arg_free = free_arg;
}
void UI_but_func_tooltip_custom_set(uiBut *but,
uiButToolTipCustomFunc func,
void *arg,
uiFreeArgFunc free_arg)
{
but->tip_custom_func = func;
if (but->tip_arg_free) {
but->tip_arg_free(but->tip_arg);
}
but->tip_arg = arg;
but->tip_arg_free = free_arg;
}
void UI_but_func_pushed_state_set(uiBut *but, std::function<bool(const uiBut &)> func)
{
but->pushed_state_func = func;

View File

@ -236,6 +236,8 @@ struct uiBut {
* #UI_BUT_HAS_TOOLTIP_LABEL drawflag. */
std::function<std::string(const uiBut *)> tip_label_func;
uiButToolTipCustomFunc tip_custom_func = nullptr;
/** info on why button is disabled, displayed in tooltip */
const char *disabled_info = nullptr;

View File

@ -1888,7 +1888,7 @@ static void edittranslation_find_po_file(const char *root,
return;
}
/* Now try without the second ISO code part (`_ES` in `es_ES`). */
/* Now try without the second ISO code part (`_BR` in `pt_BR`). */
{
const char *tc = nullptr;
size_t szt = 0;

View File

@ -37,6 +37,15 @@
#include "BKE_paint.hh"
#include "BKE_screen.h"
#include "BIF_glutil.hh"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_state.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "WM_api.hh"
#include "WM_types.hh"
@ -60,31 +69,13 @@
#define UI_TIP_PAD_FAC 1.3f
#define UI_TIP_PADDING int(UI_TIP_PAD_FAC * UI_UNIT_Y)
#define UI_TIP_MAXWIDTH 600
#define UI_TIP_MAXIMAGEWIDTH 500
#define UI_TIP_MAXIMAGEHEIGHT 300
#define UI_TIP_STR_MAX 1024
struct uiTooltipFormat {
enum class Style : int8_t {
Normal,
Header,
Mono,
};
enum class ColorID : int8_t {
/** Primary Text. */
Main = 0,
/** The value of buttons (also shortcuts). */
Value = 1,
/** Titles of active enum values. */
Active = 2,
/** Regular text. */
Normal = 3,
/** Python snippet. */
Python = 4,
/** Description of why an operator can't run. */
Alert = 5,
};
Style style;
ColorID color_id;
UiTooltipStyle style;
UiTooltipColor color_id;
bool is_pad;
};
@ -98,6 +89,9 @@ struct uiTooltipField {
uint lines;
} geom;
uiTooltipFormat format;
ImBuf *image;
short image_width;
short image_height;
};
struct uiTooltipData {
@ -109,10 +103,7 @@ struct uiTooltipData {
int toth, lineh;
};
#define UI_TIP_LC_MAX 6
BLI_STATIC_ASSERT(UI_TIP_LC_MAX == int(uiTooltipFormat::ColorID::Alert) + 1, "invalid lc-max");
BLI_STATIC_ASSERT(sizeof(uiTooltipFormat) <= sizeof(int), "oversize");
BLI_STATIC_ASSERT(int(UI_TIP_LC_MAX) == int(UI_TIP_LC_ALERT) + 1, "invalid lc-max");
static uiTooltipField *text_field_add_only(uiTooltipData *data)
{
@ -122,24 +113,34 @@ static uiTooltipField *text_field_add_only(uiTooltipData *data)
return &data->fields[data->fields_len - 1];
}
// static uiTooltipField *text_field_add(uiTooltipData *data, const uiTooltipFormat *format)
// {
// uiTooltipField *field = text_field_add_only(data);
// field->format = *format;
// return field;
// }
static uiTooltipField *text_field_add(uiTooltipData *data,
const uiTooltipFormat::Style style,
const uiTooltipFormat::ColorID color,
const bool is_pad = false)
void UI_tooltip_text_field_add(uiTooltipData *data,
char *text,
char *suffix,
const UiTooltipStyle style,
const UiTooltipColor color,
const bool is_pad)
{
uiTooltipField *field = text_field_add_only(data);
field->format = {};
field->format.style = style;
field->format.color_id = color;
field->format.is_pad = is_pad;
return field;
field->text = text ? text : nullptr;
field->text_suffix = suffix ? suffix : nullptr;
}
void UI_tooltip_image_field_add(uiTooltipData *data,
struct ImBuf *image,
short width,
short height)
{
uiTooltipField *field = text_field_add_only(data);
field->format = {};
field->format.style = UI_TIP_STYLE_IMAGE;
field->image = IMB_dupImBuf(image);
field->image_width = MIN2(width, UI_TIP_MAXIMAGEWIDTH * UI_SCALE_FAC);
field->image_height = MIN2(height, UI_TIP_MAXIMAGEHEIGHT * UI_SCALE_FAC);
field->text = nullptr;
}
/* -------------------------------------------------------------------- */
@ -170,12 +171,12 @@ static void ui_tooltip_region_draw_cb(const bContext * /*C*/, ARegion *region)
uchar drawcol[4] = {0, 0, 0, 255}; /* to store color in while drawing (alpha is always 255) */
/* The color from the theme. */
float *main_color = tip_colors[int(uiTooltipFormat::ColorID::Main)];
float *value_color = tip_colors[int(uiTooltipFormat::ColorID::Value)];
float *active_color = tip_colors[int(uiTooltipFormat::ColorID::Active)];
float *normal_color = tip_colors[int(uiTooltipFormat::ColorID::Normal)];
float *python_color = tip_colors[int(uiTooltipFormat::ColorID::Python)];
float *alert_color = tip_colors[int(uiTooltipFormat::ColorID::Alert)];
float *main_color = tip_colors[UI_TIP_LC_MAIN];
float *value_color = tip_colors[UI_TIP_LC_VALUE];
float *active_color = tip_colors[UI_TIP_LC_ACTIVE];
float *normal_color = tip_colors[UI_TIP_LC_NORMAL];
float *python_color = tip_colors[UI_TIP_LC_PYTHON];
float *alert_color = tip_colors[UI_TIP_LC_ALERT];
float background_color[3];
@ -220,13 +221,13 @@ static void ui_tooltip_region_draw_cb(const bContext * /*C*/, ARegion *region)
nullptr;
bbox.ymin = bbox.ymax - (data->lineh * field->geom.lines);
if (field->format.style == uiTooltipFormat::Style::Header) {
if (field->format.style == UI_TIP_STYLE_HEADER) {
uiFontStyleDraw_Params fs_params{};
fs_params.align = UI_STYLE_TEXT_LEFT;
fs_params.word_wrap = true;
/* Draw header and active data (is done here to be able to change color). */
rgb_float_to_uchar(drawcol, tip_colors[int(uiTooltipFormat::ColorID::Main)]);
rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_MAIN]);
UI_fontstyle_set(&data->fstyle);
UI_fontstyle_draw(&data->fstyle, &bbox, field->text, UI_TIP_STR_MAX, drawcol, &fs_params);
@ -237,7 +238,7 @@ static void ui_tooltip_region_draw_cb(const bContext * /*C*/, ARegion *region)
bbox.xmin += xofs;
bbox.ymax -= yofs;
rgb_float_to_uchar(drawcol, tip_colors[int(uiTooltipFormat::ColorID::Active)]);
rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_ACTIVE]);
UI_fontstyle_draw(
&data->fstyle, &bbox, field->text_suffix, UI_TIP_STR_MAX, drawcol, &fs_params);
@ -246,7 +247,7 @@ static void ui_tooltip_region_draw_cb(const bContext * /*C*/, ARegion *region)
bbox.ymax += yofs;
}
}
else if (field->format.style == uiTooltipFormat::Style::Mono) {
else if (field->format.style == UI_TIP_STYLE_MONO) {
uiFontStyleDraw_Params fs_params{};
fs_params.align = UI_STYLE_TEXT_LEFT;
fs_params.word_wrap = true;
@ -259,8 +260,31 @@ static void ui_tooltip_region_draw_cb(const bContext * /*C*/, ARegion *region)
rgb_float_to_uchar(drawcol, tip_colors[int(field->format.color_id)]);
UI_fontstyle_draw(&fstyle_mono, &bbox, field->text, UI_TIP_STR_MAX, drawcol, &fs_params);
}
else if (field->format.style == UI_TIP_STYLE_IMAGE) {
bbox.ymax -= field->image_height;
bbox.ymin -= field->image_height;
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_3D_IMAGE_COLOR);
immDrawPixelsTexScaledFullSize(&state,
bbox.xmin,
bbox.ymax,
field->image->x,
field->image->y,
GPU_RGBA8,
true,
field->image->byte_buffer.data,
1.0f,
1.0f,
(float)field->image_width / (float)field->image->x,
(float)field->image_height / (float)field->image->y,
NULL);
GPU_blend(GPU_BLEND_ALPHA);
}
else {
BLI_assert(field->format.style == uiTooltipFormat::Style::Normal);
BLI_assert(field->format.style == UI_TIP_STYLE_NORMAL);
uiFontStyleDraw_Params fs_params{};
fs_params.align = UI_STYLE_TEXT_LEFT;
fs_params.word_wrap = true;
@ -288,10 +312,15 @@ static void ui_tooltip_region_free_cb(ARegion *region)
for (int i = 0; i < data->fields_len; i++) {
const uiTooltipField *field = &data->fields[i];
MEM_freeN(field->text);
if (field->text) {
MEM_freeN(field->text);
}
if (field->text_suffix) {
MEM_freeN(field->text_suffix);
}
if (field->image) {
IMB_freeImBuf(field->image);
}
}
MEM_freeN(data->fields);
MEM_freeN(data);
@ -332,27 +361,34 @@ static bool ui_tooltip_data_append_from_keymap(bContext *C, uiTooltipData *data,
if (ot != nullptr) {
/* Tip. */
{
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Main, true);
field->text = BLI_strdup(ot->description ? ot->description : ot->name);
UI_tooltip_text_field_add(data,
BLI_strdup(ot->description ? ot->description : ot->name),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_MAIN,
true);
}
/* Shortcut. */
{
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Normal);
bool found = false;
if (WM_keymap_item_to_string(kmi, false, buf, sizeof(buf))) {
found = true;
}
field->text = BLI_sprintfN(TIP_("Shortcut: %s"), found ? buf : "None");
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Shortcut: %s"), found ? buf : "None"),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_NORMAL);
}
/* Python. */
if (U.flag & USER_TOOLTIPS_PYTHON) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Python);
char *str = ui_tooltip_text_python_from_op(C, ot, kmi->ptr);
field->text = BLI_sprintfN(TIP_("Python: %s"), str);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Python: %s"), str),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_PYTHON);
MEM_freeN(str);
}
}
@ -456,13 +492,12 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
expr_result = BLI_strdup(label_str);
}
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Main, true);
field->text = expr_result;
if (UNLIKELY(is_error)) {
field->format.color_id = uiTooltipFormat::ColorID::Alert;
}
UI_tooltip_text_field_add(data,
expr_result,
nullptr,
UI_TIP_STYLE_NORMAL,
(is_error) ? UI_TIP_LC_ALERT : UI_TIP_LC_MAIN,
true);
}
}
@ -497,13 +532,12 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
}
if (expr_result != nullptr) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Main, true);
field->text = expr_result;
if (UNLIKELY(is_error)) {
field->format.color_id = uiTooltipFormat::ColorID::Alert;
}
UI_tooltip_text_field_add(data,
expr_result,
nullptr,
UI_TIP_STYLE_NORMAL,
(is_error) ? UI_TIP_LC_ALERT : UI_TIP_LC_MAIN,
true);
}
}
@ -612,9 +646,12 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
}
if (shortcut != nullptr) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true);
field->text = BLI_sprintfN(TIP_("Shortcut: %s"), shortcut);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Shortcut: %s"), shortcut),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_VALUE,
true);
MEM_freeN(shortcut);
}
}
@ -684,19 +721,25 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
MEM_freeN(expr_result);
if (shortcut[0] != '\0') {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true);
field->text = BLI_sprintfN(TIP_("Shortcut Cycle: %s"), shortcut);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Shortcut Cycle: %s"), shortcut),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_VALUE,
true);
}
}
}
/* Python */
if ((is_label == false) && (U.flag & USER_TOOLTIPS_PYTHON)) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Python, true);
char *str = ui_tooltip_text_python_from_op(C, but->optype, but->opptr);
field->text = BLI_sprintfN(TIP_("Python: %s"), str);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Python: %s"), str),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_PYTHON,
true);
MEM_freeN(str);
}
@ -722,11 +765,12 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
}
else if (BPY_run_string_as_intptr(C, expr_imports, expr, nullptr, &expr_result)) {
if (expr_result != 0) {
{
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Normal, true);
field->text = BLI_strdup("Tool Keymap:");
}
UI_tooltip_text_field_add(data,
BLI_strdup("Tool Keymap:"),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_NORMAL,
true);
wmKeyMap *keymap = (wmKeyMap *)expr_result;
ui_tooltip_data_append_from_keymap(C, data, keymap);
}
@ -804,59 +848,68 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
* can already provide more accurate and specific tool-tip content. */
!but->tip_func)
{
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Header, uiTooltipFormat::ColorID::Normal);
field->text = BLI_strdup(but_tip_label.strinfo);
UI_tooltip_text_field_add(
data, BLI_strdup(but_label.strinfo), nullptr, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL);
}
/* Tip */
if (but_tip.strinfo) {
{
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Header, uiTooltipFormat::ColorID::Normal);
if (enum_label.strinfo) {
field->text = BLI_sprintfN("%s: ", but_tip.strinfo);
field->text_suffix = BLI_strdup(enum_label.strinfo);
UI_tooltip_text_field_add(data,
BLI_sprintfN("%s: ", but_tip.strinfo),
BLI_strdup(enum_label.strinfo),
UI_TIP_STYLE_HEADER,
UI_TIP_LC_NORMAL);
}
else {
field->text = BLI_sprintfN("%s.", but_tip.strinfo);
UI_tooltip_text_field_add(data,
BLI_sprintfN("%s.", but_tip.strinfo),
nullptr,
UI_TIP_STYLE_HEADER,
UI_TIP_LC_NORMAL);
}
}
/* special case enum rna buttons */
if ((but->type & UI_BTYPE_ROW) && rnaprop && RNA_property_flag(rnaprop) & PROP_ENUM_FLAG) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Normal);
field->text = BLI_strdup(TIP_("(Shift-Click/Drag to select multiple)"));
UI_tooltip_text_field_add(data,
BLI_strdup(TIP_("(Shift-Click/Drag to select multiple)")),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_NORMAL);
}
}
/* When there is only an enum label (no button label or tip), draw that as header. */
else if (enum_label.strinfo && !(but_label.strinfo && but_label.strinfo[0])) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Header, uiTooltipFormat::ColorID::Normal);
field->text = BLI_strdup(enum_label.strinfo);
UI_tooltip_text_field_add(
data, BLI_strdup(enum_label.strinfo), nullptr, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL);
}
/* Enum field label & tip. */
if (enum_tip.strinfo) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value);
field->text = BLI_strdup(enum_tip.strinfo);
UI_tooltip_text_field_add(
data, BLI_strdup(enum_tip.strinfo), nullptr, UI_TIP_STYLE_NORMAL, UI_TIP_LC_VALUE);
}
/* Operator shortcut. */
if (op_keymap.strinfo) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true);
field->text = BLI_sprintfN(TIP_("Shortcut: %s"), op_keymap.strinfo);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Shortcut: %s"), op_keymap.strinfo),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_VALUE,
true);
}
/* Property context-toggle shortcut. */
if (prop_keymap.strinfo) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true);
field->text = BLI_sprintfN(TIP_("Shortcut: %s"), prop_keymap.strinfo);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Shortcut: %s"), prop_keymap.strinfo),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_VALUE,
true);
}
if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
@ -865,9 +918,12 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
/* Full string. */
ui_but_string_get(but, buf, sizeof(buf));
if (buf[0]) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true);
field->text = BLI_sprintfN(TIP_("Value: %s"), buf);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Value: %s"), buf),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_VALUE,
true);
}
}
}
@ -880,27 +936,32 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
float value = RNA_property_array_check(rnaprop) ?
RNA_property_float_get_index(&but->rnapoin, rnaprop, but->rnaindex) :
RNA_property_float_get(&but->rnapoin, rnaprop);
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value);
field->text = BLI_sprintfN(TIP_("Radians: %f"), value);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Radians: %f"), value),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_VALUE);
}
}
if (but->flag & UI_BUT_DRIVEN) {
if (ui_but_anim_expression_get(but, buf, sizeof(buf))) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Normal);
field->text = BLI_sprintfN(TIP_("Expression: %s"), buf);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Expression: %s"), buf),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_NORMAL);
}
}
if (but->rnapoin.owner_id) {
const ID *id = but->rnapoin.owner_id;
if (ID_IS_LINKED(id)) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Normal);
field->text = BLI_sprintfN(TIP_("Library: %s"), id->lib->filepath);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Library: %s"), id->lib->filepath),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_NORMAL);
}
}
}
@ -916,9 +977,12 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
/* Operator info. */
if (U.flag & USER_TOOLTIPS_PYTHON) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Mono, uiTooltipFormat::ColorID::Python, true);
field->text = BLI_sprintfN(TIP_("Python: %s"), str);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Python: %s"), str),
nullptr,
UI_TIP_STYLE_MONO,
UI_TIP_LC_PYTHON,
true);
}
MEM_freeN(str);
@ -946,9 +1010,11 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
}
if (disabled_msg && disabled_msg[0]) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Alert);
field->text = BLI_sprintfN(TIP_("Disabled: %s"), disabled_msg);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Disabled: %s"), disabled_msg),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_ALERT);
}
if (disabled_msg_free) {
MEM_freeN((void *)disabled_msg);
@ -957,32 +1023,25 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
if ((U.flag & USER_TOOLTIPS_PYTHON) && !optype && rna_struct.strinfo) {
{
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Mono, uiTooltipFormat::ColorID::Python, true);
if (rna_prop.strinfo) {
/* Struct and prop */
field->text = BLI_sprintfN(TIP_("Python: %s.%s"), rna_struct.strinfo, rna_prop.strinfo);
}
else {
/* Only struct (e.g. menus). */
field->text = BLI_sprintfN(TIP_("Python: %s"), rna_struct.strinfo);
}
UI_tooltip_text_field_add(
data,
(rna_prop.strinfo) ?
BLI_sprintfN(TIP_("Python: %s.%s"), rna_struct.strinfo, rna_prop.strinfo) :
BLI_sprintfN(TIP_("Python: %s"), rna_struct.strinfo),
nullptr,
UI_TIP_STYLE_MONO,
UI_TIP_LC_PYTHON,
true);
}
if (but->rnapoin.owner_id) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Mono, uiTooltipFormat::ColorID::Python);
/* This could get its own `BUT_GET_...` type. */
/* never fails */
/* Move ownership (no need for re-allocation). */
if (rnaprop) {
field->text = RNA_path_full_property_py_ex(&but->rnapoin, rnaprop, but->rnaindex, true);
}
else {
field->text = RNA_path_full_struct_py(&but->rnapoin);
}
UI_tooltip_text_field_add(
data,
(rnaprop) ? RNA_path_full_property_py_ex(&but->rnapoin, rnaprop, but->rnaindex, true) :
RNA_path_full_struct_py(&but->rnapoin),
nullptr,
UI_TIP_STYLE_MONO,
UI_TIP_LC_PYTHON);
}
}
@ -1055,14 +1114,15 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
std::string info = WM_operatortype_description_or_name(C, gzop->type, &gzop->ptr);
if (!info.empty()) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Header, uiTooltipFormat::ColorID::Value, true);
if (gzop_actions[i].prefix != nullptr) {
field->text = BLI_sprintfN("%s: %s", gzop_actions[i].prefix, info.c_str());
}
else {
field->text = BLI_strdup(info.c_str());
}
UI_tooltip_text_field_add(
data,
gzop_actions[i].prefix ?
BLI_sprintfN("%s: %s", gzop_actions[i].prefix, info.c_str()) :
BLI_strdup(info.c_str()),
nullptr,
UI_TIP_STYLE_HEADER,
UI_TIP_LC_VALUE,
true);
}
/* Shortcut */
@ -1072,9 +1132,12 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
if (WM_key_event_operator_string(
C, gzop->type->idname, WM_OP_INVOKE_DEFAULT, prop, true, buf, ARRAY_SIZE(buf)))
{
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true);
field->text = BLI_sprintfN(TIP_("Shortcut: %s"), buf);
UI_tooltip_text_field_add(data,
BLI_sprintfN(TIP_("Shortcut: %s"), buf),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_VALUE,
true);
}
}
}
@ -1090,9 +1153,8 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
if (gz_prop->prop != nullptr) {
const char *info = RNA_property_ui_description(gz_prop->prop);
if (info && info[0]) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true);
field->text = BLI_strdup(info);
UI_tooltip_text_field_add(
data, BLI_strdup(info), nullptr, UI_TIP_STYLE_NORMAL, UI_TIP_LC_VALUE, true);
}
}
}
@ -1154,33 +1216,41 @@ static ARegion *ui_tooltip_create_with_data(bContext *C,
uiTooltipField *field = &data->fields[i];
uiTooltipField *field_next = (i + 1) != data->fields_len ? &data->fields[i + 1] : nullptr;
ResultBLF info;
int w, x_pos = 0;
ResultBLF info = {0};
int w = 0;
int x_pos = 0;
int font_id;
if (field->format.style == uiTooltipFormat::Style::Mono) {
if (field->format.style == UI_TIP_STYLE_MONO) {
BLF_size(blf_mono_font, data->fstyle.points * UI_SCALE_FAC);
font_id = blf_mono_font;
}
else {
BLI_assert(ELEM(
field->format.style, uiTooltipFormat::Style::Normal, uiTooltipFormat::Style::Header));
font_id = data->fstyle.uifont_id;
}
w = BLF_width_ex(font_id, field->text, UI_TIP_STR_MAX, &info);
if (field->text && field->text[0]) {
w = BLF_width_ex(font_id, field->text, UI_TIP_STR_MAX, &info);
}
/* check for suffix (enum label) */
if (field->text_suffix && field->text_suffix[0]) {
x_pos = info.width;
w = max_ii(w, x_pos + BLF_width(font_id, field->text_suffix, UI_TIP_STR_MAX));
}
fontw = max_ii(fontw, w);
fonth += h * info.lines;
if (field_next && field_next->format.is_pad) {
fonth += h * (UI_TIP_PAD_FAC - 1);
}
if (field->format.style == UI_TIP_STYLE_IMAGE) {
fonth += field->image_height;
w = field->image_width;
}
fontw = max_ii(fontw, w);
field->geom.lines = info.lines;
field->geom.x_pos = x_pos;
}
@ -1368,6 +1438,11 @@ ARegion *UI_tooltip_create_from_button_or_extra_icon(
}
uiTooltipData *data = nullptr;
if (but->tip_custom_func) {
data = (uiTooltipData *)MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
but->tip_custom_func(C, data, but->tip_arg);
}
if (data == nullptr) {
data = ui_tooltip_data_from_tool(C, but, is_label);
}
@ -1450,20 +1525,29 @@ static uiTooltipData *ui_tooltip_data_from_search_item_tooltip_data(
uiTooltipData *data = MEM_cnew<uiTooltipData>(__func__);
if (item_tooltip_data->description[0]) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Header, uiTooltipFormat::ColorID::Normal, true);
field->text = BLI_strdup(item_tooltip_data->description);
UI_tooltip_text_field_add(data,
BLI_strdup(item_tooltip_data->description),
nullptr,
UI_TIP_STYLE_HEADER,
UI_TIP_LC_NORMAL,
true);
}
if (item_tooltip_data->name && item_tooltip_data->name[0]) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true);
field->text = BLI_strdup(item_tooltip_data->name);
UI_tooltip_text_field_add(data,
BLI_strdup(item_tooltip_data->name),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_VALUE,
true);
}
if (item_tooltip_data->hint[0]) {
uiTooltipField *field = text_field_add(
data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Normal, true);
field->text = BLI_strdup(item_tooltip_data->hint);
UI_tooltip_text_field_add(data,
BLI_strdup(item_tooltip_data->hint),
nullptr,
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_NORMAL,
true);
}
if (data->fields_len == 0) {

View File

@ -45,11 +45,11 @@
#include "ED_armature.hh"
#include "ED_gpencil_legacy.hh"
#include "ED_outliner.hh"
#include "ED_screen.hh"
#include "ED_transform_snap_object_context.hh"
#include "ED_undo.hh"
#include "ED_view3d.hh"
#include "ED_outliner.hh"
#include "WM_toolsystem.h"

View File

@ -303,24 +303,8 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
const char *str_dir = (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_RIGHT) ?
TIP_("right") :
TIP_("left");
char str_dir_km[64];
WM_modalkeymap_items_to_string(
t->keymap, TFM_MODAL_INSERTOFS_TOGGLE_DIR, true, str_dir_km, sizeof(str_dir_km));
ofs += BLI_snprintf_rlen(str,
UI_MAX_DRAW_STR,
TIP_("%s: Toggle auto-offset direction (%s)"),
str_dir_km,
str_dir);
ofs += BLI_snprintf_rlen(str, UI_MAX_DRAW_STR, TIP_("Auto-offset direction: %s"), str_dir);
}
char str_attach_km[64];
WM_modalkeymap_items_to_string(
t->keymap, TFM_MODAL_NODE_ATTACH_OFF, true, str_attach_km, sizeof(str_attach_km));
ofs += BLI_snprintf_rlen(str + ofs,
UI_MAX_DRAW_STR - ofs,
TIP_(", %s: Toggle auto-attach (%s)"),
str_attach_km,
WM_bool_as_string((t->modifiers & MOD_NODE_ATTACH) != 0));
}
else {
if (t->flag & T_2D_EDIT) {

View File

@ -610,6 +610,8 @@ static void rna_def_asset_representation(BlenderRNA *brna)
RNA_def_property_ui_text(
prop,
"Data-block Type",
/* Won't ever actually return 'NONE' currently, this is just for information for once non-ID
* assets are supported. */
"The type of the data-block, if the asset represents one ('NONE' otherwise)");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
}

View File

@ -1071,7 +1071,8 @@ static StructRNA *rna_Menu_refine(PointerRNA *mtr)
/* Asset Shelf */
static bool asset_shelf_asset_poll(const AssetShelfType *shelf_type, const AssetHandle *asset)
static bool asset_shelf_asset_poll(const AssetShelfType *shelf_type,
const AssetRepresentationHandle *asset)
{
extern FunctionRNA rna_AssetShelf_asset_poll_func;
@ -1080,7 +1081,7 @@ static bool asset_shelf_asset_poll(const AssetShelfType *shelf_type, const Asset
ParameterList list;
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "asset_handle", &asset);
RNA_parameter_set_lookup(&list, "asset", &asset);
shelf_type->rna_ext.call(nullptr, &ptr, func, &list);
void *ret;
@ -1117,7 +1118,7 @@ static bool asset_shelf_poll(const bContext *C, const AssetShelfType *shelf_type
static void asset_shelf_draw_context_menu(const bContext *C,
const AssetShelfType *shelf_type,
const AssetHandle *asset,
const AssetRepresentationHandle *asset,
uiLayout *layout)
{
extern FunctionRNA rna_AssetShelf_draw_context_menu_func;
@ -1130,7 +1131,7 @@ static void asset_shelf_draw_context_menu(const bContext *C,
ParameterList list;
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "context", &C);
RNA_parameter_set_lookup(&list, "asset_handle", &asset);
RNA_parameter_set_lookup(&list, "asset", &asset);
RNA_parameter_set_lookup(&list, "layout", &layout);
shelf_type->rna_ext.call((bContext *)C, &ptr, func, &list);
@ -2357,7 +2358,7 @@ static void rna_def_asset_shelf(BlenderRNA *brna)
"non-null output, the asset will be visible");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
RNA_def_function_return(func, RNA_def_boolean(func, "visible", true, "", ""));
parm = RNA_def_pointer(func, "asset_handle", "AssetHandle", "", "");
parm = RNA_def_pointer(func, "asset", "AssetRepresentation", "", "");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "draw_context_menu", nullptr);
@ -2366,7 +2367,7 @@ static void rna_def_asset_shelf(BlenderRNA *brna)
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
parm = RNA_def_pointer(func, "context", "Context", "", "");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func, "asset_handle", "AssetHandle", "", "");
parm = RNA_def_pointer(func, "asset", "AssetRepresentation", "", "");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func, "layout", "UILayout", "", "");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);

View File

@ -62,6 +62,10 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions,
const float radius,
const AttributeIDRef &uv_map_id)
{
if (subdivisions >= 3) {
lazy_threading::send_hint();
}
const float4x4 transform = float4x4::identity();
const bool create_uv_map = bool(uv_map_id);

View File

@ -1934,6 +1934,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
ImBuf *ibuf2 = seq_render_strip(context, state, seq, timeline_frame);
out = seq_render_strip_stack_apply_effect(context, seq, timeline_frame, ibuf1, ibuf2);
IMB_metadata_copy(out, ibuf2);
seq_cache_put(context, seq_arr[i], timeline_frame, SEQ_CACHE_STORE_COMPOSITE, out);

View File

@ -6277,10 +6277,11 @@ bool WM_window_modal_keymap_status_draw(bContext *C, wmWindow *win, uiLayout *la
wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
if (handler->op != nullptr) {
/* 'handler->keymap' could be checked too, seems not to be used. */
wmKeyMap *keymap_test = WM_keymap_active(wm, handler->op->type->modalkeymap);
wmOperator *op_test = handler->op->opm ? handler->op->opm : handler->op;
wmKeyMap *keymap_test = WM_keymap_active(wm, op_test->type->modalkeymap);
if (keymap_test && keymap_test->modal_items) {
keymap = keymap_test;
op = handler->op;
op = op_test;
break;
}
}