WIP: Brush assets project #106303
|
@ -134,9 +134,18 @@ BUILD_MANDATORY_SUBPACKAGES = (
|
|||
},
|
||||
),
|
||||
Package(name="Git",
|
||||
sub_packages=(
|
||||
Package(name="Git LFS",
|
||||
distro_package_names={DISTRO_ID_DEBIAN: "git-lfs",
|
||||
DISTRO_ID_FEDORA: "git-lfs",
|
||||
DISTRO_ID_SUSE: "git-lfs",
|
||||
DISTRO_ID_ARCH: "git-lfs",
|
||||
},
|
||||
),
|
||||
),
|
||||
distro_package_names={DISTRO_ID_DEBIAN: "git",
|
||||
DISTRO_ID_FEDORA: "git",
|
||||
DISTRO_ID_SUSE: None,
|
||||
DISTRO_ID_SUSE: "git",
|
||||
DISTRO_ID_ARCH: "git",
|
||||
},
|
||||
),
|
||||
|
|
|
@ -108,7 +108,9 @@ LightTreeEmitter::LightTreeEmitter(Scene *scene,
|
|||
|
||||
/* TODO: need a better way to handle this when textures are used. */
|
||||
float area = triangle_area(vertices[0], vertices[1], vertices[2]);
|
||||
measure.energy = area * average(shader->emission_estimate);
|
||||
/* Use absolute value of emission_estimate so lights with negative strength are properly
|
||||
* supported in the light tree. */
|
||||
measure.energy = area * average(fabs(shader->emission_estimate));
|
||||
|
||||
/* NOTE: the original implementation used the bounding box centroid, but triangle centroid
|
||||
* seems to work fine */
|
||||
|
@ -220,7 +222,7 @@ LightTreeEmitter::LightTreeEmitter(Scene *scene,
|
|||
|
||||
/* Use absolute value of energy so lights with negative strength are properly supported in the
|
||||
* light tree. */
|
||||
measure.energy = fabsf(average(strength));
|
||||
measure.energy = average(fabs(strength));
|
||||
|
||||
light_set_membership = lamp->get_light_set_membership();
|
||||
}
|
||||
|
|
|
@ -264,7 +264,7 @@ void Shader::estimate_emission()
|
|||
}
|
||||
|
||||
ShaderInput *surf = graph->output()->input("Surface");
|
||||
emission_estimate = fabs(output_estimate_emission(surf->link, emission_is_constant));
|
||||
emission_estimate = output_estimate_emission(surf->link, emission_is_constant);
|
||||
|
||||
if (is_zero(emission_estimate)) {
|
||||
emission_sampling = EMISSION_SAMPLING_NONE;
|
||||
|
@ -274,8 +274,9 @@ void Shader::estimate_emission()
|
|||
* using a lot of memory in the light tree and potentially wasting samples
|
||||
* where indirect light samples are sufficient.
|
||||
* Possible optimization: estimate front and back emission separately. */
|
||||
emission_sampling = (reduce_max(emission_estimate) > 0.5f) ? EMISSION_SAMPLING_FRONT_BACK :
|
||||
EMISSION_SAMPLING_NONE;
|
||||
emission_sampling = (reduce_max(fabs(emission_estimate)) > 0.5f) ?
|
||||
EMISSION_SAMPLING_FRONT_BACK :
|
||||
EMISSION_SAMPLING_NONE;
|
||||
}
|
||||
else {
|
||||
emission_sampling = emission_sampling_method;
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d2eea8a8a6b22d6ec6849deea72e141fc5b384d4
|
||||
Subproject commit 014844518a90dd96685f6f3f114b9ce6b2522e43
|
|
@ -1 +1 @@
|
|||
Subproject commit 6c8139034cfb05f8dee9f6648d31443792c160b5
|
||||
Subproject commit 9e78c2e377a75ab8fa33430d8e6567f34b2b05b2
|
|
@ -1 +1 @@
|
|||
Subproject commit bf950af1a7d197675bd28ce7d4920ba2b4a0a4f6
|
||||
Subproject commit 0a6d9ad4c6effa4227a9c0a324c7b588c1f9f71b
|
|
@ -1 +1 @@
|
|||
Subproject commit 2935423fe0636157750feef1fc02d8d0c3efd9dd
|
||||
Subproject commit 19b2b87f5ef0d8caa39e0882fbf832052974b785
|
|
@ -1 +1 @@
|
|||
Subproject commit 38a8f38d98987efc9aebe878ca941d99756e914e
|
||||
Subproject commit 3a36a5abc7b8866fe1e4d23ddea9aed1ff01c80d
|
|
@ -450,7 +450,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
** AutoPackage; version 1.0 -- http://autopackage.org
|
||||
BinReloc - a library for creating relocatable executables
|
||||
Written by: Hongli Lai <h.lai@chello.nl>
|
||||
** LZMA SDK; version 5.2.5 -- https://www.7-zip.org/sdk.html
|
||||
** LZMA SDK; version 23.01 -- https://www.7-zip.org/sdk.html
|
||||
LZMA SDK: Public Domain
|
||||
|
||||
Creative Commons Legal Code
|
||||
|
@ -3462,7 +3462,7 @@ SOFTWARE.
|
|||
|
||||
------
|
||||
|
||||
** {fmt}; version 10.0.0 -- https://github.com/fmtlib/fmt
|
||||
** {fmt}; version 10.1.1 -- https://github.com/fmtlib/fmt
|
||||
Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
|
||||
** Brotli; version 1.0.9 -- https://github.com/google/brotli
|
||||
Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
|
||||
|
|
|
@ -31,9 +31,9 @@
|
|||
*/
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "DNA_userdef_enums.h"
|
||||
|
||||
|
@ -662,9 +662,8 @@ bool BKE_id_is_editable(const Main *bmain, const ID *id);
|
|||
|
||||
/**
|
||||
* Returns ordered list of data-blocks for display in the UI.
|
||||
* Result is list of #LinkData of IDs that must be freed.
|
||||
*/
|
||||
void BKE_id_ordered_list(ListBase *ordered_lb, const ListBase *lb);
|
||||
blender::Vector<ID *> BKE_id_ordered_list(const ListBase *lb);
|
||||
/**
|
||||
* Reorder ID in the list, before or after the "relative" ID.
|
||||
*/
|
||||
|
|
|
@ -15,3 +15,9 @@ struct Library;
|
|||
struct Main;
|
||||
|
||||
void BKE_library_filepath_set(Main *bmain, Library *lib, const char *filepath);
|
||||
|
||||
/**
|
||||
* Rebuild the hierarchy of libraries, after e.g. deleting or relocating one, often some indirectly
|
||||
* linked libraries lose their 'parent' pointer, making them wrongly directly used ones.
|
||||
*/
|
||||
void BKE_library_main_rebuild_hierarchy(Main *bmain);
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "BKE_lib_override.hh"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_library.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_main_namemap.hh"
|
||||
#include "BKE_material.h"
|
||||
|
@ -1916,6 +1917,8 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
|
|||
}
|
||||
FOREACH_MAIN_ID_END;
|
||||
|
||||
BKE_library_main_rebuild_hierarchy(bmain);
|
||||
|
||||
/* Resync overrides if needed. */
|
||||
if (!USER_EXPERIMENTAL_TEST(&U, no_override_auto_resync)) {
|
||||
BlendFileReadReport report{};
|
||||
|
|
|
@ -77,6 +77,8 @@
|
|||
# include "BLI_time_utildefines.h"
|
||||
#endif
|
||||
|
||||
using blender::Vector;
|
||||
|
||||
using namespace blender::bke::id;
|
||||
|
||||
static CLG_LogRef LOG = {"bke.lib_id"};
|
||||
|
@ -2165,43 +2167,40 @@ static int *id_order_get(ID *id)
|
|||
}
|
||||
}
|
||||
|
||||
static int id_order_compare(const void *a, const void *b)
|
||||
static bool id_order_compare(ID *a, ID *b)
|
||||
{
|
||||
ID *id_a = static_cast<ID *>(((LinkData *)a)->data);
|
||||
ID *id_b = static_cast<ID *>(((LinkData *)b)->data);
|
||||
|
||||
int *order_a = id_order_get(id_a);
|
||||
int *order_b = id_order_get(id_b);
|
||||
int *order_a = id_order_get(a);
|
||||
int *order_b = id_order_get(b);
|
||||
|
||||
if (order_a && order_b) {
|
||||
if (*order_a < *order_b) {
|
||||
return -1;
|
||||
return true;
|
||||
}
|
||||
if (*order_a > *order_b) {
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return strcmp(id_a->name, id_b->name);
|
||||
return strcmp(a->name, b->name) <= 0;
|
||||
}
|
||||
|
||||
void BKE_id_ordered_list(ListBase *ordered_lb, const ListBase *lb)
|
||||
Vector<ID *> BKE_id_ordered_list(const ListBase *lb)
|
||||
{
|
||||
BLI_listbase_clear(ordered_lb);
|
||||
Vector<ID *> ordered;
|
||||
|
||||
LISTBASE_FOREACH (ID *, id, lb) {
|
||||
BLI_addtail(ordered_lb, BLI_genericNodeN(id));
|
||||
ordered.append(id);
|
||||
}
|
||||
|
||||
BLI_listbase_sort(ordered_lb, id_order_compare);
|
||||
std::sort(ordered.begin(), ordered.end(), id_order_compare);
|
||||
|
||||
int num = 0;
|
||||
LISTBASE_FOREACH (LinkData *, link, ordered_lb) {
|
||||
int *order = id_order_get(static_cast<ID *>(link->data));
|
||||
if (order) {
|
||||
*order = num++;
|
||||
for (const int i : ordered.index_range()) {
|
||||
if (int *order = id_order_get(ordered[i])) {
|
||||
*order = i;
|
||||
}
|
||||
}
|
||||
|
||||
return ordered;
|
||||
}
|
||||
|
||||
void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_override.hh"
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_library.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_main_namemap.hh"
|
||||
|
||||
|
@ -210,9 +211,15 @@ void BKE_id_free_us(Main *bmain, void *idv) /* test users */
|
|||
}
|
||||
|
||||
if (id->us == 0) {
|
||||
const bool is_lib = GS(id->name) == ID_LI;
|
||||
|
||||
BKE_libblock_unlink(bmain, id, false);
|
||||
|
||||
BKE_id_free(bmain, id);
|
||||
|
||||
if (is_lib) {
|
||||
BKE_library_main_rebuild_hierarchy(bmain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,6 +227,8 @@ static size_t id_delete(Main *bmain,
|
|||
blender::Set<ID *> &ids_to_delete,
|
||||
const int extra_remapping_flags)
|
||||
{
|
||||
bool has_deleted_library = false;
|
||||
|
||||
/* Used by batch tagged deletion, when we call BKE_id_free then, id is no more in Main database,
|
||||
* and has already properly unlinked its other IDs usages.
|
||||
* UI users are always cleared in BKE_libblock_remap_locked() call, so we can always skip it. */
|
||||
|
@ -318,6 +327,10 @@ static size_t id_delete(Main *bmain,
|
|||
* remapping code, depending on order in which these are handled). */
|
||||
id->us = ID_FAKE_USERS(id);
|
||||
|
||||
if (!has_deleted_library && GS(id->name) == ID_LI) {
|
||||
has_deleted_library = true;
|
||||
}
|
||||
|
||||
id_free(bmain, id, free_flag, false);
|
||||
}
|
||||
|
||||
|
@ -325,6 +338,10 @@ static size_t id_delete(Main *bmain,
|
|||
BKE_layer_collection_resync_allow();
|
||||
BKE_main_collection_sync_remap(bmain);
|
||||
|
||||
if (has_deleted_library) {
|
||||
BKE_library_main_rebuild_hierarchy(bmain);
|
||||
}
|
||||
|
||||
bmain->is_memfile_undo_written = false;
|
||||
return size_t(ids_to_delete.size());
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_set.hh"
|
||||
|
||||
#include "BLT_translation.hh"
|
||||
|
||||
|
@ -132,3 +134,158 @@ void BKE_library_filepath_set(Main *bmain, Library *lib, const char *filepath)
|
|||
BLI_path_abs(lib->filepath_abs, blendfile_path);
|
||||
}
|
||||
}
|
||||
|
||||
static void rebuild_hierarchy_best_parent_find(Main *bmain,
|
||||
blender::Set<Library *> &directly_used_libs,
|
||||
Library *lib)
|
||||
{
|
||||
BLI_assert(!directly_used_libs.contains(lib));
|
||||
|
||||
Library *best_parent_lib = nullptr;
|
||||
bool do_break = false;
|
||||
ListBase *lb;
|
||||
ID *id_iter;
|
||||
FOREACH_MAIN_LISTBASE_BEGIN (bmain, lb) {
|
||||
FOREACH_MAIN_LISTBASE_ID_BEGIN (lb, id_iter) {
|
||||
if (!ID_IS_LINKED(id_iter) || id_iter->lib != lib) {
|
||||
continue;
|
||||
}
|
||||
MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
|
||||
BLI_ghash_lookup(bmain->relations->relations_from_pointers, id_iter));
|
||||
for (MainIDRelationsEntryItem *item = entry->from_ids; item; item = item->next) {
|
||||
ID *from_id = item->id_pointer.from;
|
||||
if (!ID_IS_LINKED(from_id)) {
|
||||
BLI_assert_unreachable();
|
||||
continue;
|
||||
}
|
||||
Library *from_id_lib = from_id->lib;
|
||||
if (from_id_lib == lib) {
|
||||
continue;
|
||||
}
|
||||
if (directly_used_libs.contains(from_id_lib)) {
|
||||
/* Found the first best possible candidate, no need to search further. */
|
||||
BLI_assert(best_parent_lib == nullptr || best_parent_lib->temp_index > 0);
|
||||
best_parent_lib = from_id_lib;
|
||||
do_break = true;
|
||||
break;
|
||||
}
|
||||
if (!from_id_lib->parent) {
|
||||
rebuild_hierarchy_best_parent_find(bmain, directly_used_libs, from_id_lib);
|
||||
}
|
||||
if (!best_parent_lib || best_parent_lib->temp_index > from_id_lib->temp_index) {
|
||||
best_parent_lib = from_id_lib;
|
||||
if (best_parent_lib->temp_index == 0) {
|
||||
/* Found the first best possible candidate, no need to search further. */
|
||||
BLI_assert(directly_used_libs.contains(best_parent_lib));
|
||||
do_break = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (do_break) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
FOREACH_MAIN_LISTBASE_ID_END;
|
||||
if (do_break) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
FOREACH_MAIN_LISTBASE_END;
|
||||
|
||||
/* NOTE: It may happen that no parent library is found, e.g. if after deleting a directly used
|
||||
* library, its indirect dependency is still around, but none of its linked IDs are used by local
|
||||
* data. */
|
||||
if (best_parent_lib) {
|
||||
lib->parent = best_parent_lib;
|
||||
lib->temp_index = best_parent_lib->temp_index + 1;
|
||||
}
|
||||
else {
|
||||
lib->parent = nullptr;
|
||||
lib->temp_index = 0;
|
||||
directly_used_libs.add(lib);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_library_main_rebuild_hierarchy(Main *bmain)
|
||||
{
|
||||
BKE_main_relations_create(bmain, 0);
|
||||
|
||||
/* Find all libraries with directly linked IDs (i.e. IDs used by local data). */
|
||||
blender::Set<Library *> directly_used_libs;
|
||||
ID *id_iter;
|
||||
FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
|
||||
if (!ID_IS_LINKED(id_iter)) {
|
||||
continue;
|
||||
}
|
||||
id_iter->lib->temp_index = 0;
|
||||
if (directly_used_libs.contains(id_iter->lib)) {
|
||||
continue;
|
||||
}
|
||||
MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
|
||||
BLI_ghash_lookup(bmain->relations->relations_from_pointers, id_iter));
|
||||
for (MainIDRelationsEntryItem *item = entry->from_ids; item; item = item->next) {
|
||||
if (!ID_IS_LINKED(item->id_pointer.from)) {
|
||||
directly_used_libs.add(id_iter->lib);
|
||||
id_iter->lib->parent = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
FOREACH_MAIN_ID_END;
|
||||
|
||||
LISTBASE_FOREACH (Library *, lib_iter, &bmain->libraries) {
|
||||
/* A directly used library. */
|
||||
if (directly_used_libs.contains(lib_iter)) {
|
||||
BLI_assert(lib_iter->temp_index == 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Assume existing parent is still valid, since it was not cleared in previous loop above.
|
||||
* Just compute 'hierarchy value' in temp index, if needed. */
|
||||
if (lib_iter->parent) {
|
||||
if (lib_iter->temp_index > 0) {
|
||||
continue;
|
||||
}
|
||||
blender::Vector<Library *> parent_libraries;
|
||||
for (Library *parent_lib_iter = lib_iter;
|
||||
parent_lib_iter && parent_lib_iter->temp_index == 0;
|
||||
parent_lib_iter = parent_lib_iter->parent)
|
||||
{
|
||||
parent_libraries.append(parent_lib_iter);
|
||||
}
|
||||
int parent_temp_index = parent_libraries.last()->temp_index + int(parent_libraries.size()) -
|
||||
1;
|
||||
for (Library *parent_lib_iter : parent_libraries) {
|
||||
BLI_assert(parent_lib_iter != parent_libraries.last() ||
|
||||
parent_lib_iter->temp_index == parent_temp_index);
|
||||
parent_lib_iter->temp_index = parent_temp_index--;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Otherwise, it's an indirectly used library with no known parent, another loop is needed to
|
||||
* ansure all knwon hierarcy has valid indices when trying to find the best valid parent
|
||||
* library. */
|
||||
}
|
||||
|
||||
/* For all libraries known to be indirect, but without a known parent, find a best valid parent
|
||||
* (i.e. a 'most directly used' library). */
|
||||
LISTBASE_FOREACH (Library *, lib_iter, &bmain->libraries) {
|
||||
/* A directly used library. */
|
||||
if (directly_used_libs.contains(lib_iter)) {
|
||||
BLI_assert(lib_iter->temp_index == 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lib_iter->parent) {
|
||||
BLI_assert(lib_iter->temp_index > 0);
|
||||
}
|
||||
else {
|
||||
BLI_assert(lib_iter->temp_index == 0);
|
||||
rebuild_hierarchy_best_parent_find(bmain, directly_used_libs, lib_iter);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_main_relations_free(bmain);
|
||||
}
|
||||
|
|
|
@ -97,6 +97,8 @@
|
|||
#include "UI_string_search.hh"
|
||||
#include "interface_intern.hh"
|
||||
|
||||
using blender::Vector;
|
||||
|
||||
/* we may want to make this optional, disable for now. */
|
||||
// #define USE_OP_RESET_BUT
|
||||
|
||||
|
@ -1659,11 +1661,7 @@ static void template_ID_tabs(const bContext *C,
|
|||
uiBlock *block = uiLayoutGetBlock(layout);
|
||||
const uiStyle *style = UI_style_get_dpi();
|
||||
|
||||
ListBase ordered;
|
||||
BKE_id_ordered_list(&ordered, template_id->idlb);
|
||||
|
||||
LISTBASE_FOREACH (LinkData *, link, &ordered) {
|
||||
ID *id = static_cast<ID *>(link->data);
|
||||
for (ID *id : BKE_id_ordered_list(template_id->idlb)) {
|
||||
const int name_width = UI_fontstyle_string_width(&style->widget, id->name + 2);
|
||||
const int but_width = name_width + UI_UNIT_X;
|
||||
|
||||
|
@ -1689,8 +1687,6 @@ static void template_ID_tabs(const bContext *C,
|
|||
UI_but_drawflag_enable(tab, but_align);
|
||||
}
|
||||
|
||||
BLI_freelistN(&ordered);
|
||||
|
||||
if (flag & UI_ID_ADD_NEW) {
|
||||
const bool editable = RNA_property_editable(&template_id->ptr, template_id->prop);
|
||||
uiBut *but;
|
||||
|
@ -3378,14 +3374,18 @@ struct RNAUpdateCb {
|
|||
PropertyRNA *prop;
|
||||
};
|
||||
|
||||
static void rna_update_cb(bContext *C, void *arg_cb, void * /*arg*/)
|
||||
static void rna_update_cb(bContext &C, const RNAUpdateCb &cb)
|
||||
{
|
||||
RNAUpdateCb *cb = (RNAUpdateCb *)arg_cb;
|
||||
|
||||
/* we call update here on the pointer property, this way the
|
||||
* owner of the curve mapping can still define its own update
|
||||
* and notifier, even if the CurveMapping struct is shared. */
|
||||
RNA_property_update(C, &cb->ptr, cb->prop);
|
||||
RNA_property_update(&C, &const_cast<PointerRNA &>(cb.ptr), cb.prop);
|
||||
}
|
||||
|
||||
static void rna_update_cb(bContext *C, void *arg_cb, void * /*arg*/)
|
||||
{
|
||||
RNAUpdateCb *cb = (RNAUpdateCb *)arg_cb;
|
||||
rna_update_cb(*C, *cb);
|
||||
}
|
||||
|
||||
enum {
|
||||
|
@ -3553,33 +3553,22 @@ static uiBlock *colorband_tools_func(bContext *C, ARegion *region, void *arg_cb)
|
|||
return block;
|
||||
}
|
||||
|
||||
static void colorband_add_cb(bContext *C, void *cb_v, void *coba_v)
|
||||
static void colorband_add(bContext &C, const RNAUpdateCb &cb, ColorBand &coba)
|
||||
{
|
||||
ColorBand *coba = static_cast<ColorBand *>(coba_v);
|
||||
float pos = 0.5f;
|
||||
|
||||
if (coba->tot > 1) {
|
||||
if (coba->cur > 0) {
|
||||
pos = (coba->data[coba->cur - 1].pos + coba->data[coba->cur].pos) * 0.5f;
|
||||
if (coba.tot > 1) {
|
||||
if (coba.cur > 0) {
|
||||
pos = (coba.data[coba.cur - 1].pos + coba.data[coba.cur].pos) * 0.5f;
|
||||
}
|
||||
else {
|
||||
pos = (coba->data[coba->cur + 1].pos + coba->data[coba->cur].pos) * 0.5f;
|
||||
pos = (coba.data[coba.cur + 1].pos + coba.data[coba.cur].pos) * 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
if (BKE_colorband_element_add(coba, pos)) {
|
||||
rna_update_cb(C, cb_v, nullptr);
|
||||
ED_undo_push(C, "Add Color Ramp Stop");
|
||||
}
|
||||
}
|
||||
|
||||
static void colorband_del_cb(bContext *C, void *cb_v, void *coba_v)
|
||||
{
|
||||
ColorBand *coba = static_cast<ColorBand *>(coba_v);
|
||||
|
||||
if (BKE_colorband_element_remove(coba, coba->cur)) {
|
||||
ED_undo_push(C, "Delete Color Ramp Stop");
|
||||
rna_update_cb(C, cb_v, nullptr);
|
||||
if (BKE_colorband_element_add(&coba, pos)) {
|
||||
rna_update_cb(C, cb);
|
||||
ED_undo_push(&C, "Add Color Ramp Stop");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3598,7 +3587,7 @@ static void colorband_buttons_layout(uiLayout *layout,
|
|||
uiBlock *block,
|
||||
ColorBand *coba,
|
||||
const rctf *butr,
|
||||
RNAUpdateCb *cb,
|
||||
const RNAUpdateCb &cb,
|
||||
int expand)
|
||||
{
|
||||
uiBut *bt;
|
||||
|
@ -3606,7 +3595,7 @@ static void colorband_buttons_layout(uiLayout *layout,
|
|||
const float xs = butr->xmin;
|
||||
const float ys = butr->ymin;
|
||||
|
||||
PointerRNA ptr = RNA_pointer_create(cb->ptr.owner_id, &RNA_ColorRamp, coba);
|
||||
PointerRNA ptr = RNA_pointer_create(cb.ptr.owner_id, &RNA_ColorRamp, coba);
|
||||
|
||||
uiLayout *split = uiLayoutSplit(layout, 0.4f, false);
|
||||
|
||||
|
@ -3629,7 +3618,7 @@ static void colorband_buttons_layout(uiLayout *layout,
|
|||
0,
|
||||
0,
|
||||
TIP_("Add a new color stop to the color ramp"));
|
||||
UI_but_funcN_set(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
|
||||
UI_but_func_set(bt, [coba, cb](bContext &C) { colorband_add(C, cb, *coba); });
|
||||
|
||||
bt = uiDefIconTextBut(block,
|
||||
UI_BTYPE_BUT,
|
||||
|
@ -3646,9 +3635,14 @@ static void colorband_buttons_layout(uiLayout *layout,
|
|||
0,
|
||||
0,
|
||||
TIP_("Delete the active position"));
|
||||
UI_but_funcN_set(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
|
||||
UI_but_func_set(bt, [coba, cb](bContext &C) {
|
||||
if (BKE_colorband_element_remove(coba, coba->cur)) {
|
||||
rna_update_cb(C, cb);
|
||||
ED_undo_push(&C, "Delete Color Ramp Stop");
|
||||
}
|
||||
});
|
||||
|
||||
RNAUpdateCb *tools_cb = static_cast<RNAUpdateCb *>(MEM_dupallocN(cb));
|
||||
RNAUpdateCb *tools_cb = MEM_new<RNAUpdateCb>(__func__, cb);
|
||||
bt = uiDefIconBlockBut(block,
|
||||
colorband_tools_func,
|
||||
tools_cb,
|
||||
|
@ -3692,14 +3686,14 @@ static void colorband_buttons_layout(uiLayout *layout,
|
|||
0,
|
||||
0,
|
||||
"");
|
||||
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), nullptr);
|
||||
UI_but_func_set(bt, [cb](bContext &C) { rna_update_cb(C, cb); });
|
||||
|
||||
row = uiLayoutRow(layout, false);
|
||||
|
||||
if (coba->tot) {
|
||||
CBData *cbd = coba->data + coba->cur;
|
||||
|
||||
ptr = RNA_pointer_create(cb->ptr.owner_id, &RNA_ColorRampElement, cbd);
|
||||
ptr = RNA_pointer_create(cb.ptr.owner_id, &RNA_ColorRampElement, cbd);
|
||||
|
||||
if (!expand) {
|
||||
split = uiLayoutSplit(layout, 0.3f, false);
|
||||
|
@ -3770,7 +3764,7 @@ static void colorband_buttons_layout(uiLayout *layout,
|
|||
}
|
||||
|
||||
if (STREQ(prop_identifier, "color")) {
|
||||
UI_but_funcN_set(but, rna_update_cb, MEM_dupallocN(cb), nullptr);
|
||||
UI_but_func_set(bt, [cb](bContext &C) { rna_update_cb(C, cb); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3789,10 +3783,6 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname
|
|||
return;
|
||||
}
|
||||
|
||||
RNAUpdateCb *cb = MEM_cnew<RNAUpdateCb>("RNAUpdateCb");
|
||||
cb->ptr = *ptr;
|
||||
cb->prop = prop;
|
||||
|
||||
rctf rect;
|
||||
rect.xmin = 0;
|
||||
rect.xmax = 10.0f * UI_UNIT_X;
|
||||
|
@ -3804,11 +3794,10 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname
|
|||
ID *id = cptr.owner_id;
|
||||
UI_block_lock_set(block, (id && ID_IS_LINKED(id)), ERROR_LIBDATA_MESSAGE);
|
||||
|
||||
colorband_buttons_layout(layout, block, static_cast<ColorBand *>(cptr.data), &rect, cb, expand);
|
||||
colorband_buttons_layout(
|
||||
layout, block, static_cast<ColorBand *>(cptr.data), &rect, RNAUpdateCb{*ptr, prop}, expand);
|
||||
|
||||
UI_block_lock_clear(block);
|
||||
|
||||
MEM_freeN(cb);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -4169,10 +4158,8 @@ static bool curvemap_can_zoom_in(CurveMapping *cumap)
|
|||
return BLI_rctf_size_x(&cumap->curr) > CURVE_ZOOM_MAX * BLI_rctf_size_x(&cumap->clipr);
|
||||
}
|
||||
|
||||
static void curvemap_buttons_zoom_in(bContext *C, void *cumap_v, void * /*arg*/)
|
||||
static void curvemap_buttons_zoom_in(bContext *C, CurveMapping *cumap)
|
||||
{
|
||||
CurveMapping *cumap = static_cast<CurveMapping *>(cumap_v);
|
||||
|
||||
if (curvemap_can_zoom_in(cumap)) {
|
||||
const float dx = 0.1154f * BLI_rctf_size_x(&cumap->curr);
|
||||
cumap->curr.xmin += dx;
|
||||
|
@ -4185,9 +4172,8 @@ static void curvemap_buttons_zoom_in(bContext *C, void *cumap_v, void * /*arg*/)
|
|||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
}
|
||||
|
||||
static void curvemap_buttons_zoom_out(bContext *C, void *cumap_v, void * /*unused*/)
|
||||
static void curvemap_buttons_zoom_out(bContext *C, CurveMapping *cumap)
|
||||
{
|
||||
CurveMapping *cumap = static_cast<CurveMapping *>(cumap_v);
|
||||
float d, d1;
|
||||
|
||||
if (curvemap_can_zoom_out(cumap)) {
|
||||
|
@ -4229,23 +4215,6 @@ static void curvemap_buttons_zoom_out(bContext *C, void *cumap_v, void * /*unuse
|
|||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
}
|
||||
|
||||
static void curvemap_buttons_setclip(bContext * /*C*/, void *cumap_v, void * /*arg*/)
|
||||
{
|
||||
CurveMapping *cumap = static_cast<CurveMapping *>(cumap_v);
|
||||
|
||||
BKE_curvemapping_changed(cumap, false);
|
||||
}
|
||||
|
||||
static void curvemap_buttons_delete(bContext *C, void *cb_v, void *cumap_v)
|
||||
{
|
||||
CurveMapping *cumap = static_cast<CurveMapping *>(cumap_v);
|
||||
|
||||
BKE_curvemap_remove(cumap->cm + cumap->cur, SELECT);
|
||||
BKE_curvemapping_changed(cumap, false);
|
||||
|
||||
rna_update_cb(C, cb_v, nullptr);
|
||||
}
|
||||
|
||||
/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
|
||||
static uiBlock *curvemap_clipping_func(bContext *C, ARegion *region, void *cumap_v)
|
||||
{
|
||||
|
@ -4270,7 +4239,7 @@ static uiBlock *curvemap_clipping_func(bContext *C, ARegion *region, void *cumap
|
|||
0.0,
|
||||
0.0,
|
||||
"");
|
||||
UI_but_func_set(bt, curvemap_buttons_setclip, cumap, nullptr);
|
||||
UI_but_func_set(bt, [cumap](bContext & /*C*/) { BKE_curvemapping_changed(cumap, false); });
|
||||
|
||||
UI_block_align_begin(block);
|
||||
bt = uiDefButF(block,
|
||||
|
@ -4514,33 +4483,9 @@ static void curvemap_tools_handle_auto_clamped(bContext *C, void *cumap_v, void
|
|||
curvemap_tools_dofunc(C, cumap_v, UICURVE_FUNC_HANDLE_AUTO_ANIM);
|
||||
}
|
||||
|
||||
static void curvemap_buttons_redraw(bContext *C, void * /*arg1*/, void * /*arg2*/)
|
||||
static void curvemap_buttons_redraw(bContext &C)
|
||||
{
|
||||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
}
|
||||
|
||||
static void curvemap_buttons_update(bContext *C, void *arg1_v, void *cumap_v)
|
||||
{
|
||||
CurveMapping *cumap = static_cast<CurveMapping *>(cumap_v);
|
||||
BKE_curvemapping_changed(cumap, true);
|
||||
rna_update_cb(C, arg1_v, nullptr);
|
||||
}
|
||||
|
||||
static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v)
|
||||
{
|
||||
CurveMapping *cumap = static_cast<CurveMapping *>(cumap_v);
|
||||
cumap->preset = CURVE_PRESET_LINE;
|
||||
for (int a = 0; a < CM_TOT; a++) {
|
||||
BKE_curvemap_reset(cumap->cm + a, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
|
||||
}
|
||||
|
||||
cumap->black[0] = cumap->black[1] = cumap->black[2] = 0.0f;
|
||||
cumap->white[0] = cumap->white[1] = cumap->white[2] = 1.0f;
|
||||
BKE_curvemapping_set_black_white(cumap, nullptr, nullptr);
|
||||
|
||||
BKE_curvemapping_changed(cumap, false);
|
||||
|
||||
rna_update_cb(C, cb_v, nullptr);
|
||||
ED_region_tag_redraw(CTX_wm_region(&C));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4555,7 +4500,7 @@ static void curvemap_buttons_layout(uiLayout *layout,
|
|||
bool brush,
|
||||
bool neg_slope,
|
||||
bool tone,
|
||||
RNAUpdateCb *cb)
|
||||
const RNAUpdateCb &cb)
|
||||
{
|
||||
CurveMapping *cumap = static_cast<CurveMapping *>(ptr->data);
|
||||
CurveMap *cm = &cumap->cm[cumap->cur];
|
||||
|
@ -4583,17 +4528,17 @@ static void curvemap_buttons_layout(uiLayout *layout,
|
|||
if (cumap->cm[0].curve) {
|
||||
bt = uiDefButI(
|
||||
block, UI_BTYPE_ROW, 0, "X", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw, nullptr, nullptr);
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw);
|
||||
}
|
||||
if (cumap->cm[1].curve) {
|
||||
bt = uiDefButI(
|
||||
block, UI_BTYPE_ROW, 0, "Y", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw, nullptr, nullptr);
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw);
|
||||
}
|
||||
if (cumap->cm[2].curve) {
|
||||
bt = uiDefButI(
|
||||
block, UI_BTYPE_ROW, 0, "Z", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw, nullptr, nullptr);
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw);
|
||||
}
|
||||
}
|
||||
else if (labeltype == 'c') {
|
||||
|
@ -4616,22 +4561,22 @@ static void curvemap_buttons_layout(uiLayout *layout,
|
|||
0.0,
|
||||
0.0,
|
||||
"");
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw, nullptr, nullptr);
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw);
|
||||
}
|
||||
if (cumap->cm[0].curve) {
|
||||
bt = uiDefButI(
|
||||
block, UI_BTYPE_ROW, 0, IFACE_("R"), 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw, nullptr, nullptr);
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw);
|
||||
}
|
||||
if (cumap->cm[1].curve) {
|
||||
bt = uiDefButI(
|
||||
block, UI_BTYPE_ROW, 0, IFACE_("G"), 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw, nullptr, nullptr);
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw);
|
||||
}
|
||||
if (cumap->cm[2].curve) {
|
||||
bt = uiDefButI(
|
||||
block, UI_BTYPE_ROW, 0, IFACE_("B"), 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw, nullptr, nullptr);
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw);
|
||||
}
|
||||
}
|
||||
else if (labeltype == 'h') {
|
||||
|
@ -4642,17 +4587,17 @@ static void curvemap_buttons_layout(uiLayout *layout,
|
|||
if (cumap->cm[0].curve) {
|
||||
bt = uiDefButI(
|
||||
block, UI_BTYPE_ROW, 0, IFACE_("H"), 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw, nullptr, nullptr);
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw);
|
||||
}
|
||||
if (cumap->cm[1].curve) {
|
||||
bt = uiDefButI(
|
||||
block, UI_BTYPE_ROW, 0, IFACE_("S"), 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw, nullptr, nullptr);
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw);
|
||||
}
|
||||
if (cumap->cm[2].curve) {
|
||||
bt = uiDefButI(
|
||||
block, UI_BTYPE_ROW, 0, IFACE_("V"), 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw, nullptr, nullptr);
|
||||
UI_but_func_set(bt, curvemap_buttons_redraw);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -4683,7 +4628,7 @@ static void curvemap_buttons_layout(uiLayout *layout,
|
|||
0.0,
|
||||
0.0,
|
||||
TIP_("Zoom in"));
|
||||
UI_but_func_set(bt, curvemap_buttons_zoom_in, cumap, nullptr);
|
||||
UI_but_func_set(bt, [cumap](bContext &C) { curvemap_buttons_zoom_in(&C, cumap); });
|
||||
if (!curvemap_can_zoom_in(cumap)) {
|
||||
UI_but_disable(bt, "");
|
||||
}
|
||||
|
@ -4703,7 +4648,7 @@ static void curvemap_buttons_layout(uiLayout *layout,
|
|||
0.0,
|
||||
0.0,
|
||||
TIP_("Zoom out"));
|
||||
UI_but_func_set(bt, curvemap_buttons_zoom_out, cumap, nullptr);
|
||||
UI_but_func_set(bt, [cumap](bContext &C) { curvemap_buttons_zoom_out(&C, cumap); });
|
||||
if (!curvemap_can_zoom_out(cumap)) {
|
||||
UI_but_disable(bt, "");
|
||||
}
|
||||
|
@ -4713,7 +4658,7 @@ static void curvemap_buttons_layout(uiLayout *layout,
|
|||
bt = uiDefIconBlockBut(
|
||||
block, curvemap_clipping_func, cumap, 0, icon, 0, 0, dx, dx, TIP_("Clipping Options"));
|
||||
bt->drawflag &= ~UI_BUT_ICON_LEFT;
|
||||
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), nullptr);
|
||||
UI_but_func_set(bt, [cb](bContext &C) { rna_update_cb(C, cb); });
|
||||
|
||||
if (brush && neg_slope) {
|
||||
bt = uiDefIconBlockBut(block,
|
||||
|
@ -4739,9 +4684,9 @@ static void curvemap_buttons_layout(uiLayout *layout,
|
|||
bt = uiDefIconBlockBut(
|
||||
block, curvemap_tools_posslope_func, cumap, 0, ICON_NONE, 0, 0, dx, dx, TIP_("Tools"));
|
||||
}
|
||||
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), nullptr);
|
||||
UI_but_func_set(bt, [cb](bContext &C) { rna_update_cb(C, cb); });
|
||||
|
||||
UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), nullptr);
|
||||
UI_block_funcN_set(block, rna_update_cb, MEM_new<RNAUpdateCb>(__func__, cb), nullptr);
|
||||
|
||||
/* Curve itself. */
|
||||
const int size = max_ii(uiLayoutGetWidth(layout), UI_UNIT_X);
|
||||
|
@ -4839,7 +4784,10 @@ static void curvemap_buttons_layout(uiLayout *layout,
|
|||
}
|
||||
|
||||
/* Curve handle position */
|
||||
UI_block_funcN_set(block, curvemap_buttons_update, MEM_dupallocN(cb), cumap);
|
||||
UI_but_func_set(bt, [cumap, cb](bContext &C) {
|
||||
BKE_curvemapping_changed(cumap, true);
|
||||
rna_update_cb(C, cb);
|
||||
});
|
||||
bt = uiDefButF(block,
|
||||
UI_BTYPE_NUM,
|
||||
0,
|
||||
|
@ -4884,7 +4832,11 @@ static void curvemap_buttons_layout(uiLayout *layout,
|
|||
0.0,
|
||||
0.0,
|
||||
TIP_("Delete points"));
|
||||
UI_but_funcN_set(bt, curvemap_buttons_delete, MEM_dupallocN(cb), cumap);
|
||||
UI_but_func_set(bt, [cumap, cb](bContext &C) {
|
||||
BKE_curvemap_remove(cumap->cm + cumap->cur, SELECT);
|
||||
BKE_curvemapping_changed(cumap, false);
|
||||
rna_update_cb(C, cb);
|
||||
});
|
||||
if (point_last_or_first) {
|
||||
UI_but_flag_enable(bt, UI_BUT_DISABLED);
|
||||
}
|
||||
|
@ -4913,7 +4865,19 @@ static void curvemap_buttons_layout(uiLayout *layout,
|
|||
0,
|
||||
0,
|
||||
TIP_("Reset Black/White point and curves"));
|
||||
UI_but_funcN_set(bt, curvemap_buttons_reset, MEM_dupallocN(cb), cumap);
|
||||
UI_but_func_set(bt, [cumap, cb](bContext &C) {
|
||||
cumap->preset = CURVE_PRESET_LINE;
|
||||
for (int a = 0; a < CM_TOT; a++) {
|
||||
BKE_curvemap_reset(cumap->cm + a, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
|
||||
}
|
||||
|
||||
cumap->black[0] = cumap->black[1] = cumap->black[2] = 0.0f;
|
||||
cumap->white[0] = cumap->white[1] = cumap->white[2] = 1.0f;
|
||||
BKE_curvemapping_set_black_white(cumap, nullptr, nullptr);
|
||||
|
||||
BKE_curvemapping_changed(cumap, false);
|
||||
rna_update_cb(C, cb);
|
||||
});
|
||||
}
|
||||
|
||||
UI_block_funcN_set(block, nullptr, nullptr, nullptr);
|
||||
|
@ -4946,18 +4910,13 @@ void uiTemplateCurveMapping(uiLayout *layout,
|
|||
return;
|
||||
}
|
||||
|
||||
RNAUpdateCb *cb = MEM_cnew<RNAUpdateCb>("RNAUpdateCb");
|
||||
cb->ptr = *ptr;
|
||||
cb->prop = prop;
|
||||
|
||||
ID *id = cptr.owner_id;
|
||||
UI_block_lock_set(block, (id && ID_IS_LINKED(id)), ERROR_LIBDATA_MESSAGE);
|
||||
|
||||
curvemap_buttons_layout(layout, &cptr, type, levels, brush, neg_slope, tone, cb);
|
||||
curvemap_buttons_layout(
|
||||
layout, &cptr, type, levels, brush, neg_slope, tone, RNAUpdateCb{*ptr, prop});
|
||||
|
||||
UI_block_lock_clear(block);
|
||||
|
||||
MEM_freeN(cb);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -5155,10 +5114,8 @@ static bool CurveProfile_can_zoom_out(CurveProfile *profile)
|
|||
return BLI_rctf_size_x(&profile->view_rect) < BLI_rctf_size_x(&profile->clip_rect);
|
||||
}
|
||||
|
||||
static void CurveProfile_buttons_zoom_in(bContext *C, void *profile_v, void * /*arg*/)
|
||||
static void CurveProfile_buttons_zoom_in(bContext *C, CurveProfile *profile)
|
||||
{
|
||||
CurveProfile *profile = static_cast<CurveProfile *>(profile_v);
|
||||
|
||||
if (CurveProfile_can_zoom_in(profile)) {
|
||||
const float dx = 0.1154f * BLI_rctf_size_x(&profile->view_rect);
|
||||
profile->view_rect.xmin += dx;
|
||||
|
@ -5171,10 +5128,8 @@ static void CurveProfile_buttons_zoom_in(bContext *C, void *profile_v, void * /*
|
|||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
}
|
||||
|
||||
static void CurveProfile_buttons_zoom_out(bContext *C, void *profile_v, void * /*arg*/)
|
||||
static void CurveProfile_buttons_zoom_out(bContext *C, CurveProfile *profile)
|
||||
{
|
||||
CurveProfile *profile = static_cast<CurveProfile *>(profile_v);
|
||||
|
||||
if (CurveProfile_can_zoom_out(profile)) {
|
||||
float d = 0.15f * BLI_rctf_size_x(&profile->view_rect);
|
||||
float d1 = d;
|
||||
|
@ -5215,51 +5170,7 @@ static void CurveProfile_buttons_zoom_out(bContext *C, void *profile_v, void * /
|
|||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
}
|
||||
|
||||
static void CurveProfile_clipping_toggle(bContext *C, void *cb_v, void *profile_v)
|
||||
{
|
||||
CurveProfile *profile = static_cast<CurveProfile *>(profile_v);
|
||||
|
||||
profile->flag ^= PROF_USE_CLIP;
|
||||
|
||||
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
||||
rna_update_cb(C, cb_v, nullptr);
|
||||
}
|
||||
|
||||
static void CurveProfile_buttons_reverse(bContext *C, void *cb_v, void *profile_v)
|
||||
{
|
||||
CurveProfile *profile = static_cast<CurveProfile *>(profile_v);
|
||||
|
||||
BKE_curveprofile_reverse(profile);
|
||||
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
||||
rna_update_cb(C, cb_v, nullptr);
|
||||
}
|
||||
|
||||
static void CurveProfile_buttons_delete(bContext *C, void *cb_v, void *profile_v)
|
||||
{
|
||||
CurveProfile *profile = static_cast<CurveProfile *>(profile_v);
|
||||
|
||||
BKE_curveprofile_remove_by_flag(profile, SELECT);
|
||||
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
||||
|
||||
rna_update_cb(C, cb_v, nullptr);
|
||||
}
|
||||
|
||||
static void CurveProfile_buttons_update(bContext *C, void *arg1_v, void *profile_v)
|
||||
{
|
||||
CurveProfile *profile = static_cast<CurveProfile *>(profile_v);
|
||||
BKE_curveprofile_update(profile, PROF_UPDATE_REMOVE_DOUBLES | PROF_UPDATE_CLIP);
|
||||
rna_update_cb(C, arg1_v, nullptr);
|
||||
}
|
||||
|
||||
static void CurveProfile_buttons_reset(bContext *C, void *arg1_v, void *profile_v)
|
||||
{
|
||||
CurveProfile *profile = static_cast<CurveProfile *>(profile_v);
|
||||
BKE_curveprofile_reset(profile);
|
||||
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
||||
rna_update_cb(C, arg1_v, nullptr);
|
||||
}
|
||||
|
||||
static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUpdateCb *cb)
|
||||
static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, const RNAUpdateCb &cb)
|
||||
{
|
||||
CurveProfile *profile = static_cast<CurveProfile *>(ptr->data);
|
||||
uiBut *bt;
|
||||
|
@ -5283,7 +5194,7 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
|
|||
UI_UNIT_X,
|
||||
UI_UNIT_X,
|
||||
"");
|
||||
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), nullptr);
|
||||
UI_but_func_set(bt, [cb](bContext &C) { rna_update_cb(C, cb); });
|
||||
|
||||
/* Show a "re-apply" preset button when it has been changed from the preset. */
|
||||
if (profile->flag & PROF_DIRTY_PRESET) {
|
||||
|
@ -5304,7 +5215,11 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
|
|||
0.0,
|
||||
0.0,
|
||||
TIP_("Reapply and update the preset, removing changes"));
|
||||
UI_but_funcN_set(bt, CurveProfile_buttons_reset, MEM_dupallocN(cb), profile);
|
||||
UI_but_func_set(bt, [profile, cb](bContext &C) {
|
||||
BKE_curveprofile_reset(profile);
|
||||
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
||||
rna_update_cb(C, cb);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5329,7 +5244,7 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
|
|||
0.0,
|
||||
0.0,
|
||||
TIP_("Zoom in"));
|
||||
UI_but_func_set(bt, CurveProfile_buttons_zoom_in, profile, nullptr);
|
||||
UI_but_func_set(bt, [profile](bContext &C) { CurveProfile_buttons_zoom_in(&C, profile); });
|
||||
if (!CurveProfile_can_zoom_in(profile)) {
|
||||
UI_but_disable(bt, "");
|
||||
}
|
||||
|
@ -5349,7 +5264,7 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
|
|||
0.0,
|
||||
0.0,
|
||||
TIP_("Zoom out"));
|
||||
UI_but_func_set(bt, CurveProfile_buttons_zoom_out, profile, nullptr);
|
||||
UI_but_func_set(bt, [profile](bContext &C) { CurveProfile_buttons_zoom_out(&C, profile); });
|
||||
if (!CurveProfile_can_zoom_out(profile)) {
|
||||
UI_but_disable(bt, "");
|
||||
}
|
||||
|
@ -5373,7 +5288,11 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
|
|||
0.0,
|
||||
0.0,
|
||||
TIP_("Reverse Path"));
|
||||
UI_but_funcN_set(bt, CurveProfile_buttons_reverse, MEM_dupallocN(cb), profile);
|
||||
UI_but_func_set(bt, [profile, cb](bContext &C) {
|
||||
BKE_curveprofile_reverse(profile);
|
||||
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
||||
rna_update_cb(C, cb);
|
||||
});
|
||||
|
||||
/* Clipping toggle */
|
||||
const int icon = (profile->flag & PROF_USE_CLIP) ? ICON_CLIPUV_HLT : ICON_CLIPUV_DEHLT;
|
||||
|
@ -5391,7 +5310,11 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
|
|||
0.0,
|
||||
0.0,
|
||||
TIP_("Toggle Profile Clipping"));
|
||||
UI_but_funcN_set(bt, CurveProfile_clipping_toggle, MEM_dupallocN(cb), profile);
|
||||
UI_but_func_set(bt, [profile, cb](bContext &C) {
|
||||
profile->flag ^= PROF_USE_CLIP;
|
||||
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
||||
rna_update_cb(C, cb);
|
||||
});
|
||||
|
||||
/* Reset view, reset curve */
|
||||
bt = uiDefIconBlockBut(block,
|
||||
|
@ -5404,9 +5327,9 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
|
|||
UI_UNIT_X,
|
||||
UI_UNIT_X,
|
||||
TIP_("Tools"));
|
||||
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), nullptr);
|
||||
UI_but_func_set(bt, [cb](bContext &C) { rna_update_cb(C, cb); });
|
||||
|
||||
UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), nullptr);
|
||||
UI_block_funcN_set(block, rna_update_cb, MEM_new<RNAUpdateCb>(__func__, cb), nullptr);
|
||||
|
||||
/* The path itself */
|
||||
int path_width = max_ii(uiLayoutGetWidth(layout), UI_UNIT_X);
|
||||
|
@ -5494,7 +5417,10 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
|
|||
"");
|
||||
UI_but_number_step_size_set(bt, 1);
|
||||
UI_but_number_precision_set(bt, 5);
|
||||
UI_but_funcN_set(bt, CurveProfile_buttons_update, MEM_dupallocN(cb), profile);
|
||||
UI_but_func_set(bt, [profile, cb](bContext &C) {
|
||||
BKE_curveprofile_update(profile, PROF_UPDATE_REMOVE_DOUBLES | PROF_UPDATE_CLIP);
|
||||
rna_update_cb(C, cb);
|
||||
});
|
||||
if (point_last_or_first) {
|
||||
UI_but_flag_enable(bt, UI_BUT_DISABLED);
|
||||
}
|
||||
|
@ -5512,7 +5438,10 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
|
|||
"");
|
||||
UI_but_number_step_size_set(bt, 1);
|
||||
UI_but_number_precision_set(bt, 5);
|
||||
UI_but_funcN_set(bt, CurveProfile_buttons_update, MEM_dupallocN(cb), profile);
|
||||
UI_but_func_set(bt, [profile, cb](bContext &C) {
|
||||
BKE_curveprofile_update(profile, PROF_UPDATE_REMOVE_DOUBLES | PROF_UPDATE_CLIP);
|
||||
rna_update_cb(C, cb);
|
||||
});
|
||||
if (point_last_or_first) {
|
||||
UI_but_flag_enable(bt, UI_BUT_DISABLED);
|
||||
}
|
||||
|
@ -5532,7 +5461,11 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
|
|||
0.0,
|
||||
0.0,
|
||||
TIP_("Delete points"));
|
||||
UI_but_funcN_set(bt, CurveProfile_buttons_delete, MEM_dupallocN(cb), profile);
|
||||
UI_but_func_set(bt, [profile, cb](bContext &C) {
|
||||
BKE_curveprofile_remove_by_flag(profile, SELECT);
|
||||
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
||||
rna_update_cb(C, cb);
|
||||
});
|
||||
if (point_last_or_first) {
|
||||
UI_but_flag_enable(bt, UI_BUT_DISABLED);
|
||||
}
|
||||
|
@ -5567,19 +5500,12 @@ void uiTemplateCurveProfile(uiLayout *layout, PointerRNA *ptr, const char *propn
|
|||
return;
|
||||
}
|
||||
|
||||
/* Share update functionality with the CurveMapping widget template. */
|
||||
RNAUpdateCb *cb = MEM_cnew<RNAUpdateCb>("RNAUpdateCb");
|
||||
cb->ptr = *ptr;
|
||||
cb->prop = prop;
|
||||
|
||||
ID *id = cptr.owner_id;
|
||||
UI_block_lock_set(block, (id && ID_IS_LINKED(id)), ERROR_LIBDATA_MESSAGE);
|
||||
|
||||
CurveProfile_buttons_layout(layout, &cptr, cb);
|
||||
CurveProfile_buttons_layout(layout, &cptr, RNAUpdateCb{*ptr, prop});
|
||||
|
||||
UI_block_lock_clear(block);
|
||||
|
||||
MEM_freeN(cb);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -76,6 +76,8 @@
|
|||
|
||||
#include "screen_intern.h" /* own module include */
|
||||
|
||||
using blender::Vector;
|
||||
|
||||
#define KM_MODAL_CANCEL 1
|
||||
#define KM_MODAL_APPLY 2
|
||||
#define KM_MODAL_SNAP_ON 3
|
||||
|
@ -5788,34 +5790,26 @@ static int space_workspace_cycle_invoke(bContext *C, wmOperator *op, const wmEve
|
|||
Main *bmain = CTX_data_main(C);
|
||||
const eScreenCycle direction = eScreenCycle(RNA_enum_get(op->ptr, "direction"));
|
||||
WorkSpace *workspace_src = WM_window_get_active_workspace(win);
|
||||
WorkSpace *workspace_dst = nullptr;
|
||||
|
||||
ListBase ordered;
|
||||
BKE_id_ordered_list(&ordered, &bmain->workspaces);
|
||||
|
||||
LISTBASE_FOREACH (LinkData *, link, &ordered) {
|
||||
if (link->data == workspace_src) {
|
||||
if (direction == SPACE_CONTEXT_CYCLE_PREV) {
|
||||
workspace_dst = static_cast<WorkSpace *>((link->prev) ? link->prev->data : nullptr);
|
||||
}
|
||||
else {
|
||||
workspace_dst = static_cast<WorkSpace *>((link->next) ? link->next->data : nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (workspace_dst == nullptr) {
|
||||
LinkData *link = static_cast<LinkData *>(
|
||||
(direction == SPACE_CONTEXT_CYCLE_PREV) ? ordered.last : ordered.first);
|
||||
workspace_dst = static_cast<WorkSpace *>(link->data);
|
||||
}
|
||||
|
||||
BLI_freelistN(&ordered);
|
||||
|
||||
if (workspace_src == workspace_dst) {
|
||||
Vector<ID *> ordered = BKE_id_ordered_list(&bmain->workspaces);
|
||||
if (ordered.size() == 1) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
const int index = ordered.first_index_of(&workspace_src->id);
|
||||
|
||||
WorkSpace *workspace_dst = nullptr;
|
||||
switch (direction) {
|
||||
case SPACE_CONTEXT_CYCLE_PREV:
|
||||
workspace_dst = reinterpret_cast<WorkSpace *>(index == 0 ? ordered.last() :
|
||||
ordered[index - 1]);
|
||||
break;
|
||||
case SPACE_CONTEXT_CYCLE_NEXT:
|
||||
workspace_dst = reinterpret_cast<WorkSpace *>(
|
||||
index == ordered.index_range().last() ? ordered.first() : ordered[index + 1]);
|
||||
break;
|
||||
}
|
||||
|
||||
win->workspace_hook->temp_workspace_store = workspace_dst;
|
||||
WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, workspace_dst);
|
||||
win->workspace_hook->temp_workspace_store = nullptr;
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
|
||||
#include "screen_intern.h"
|
||||
|
||||
using blender::Vector;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Workspace API
|
||||
*
|
||||
|
@ -242,23 +244,16 @@ bool ED_workspace_delete(WorkSpace *workspace, Main *bmain, bContext *C, wmWindo
|
|||
return false;
|
||||
}
|
||||
|
||||
ListBase ordered;
|
||||
BKE_id_ordered_list(&ordered, &bmain->workspaces);
|
||||
WorkSpace *prev = nullptr, *next = nullptr;
|
||||
LISTBASE_FOREACH (LinkData *, link, &ordered) {
|
||||
if (link->data == workspace) {
|
||||
prev = static_cast<WorkSpace *>(link->prev ? link->prev->data : nullptr);
|
||||
next = static_cast<WorkSpace *>(link->next ? link->next->data : nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BLI_freelistN(&ordered);
|
||||
BLI_assert((prev != nullptr) || (next != nullptr));
|
||||
Vector<ID *> ordered = BKE_id_ordered_list(&bmain->workspaces);
|
||||
const int index = ordered.first_index_of(&workspace->id);
|
||||
|
||||
WorkSpace *new_active = reinterpret_cast<WorkSpace *>(index == 0 ? ordered[1] :
|
||||
ordered[index - 1]);
|
||||
|
||||
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
|
||||
WorkSpace *workspace_active = WM_window_get_active_workspace(win);
|
||||
if (workspace_active == workspace) {
|
||||
ED_workspace_change((prev != nullptr) ? prev : next, C, wm, win);
|
||||
ED_workspace_change(new_active, C, wm, win);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue