2011-07-30 09:24:10 +00:00
|
|
|
/*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup edinterface
|
2011-02-27 20:29:51 +00:00
|
|
|
*/
|
2009-04-03 23:30:32 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
2009-04-03 23:30:32 +00:00
|
|
|
|
|
|
|
#include "DNA_anim_types.h"
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
#include "DNA_screen_types.h"
|
|
|
|
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
#include "BLI_listbase.h"
|
2009-07-12 02:06:15 +00:00
|
|
|
#include "BLI_string.h"
|
2011-10-20 09:47:05 +00:00
|
|
|
#include "BLI_string_utf8.h"
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2009-04-03 23:30:32 +00:00
|
|
|
|
T77086 Animation: Passing Dependency Graph to Drivers
Custom driver functions need access to the dependency graph that is
triggering the evaluation of the driver. This patch passes the
dependency graph pointer through all the animation-related calls.
Instead of passing the evaluation time to functions, the code now passes
an `AnimationEvalContext` pointer:
```
typedef struct AnimationEvalContext {
struct Depsgraph *const depsgraph;
const float eval_time;
} AnimationEvalContext;
```
These structs are read-only, meaning that the code cannot change the
evaluation time. Note that the `depsgraph` pointer itself is const, but
it points to a non-const depsgraph.
FCurves and Drivers can be evaluated at a different time than the
current scene time, for example when evaluating NLA strips. This means
that, even though the current time is stored in the dependency graph, we
need an explicit evaluation time.
There are two functions that allow creation of `AnimationEvalContext`
objects:
- `BKE_animsys_eval_context_construct(Depsgraph *depsgraph, float
eval_time)`, which creates a new context object from scratch, and
- `BKE_animsys_eval_context_construct_at(AnimationEvalContext
*anim_eval_context, float eval_time)`, which can be used to create a
`AnimationEvalContext` with the same depsgraph, but at a different
time. This makes it possible to later add fields without changing any
of the code that just want to change the eval time.
This also provides a fix for T75553, although it does require a change
to the custom driver function. The driver should call
`custom_function(depsgraph)`, and the function should use that depsgraph
instead of information from `bpy.context`.
Reviewed By: brecht, sergey
Differential Revision: https://developer.blender.org/D8047
2020-07-17 17:38:09 +02:00
|
|
|
#include "BKE_animsys.h"
|
2009-04-03 23:30:32 +00:00
|
|
|
#include "BKE_context.h"
|
|
|
|
#include "BKE_fcurve.h"
|
2020-05-01 12:43:12 +02:00
|
|
|
#include "BKE_fcurve_driver.h"
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
#include "BKE_global.h"
|
2018-06-07 12:47:00 +02:00
|
|
|
#include "BKE_main.h"
|
2014-11-16 20:24:38 +13:00
|
|
|
#include "BKE_nla.h"
|
2009-04-03 23:30:32 +00:00
|
|
|
|
WIP COW Fix: Insert keyframe operators/api now queries depsgraph for evaluated data
When using copy on write, insert keyframe operators were reading from old
bmain data instead of COW data. This meant that inserting keyframes would
often read old/stale data, resulting in invalid keyframes getting created
(e.g. from last transform operation, instead of actual current state).
This commit makes it so that keyframing operators will ask depsgraph for
the evaluated copy of the data, so that it can read values from that. It
introduces a new function - `DEG_get_evaluated_rna_pointer()`, which when
working correctly/fully, should work just like the other `DEG_get_evaluated_*()`
functions, except it lets you pass in an RNA Pointer.
However, currently, this is only done for Pose Bones (as a dirty hack, since this
is an important/pivotal requirement for production) and/or datablock
properties directly (since we can just use the DEG_get_evaluated_id() directly).
on the datablock.
Committing to a branch for now as this all needs more testing. More work to come
later at a more sane time of day!
2018-05-18 20:36:48 +02:00
|
|
|
#include "DEG_depsgraph.h"
|
2017-06-08 10:14:53 +02:00
|
|
|
#include "DEG_depsgraph_build.h"
|
|
|
|
|
2009-07-08 12:30:09 +00:00
|
|
|
#include "ED_keyframing.h"
|
|
|
|
|
2009-04-03 23:30:32 +00:00
|
|
|
#include "UI_interface.h"
|
|
|
|
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
#include "RNA_access.h"
|
|
|
|
|
2009-04-03 23:30:32 +00:00
|
|
|
#include "WM_api.h"
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
|
|
#include "interface_intern.h"
|
|
|
|
|
2014-01-24 17:09:21 +13:00
|
|
|
static FCurve *ui_but_get_fcurve(
|
|
|
|
uiBut *but, AnimData **adt, bAction **action, bool *r_driven, bool *r_special)
|
2009-04-03 23:30:32 +00:00
|
|
|
{
|
2013-01-31 16:19:44 +00:00
|
|
|
/* for entire array buttons we check the first component, it's not perfect
|
|
|
|
* but works well enough in typical cases */
|
2020-08-26 10:11:13 +10:00
|
|
|
const int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex;
|
2013-01-31 16:19:44 +00:00
|
|
|
|
2020-06-05 09:30:15 +02:00
|
|
|
return BKE_fcurve_find_by_rna_context_ui(
|
2014-01-24 17:09:21 +13:00
|
|
|
but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven, r_special);
|
2009-07-12 02:06:15 +00:00
|
|
|
}
|
|
|
|
|
T77086 Animation: Passing Dependency Graph to Drivers
Custom driver functions need access to the dependency graph that is
triggering the evaluation of the driver. This patch passes the
dependency graph pointer through all the animation-related calls.
Instead of passing the evaluation time to functions, the code now passes
an `AnimationEvalContext` pointer:
```
typedef struct AnimationEvalContext {
struct Depsgraph *const depsgraph;
const float eval_time;
} AnimationEvalContext;
```
These structs are read-only, meaning that the code cannot change the
evaluation time. Note that the `depsgraph` pointer itself is const, but
it points to a non-const depsgraph.
FCurves and Drivers can be evaluated at a different time than the
current scene time, for example when evaluating NLA strips. This means
that, even though the current time is stored in the dependency graph, we
need an explicit evaluation time.
There are two functions that allow creation of `AnimationEvalContext`
objects:
- `BKE_animsys_eval_context_construct(Depsgraph *depsgraph, float
eval_time)`, which creates a new context object from scratch, and
- `BKE_animsys_eval_context_construct_at(AnimationEvalContext
*anim_eval_context, float eval_time)`, which can be used to create a
`AnimationEvalContext` with the same depsgraph, but at a different
time. This makes it possible to later add fields without changing any
of the code that just want to change the eval time.
This also provides a fix for T75553, although it does require a change
to the custom driver function. The driver should call
`custom_function(depsgraph)`, and the function should use that depsgraph
instead of information from `bpy.context`.
Reviewed By: brecht, sergey
Differential Revision: https://developer.blender.org/D8047
2020-07-17 17:38:09 +02:00
|
|
|
void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context)
|
2009-07-12 02:06:15 +00:00
|
|
|
{
|
2014-11-16 20:24:38 +13:00
|
|
|
AnimData *adt;
|
|
|
|
bAction *act;
|
2009-07-12 02:06:15 +00:00
|
|
|
FCurve *fcu;
|
2013-03-17 19:13:04 +00:00
|
|
|
bool driven;
|
2014-01-24 17:09:21 +13:00
|
|
|
bool special;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-30 01:51:25 +00:00
|
|
|
but->flag &= ~(UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN);
|
2018-12-07 03:26:20 +01:00
|
|
|
but->drawflag &= ~UI_BUT_ANIMATED_CHANGED;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-24 17:09:21 +13:00
|
|
|
/* NOTE: "special" is reserved for special F-Curves stored on the animation data
|
|
|
|
* itself (which are used to animate properties of the animation data).
|
|
|
|
* We count those as "animated" too for now
|
|
|
|
*/
|
|
|
|
fcu = ui_but_get_fcurve(but, &adt, &act, &driven, &special);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 07:09:57 +00:00
|
|
|
if (fcu) {
|
|
|
|
if (!driven) {
|
2019-05-15 22:26:58 +03:00
|
|
|
/* Empty curves are ignored by the animation evaluation system. */
|
2019-05-16 09:47:57 +03:00
|
|
|
if (BKE_fcurve_is_empty(fcu)) {
|
2019-05-15 22:26:58 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-07-12 02:06:15 +00:00
|
|
|
but->flag |= UI_BUT_ANIMATED;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-23 10:47:12 +02:00
|
|
|
/* T41525 - When the active action is a NLA strip being edited,
|
2014-11-16 20:24:38 +13:00
|
|
|
* we need to correct the frame number to "look inside" the
|
|
|
|
* remapped action
|
|
|
|
*/
|
T77086 Animation: Passing Dependency Graph to Drivers
Custom driver functions need access to the dependency graph that is
triggering the evaluation of the driver. This patch passes the
dependency graph pointer through all the animation-related calls.
Instead of passing the evaluation time to functions, the code now passes
an `AnimationEvalContext` pointer:
```
typedef struct AnimationEvalContext {
struct Depsgraph *const depsgraph;
const float eval_time;
} AnimationEvalContext;
```
These structs are read-only, meaning that the code cannot change the
evaluation time. Note that the `depsgraph` pointer itself is const, but
it points to a non-const depsgraph.
FCurves and Drivers can be evaluated at a different time than the
current scene time, for example when evaluating NLA strips. This means
that, even though the current time is stored in the dependency graph, we
need an explicit evaluation time.
There are two functions that allow creation of `AnimationEvalContext`
objects:
- `BKE_animsys_eval_context_construct(Depsgraph *depsgraph, float
eval_time)`, which creates a new context object from scratch, and
- `BKE_animsys_eval_context_construct_at(AnimationEvalContext
*anim_eval_context, float eval_time)`, which can be used to create a
`AnimationEvalContext` with the same depsgraph, but at a different
time. This makes it possible to later add fields without changing any
of the code that just want to change the eval time.
This also provides a fix for T75553, although it does require a change
to the custom driver function. The driver should call
`custom_function(depsgraph)`, and the function should use that depsgraph
instead of information from `bpy.context`.
Reviewed By: brecht, sergey
Differential Revision: https://developer.blender.org/D8047
2020-07-17 17:38:09 +02:00
|
|
|
float cfra = anim_eval_context->eval_time;
|
2019-03-25 10:15:20 +11:00
|
|
|
if (adt) {
|
2014-11-16 20:24:38 +13:00
|
|
|
cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (fcurve_frame_has_keyframe(fcu, cfra, 0)) {
|
2009-07-12 02:06:15 +00:00
|
|
|
but->flag |= UI_BUT_ANIMATED_KEY;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-08 18:49:38 +03:00
|
|
|
/* XXX: this feature is totally broken and useless with NLA */
|
|
|
|
if (adt == NULL || adt->nla_tracks.first == NULL) {
|
T77086 Animation: Passing Dependency Graph to Drivers
Custom driver functions need access to the dependency graph that is
triggering the evaluation of the driver. This patch passes the
dependency graph pointer through all the animation-related calls.
Instead of passing the evaluation time to functions, the code now passes
an `AnimationEvalContext` pointer:
```
typedef struct AnimationEvalContext {
struct Depsgraph *const depsgraph;
const float eval_time;
} AnimationEvalContext;
```
These structs are read-only, meaning that the code cannot change the
evaluation time. Note that the `depsgraph` pointer itself is const, but
it points to a non-const depsgraph.
FCurves and Drivers can be evaluated at a different time than the
current scene time, for example when evaluating NLA strips. This means
that, even though the current time is stored in the dependency graph, we
need an explicit evaluation time.
There are two functions that allow creation of `AnimationEvalContext`
objects:
- `BKE_animsys_eval_context_construct(Depsgraph *depsgraph, float
eval_time)`, which creates a new context object from scratch, and
- `BKE_animsys_eval_context_construct_at(AnimationEvalContext
*anim_eval_context, float eval_time)`, which can be used to create a
`AnimationEvalContext` with the same depsgraph, but at a different
time. This makes it possible to later add fields without changing any
of the code that just want to change the eval time.
This also provides a fix for T75553, although it does require a change
to the custom driver function. The driver should call
`custom_function(depsgraph)`, and the function should use that depsgraph
instead of information from `bpy.context`.
Reviewed By: brecht, sergey
Differential Revision: https://developer.blender.org/D8047
2020-07-17 17:38:09 +02:00
|
|
|
const AnimationEvalContext remapped_context = BKE_animsys_eval_context_construct_at(
|
|
|
|
anim_eval_context, cfra);
|
|
|
|
if (fcurve_is_changed(but->rnapoin, but->rnaprop, fcu, &remapped_context)) {
|
2019-01-08 18:49:38 +03:00
|
|
|
but->drawflag |= UI_BUT_ANIMATED_CHANGED;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-01-08 18:49:38 +03:00
|
|
|
}
|
2009-07-12 02:06:15 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
but->flag |= UI_BUT_DRIVEN;
|
|
|
|
}
|
|
|
|
}
|
2018-06-16 18:26:34 +02:00
|
|
|
}
|
2018-06-16 14:48:21 +02:00
|
|
|
|
2020-08-07 14:34:11 +02:00
|
|
|
static uiBut *ui_but_anim_decorate_find_attached_button(uiButDecorator *but_decorate)
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
{
|
|
|
|
uiBut *but_iter = NULL;
|
|
|
|
|
2020-08-07 14:34:11 +02:00
|
|
|
BLI_assert(UI_but_is_decorator(&but_decorate->but));
|
|
|
|
BLI_assert(but_decorate->rnapoin.data && but_decorate->rnaprop);
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
|
2020-08-07 14:34:11 +02:00
|
|
|
LISTBASE_CIRCULAR_BACKWARD_BEGIN (
|
|
|
|
&but_decorate->but.block->buttons, but_iter, but_decorate->but.prev) {
|
|
|
|
if (but_iter != (uiBut *)but_decorate &&
|
|
|
|
ui_but_rna_equals_ex(
|
|
|
|
but_iter, &but_decorate->rnapoin, but_decorate->rnaprop, but_decorate->rnaindex)) {
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
return but_iter;
|
|
|
|
}
|
|
|
|
}
|
2020-08-07 14:34:11 +02:00
|
|
|
LISTBASE_CIRCULAR_BACKWARD_END(
|
|
|
|
&but_decorate->but.block->buttons, but_iter, but_decorate->but.prev);
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-08-07 14:34:11 +02:00
|
|
|
void ui_but_anim_decorate_update_from_flag(uiButDecorator *decorator_but)
|
2018-06-16 18:26:34 +02:00
|
|
|
{
|
2020-08-07 14:34:11 +02:00
|
|
|
if (!decorator_but->rnapoin.data || !decorator_but->rnaprop) {
|
|
|
|
/* Nothing to do. */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const uiBut *but_anim = ui_but_anim_decorate_find_attached_button(decorator_but);
|
|
|
|
uiBut *but = &decorator_but->but;
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
|
|
|
|
if (!but_anim) {
|
2020-04-26 16:02:18 +02:00
|
|
|
printf("Could not find button with matching property to decorate (%s.%s)\n",
|
2020-08-07 14:34:11 +02:00
|
|
|
RNA_struct_identifier(decorator_but->rnapoin.type),
|
|
|
|
RNA_property_identifier(decorator_but->rnaprop));
|
2020-04-26 16:02:18 +02:00
|
|
|
return;
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
}
|
|
|
|
|
2020-08-26 10:11:13 +10:00
|
|
|
const int flag = but_anim->flag;
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
|
2018-06-16 18:26:34 +02:00
|
|
|
if (flag & UI_BUT_DRIVEN) {
|
2018-08-24 12:54:48 +02:00
|
|
|
but->icon = ICON_DECORATE_DRIVER;
|
2018-06-16 18:26:34 +02:00
|
|
|
}
|
|
|
|
else if (flag & UI_BUT_ANIMATED_KEY) {
|
2018-08-24 12:54:48 +02:00
|
|
|
but->icon = ICON_DECORATE_KEYFRAME;
|
2018-06-16 18:26:34 +02:00
|
|
|
}
|
|
|
|
else if (flag & UI_BUT_ANIMATED) {
|
2018-08-24 12:54:48 +02:00
|
|
|
but->icon = ICON_DECORATE_ANIMATE;
|
2018-06-16 18:26:34 +02:00
|
|
|
}
|
2020-12-28 10:07:36 +01:00
|
|
|
else if (flag & UI_BUT_OVERRIDDEN) {
|
2018-08-24 12:54:48 +02:00
|
|
|
but->icon = ICON_DECORATE_OVERRIDE;
|
2018-06-16 18:26:34 +02:00
|
|
|
}
|
|
|
|
else {
|
2018-08-24 12:54:48 +02:00
|
|
|
but->icon = ICON_DECORATE;
|
2018-06-16 14:48:21 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-17 12:08:33 +02:00
|
|
|
const int flag_copy = (UI_BUT_DISABLED | UI_BUT_INACTIVE);
|
|
|
|
but->flag = (but->flag & ~flag_copy) | (flag & flag_copy);
|
2009-07-12 02:06:15 +00:00
|
|
|
}
|
|
|
|
|
2016-11-18 13:37:04 +01:00
|
|
|
/**
|
|
|
|
* \a str can be NULL to only perform check if \a but has an expression at all.
|
|
|
|
* \return if button has an expression.
|
|
|
|
*/
|
2014-01-20 11:13:53 +11:00
|
|
|
bool ui_but_anim_expression_get(uiBut *but, char *str, size_t maxlen)
|
2009-07-12 02:06:15 +00:00
|
|
|
{
|
|
|
|
FCurve *fcu;
|
|
|
|
ChannelDriver *driver;
|
2014-01-24 17:09:21 +13:00
|
|
|
bool driven, special;
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2014-01-24 17:09:21 +13:00
|
|
|
fcu = ui_but_get_fcurve(but, NULL, NULL, &driven, &special);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2012-03-24 07:09:57 +00:00
|
|
|
if (fcu && driven) {
|
2012-03-30 01:51:25 +00:00
|
|
|
driver = fcu->driver;
|
2009-07-12 02:06:15 +00:00
|
|
|
|
2012-03-24 07:09:57 +00:00
|
|
|
if (driver && driver->type == DRIVER_TYPE_PYTHON) {
|
2016-11-18 13:37:04 +01:00
|
|
|
if (str) {
|
|
|
|
BLI_strncpy(str, driver->expression, maxlen);
|
|
|
|
}
|
2014-01-20 11:13:53 +11:00
|
|
|
return true;
|
2009-07-12 02:06:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-20 11:13:53 +11:00
|
|
|
return false;
|
2009-07-12 02:06:15 +00:00
|
|
|
}
|
|
|
|
|
2014-01-20 11:13:53 +11:00
|
|
|
bool ui_but_anim_expression_set(uiBut *but, const char *str)
|
2009-07-12 02:06:15 +00:00
|
|
|
{
|
|
|
|
FCurve *fcu;
|
|
|
|
ChannelDriver *driver;
|
2014-01-24 17:09:21 +13:00
|
|
|
bool driven, special;
|
2009-07-12 02:06:15 +00:00
|
|
|
|
2014-01-24 17:09:21 +13:00
|
|
|
fcu = ui_but_get_fcurve(but, NULL, NULL, &driven, &special);
|
2009-07-12 02:06:15 +00:00
|
|
|
|
2012-03-24 07:09:57 +00:00
|
|
|
if (fcu && driven) {
|
2012-03-30 01:51:25 +00:00
|
|
|
driver = fcu->driver;
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2014-05-08 17:57:11 +12:00
|
|
|
if (driver && (driver->type == DRIVER_TYPE_PYTHON)) {
|
2019-06-04 12:10:42 +02:00
|
|
|
bContext *C = but->block->evil_C;
|
|
|
|
|
2011-10-20 07:12:14 +00:00
|
|
|
BLI_strncpy_utf8(driver->expression, str, sizeof(driver->expression));
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2014-05-08 17:57:11 +12:00
|
|
|
/* tag driver as needing to be recompiled */
|
Support evaluating simple driver expressions without Python interpreter.
Recently @sergey found that hard-coding evaluation of certain very
common driver expressions without calling the Python interpreter
produces a 30-40% performance improvement. Since hard-coding is
obviously not suitable for production, I implemented a proper
parser and interpreter for simple arithmetic expressions in C.
The evaluator supports +, -, *, /, (), ==, !=, <, <=, >, >=,
and, or, not, ternary if; driver variables, frame, pi, True, False,
and a subset of standard math functions that seem most useful.
Booleans are represented as numbers, since within the supported
operation set it seems to be impossible to distinguish True/False
from 1.0/0.0. Boolean operations properly implement lazy evaluation
with jumps, and comparisons support chaining like 'a < b < c...'.
Expressions are parsed into a very simple stack machine program
that can then be safely evaluated in multiple threads.
Reviewers: sergey, campbellbarton
Differential Revision: https://developer.blender.org/D3698
2018-09-15 15:32:40 +03:00
|
|
|
BKE_driver_invalidate_expression(driver, true, false);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2014-05-08 17:57:11 +12:00
|
|
|
/* clear invalid flags which may prevent this from working */
|
|
|
|
driver->flag &= ~DRIVER_FLAG_INVALID;
|
2014-05-08 19:54:04 +10:00
|
|
|
fcu->flag &= ~FCURVE_DISABLED;
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2014-05-08 17:57:11 +12:00
|
|
|
/* this notifier should update the Graph Editor and trigger depsgraph refresh? */
|
2019-06-04 12:10:42 +02:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME, NULL);
|
|
|
|
|
|
|
|
DEG_relations_tag_update(CTX_data_main(C));
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2014-01-20 11:13:53 +11:00
|
|
|
return true;
|
2009-07-12 02:06:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-20 11:13:53 +11:00
|
|
|
return false;
|
2009-07-12 02:06:15 +00:00
|
|
|
}
|
|
|
|
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
/* create new expression for button (i.e. a "scripted driver"), if it can be created... */
|
2014-01-20 11:13:53 +11:00
|
|
|
bool ui_but_anim_expression_create(uiBut *but, const char *str)
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
{
|
|
|
|
bContext *C = but->block->evil_C;
|
|
|
|
ID *id;
|
|
|
|
FCurve *fcu;
|
|
|
|
char *path;
|
2013-01-31 21:56:14 +00:00
|
|
|
bool ok = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
/* button must have RNA-pointer to a numeric-capable property */
|
|
|
|
if (ELEM(NULL, but->rnapoin.data, but->rnaprop)) {
|
2019-03-25 10:15:20 +11:00
|
|
|
if (G.debug & G_DEBUG) {
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
printf("ERROR: create expression failed - button has no RNA info attached\n");
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2014-01-20 11:13:53 +11:00
|
|
|
return false;
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-09-16 01:35:52 +00:00
|
|
|
if (RNA_property_array_check(but->rnaprop) != 0) {
|
2013-01-31 16:19:44 +00:00
|
|
|
if (but->rnaindex == -1) {
|
2019-03-25 10:15:20 +11:00
|
|
|
if (G.debug & G_DEBUG) {
|
2013-01-31 16:19:44 +00:00
|
|
|
printf("ERROR: create expression failed - can't create expression for entire array\n");
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2014-01-20 11:13:53 +11:00
|
|
|
return false;
|
2013-01-31 16:19:44 +00:00
|
|
|
}
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
/* make sure we have animdata for this */
|
2019-01-15 23:24:20 +11:00
|
|
|
/* FIXME: until materials can be handled by depsgraph,
|
|
|
|
* don't allow drivers to be created for them */
|
2019-08-23 09:52:12 +02:00
|
|
|
id = but->rnapoin.owner_id;
|
2012-03-30 01:51:25 +00:00
|
|
|
if ((id == NULL) || (GS(id->name) == ID_MA) || (GS(id->name) == ID_TE)) {
|
2019-03-25 10:15:20 +11:00
|
|
|
if (G.debug & G_DEBUG) {
|
2016-09-19 16:46:20 +02:00
|
|
|
printf("ERROR: create expression failed - invalid data-block for adding drivers (%p)\n", id);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2014-01-20 11:13:53 +11:00
|
|
|
return false;
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
/* get path */
|
|
|
|
path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
|
2014-05-21 16:33:48 +10:00
|
|
|
if (path == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
/* create driver */
|
2019-09-27 16:33:48 +02:00
|
|
|
fcu = verify_driver_fcurve(id, path, but->rnaindex, DRIVER_FCURVE_KEYFRAMES);
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
if (fcu) {
|
2012-03-30 01:51:25 +00:00
|
|
|
ChannelDriver *driver = fcu->driver;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
if (driver) {
|
|
|
|
/* set type of driver */
|
|
|
|
driver->type = DRIVER_TYPE_PYTHON;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
/* set the expression */
|
2012-07-06 23:56:59 +00:00
|
|
|
/* TODO: need some way of identifying variables used */
|
2011-10-20 07:12:14 +00:00
|
|
|
BLI_strncpy_utf8(driver->expression, str, sizeof(driver->expression));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
/* updates */
|
Support evaluating simple driver expressions without Python interpreter.
Recently @sergey found that hard-coding evaluation of certain very
common driver expressions without calling the Python interpreter
produces a 30-40% performance improvement. Since hard-coding is
obviously not suitable for production, I implemented a proper
parser and interpreter for simple arithmetic expressions in C.
The evaluator supports +, -, *, /, (), ==, !=, <, <=, >, >=,
and, or, not, ternary if; driver variables, frame, pi, True, False,
and a subset of standard math functions that seem most useful.
Booleans are represented as numbers, since within the supported
operation set it seems to be impossible to distinguish True/False
from 1.0/0.0. Boolean operations properly implement lazy evaluation
with jumps, and comparisons support chaining like 'a < b < c...'.
Expressions are parsed into a very simple stack machine program
that can then be safely evaluated in multiple threads.
Reviewers: sergey, campbellbarton
Differential Revision: https://developer.blender.org/D3698
2018-09-15 15:32:40 +03:00
|
|
|
BKE_driver_invalidate_expression(driver, true, false);
|
2017-06-08 10:14:53 +02:00
|
|
|
DEG_relations_tag_update(CTX_data_main(C));
|
2012-03-30 01:51:25 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME, NULL);
|
2013-01-31 21:56:14 +00:00
|
|
|
ok = true;
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
}
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
MEM_freeN(path);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
First stages of easier "expressions" creation...
It is now possible to create "scripted expression" drivers by simply
clicking on some property, and typing some short Python expression
prefixed with a '#'. This will result in a scripted expression driver,
with the typed-in text being created.
For example, you can click on X-Location of the default cube, and
type:
#sin(frame)
and a new driver will be created for the x-location of the cube. This
will use the current frame value, and modulate this with a sine wave.
Do note though, that the current frame is a special case here. In the
current implementation, a special "frame" driver variable, which
references the current scene frame is created automatically, so that
this simple and (assumed) common case will work straight out of the
box.
Future improvements:
- Explore possibilities of semi-automated extraction of variables from
such expressions, resulting in automated variable extraction. (Doing
away with variables completely is definitely 100% off the agenda
though)
- Look into some ways of defining some shorthands for referencing
local data (possibly related to variable extraction?)
2011-07-04 03:12:28 +00:00
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2010-01-12 03:01:19 +00:00
|
|
|
void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
|
2009-07-12 02:06:15 +00:00
|
|
|
{
|
2020-08-12 13:20:32 +02:00
|
|
|
ED_autokeyframe_property(C, scene, &but->rnapoin, but->rnaprop, but->rnaindex, cfra);
|
2009-04-03 23:30:32 +00:00
|
|
|
}
|
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
void ui_but_anim_copy_driver(bContext *C)
|
|
|
|
{
|
2014-11-09 21:20:40 +01:00
|
|
|
/* this operator calls UI_context_active_but_prop_get */
|
2009-09-25 04:51:04 +00:00
|
|
|
WM_operator_name_call(C, "ANIM_OT_copy_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ui_but_anim_paste_driver(bContext *C)
|
|
|
|
{
|
2014-11-09 21:20:40 +01:00
|
|
|
/* this operator calls UI_context_active_but_prop_get */
|
2009-09-25 04:51:04 +00:00
|
|
|
WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
|
|
|
|
}
|
2018-06-16 14:48:21 +02:00
|
|
|
|
|
|
|
void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy))
|
|
|
|
{
|
2018-06-18 08:25:05 +02:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
2020-08-07 14:34:11 +02:00
|
|
|
uiButDecorator *but_decorate = arg_but;
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
uiBut *but_anim = ui_but_anim_decorate_find_attached_button(but_decorate);
|
|
|
|
|
|
|
|
if (!but_anim) {
|
|
|
|
return;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-16 14:48:21 +02:00
|
|
|
/* FIXME(campbell), swapping active pointer is weak. */
|
2020-08-07 14:34:11 +02:00
|
|
|
SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->but.active);
|
2018-06-18 08:25:05 +02:00
|
|
|
wm->op_undo_depth++;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
if (but_anim->flag & UI_BUT_DRIVEN) {
|
2018-06-16 14:48:21 +02:00
|
|
|
/* pass */
|
|
|
|
/* TODO: report? */
|
|
|
|
}
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
else if (but_anim->flag & UI_BUT_ANIMATED_KEY) {
|
2018-06-16 14:48:21 +02:00
|
|
|
PointerRNA props_ptr;
|
|
|
|
wmOperatorType *ot = WM_operatortype_find("ANIM_OT_keyframe_delete_button", false);
|
|
|
|
WM_operator_properties_create_ptr(&props_ptr, ot);
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
RNA_boolean_set(&props_ptr, "all", but_anim->rnaindex == -1);
|
2018-06-16 14:48:21 +02:00
|
|
|
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
|
|
|
|
WM_operator_properties_free(&props_ptr);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
PointerRNA props_ptr;
|
|
|
|
wmOperatorType *ot = WM_operatortype_find("ANIM_OT_keyframe_insert_button", false);
|
|
|
|
WM_operator_properties_create_ptr(&props_ptr, ot);
|
UI: Better split layout support for checkboxes
Makes the following layout changes possible:
{F8473498} {F8473499} {F8473502}
The next commit will contain many layout changes to make good use of
these new possibilities. The result should be more consistent, easier to
read and should give a more organized impression. Additionally, it
should be possible to replace many sub-panels with compacter layouts.
Main changes:
* Checkboxes now respect the property split layouts
* Add support for row and column headers (i.e.
`uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")`). If the
first property added to this layout doesn't insert anything into the label
split column, the heading is inserted there. Otherwise, it's inserted as own
item.
* Add support for manually inserting decorators for an existing item
(`uiLayout.prop_decorator()`). That way layout creators can manually insert
this, which was the only way I saw to support property split layouts with a
checkbox before the actual property. {F8471883}
* Autogenerated layouts for operator properties look bad if there are only
checkboxes (which only use half the region width). So before creating the
layout, we iterate over visible properties and disable split layout if all
are booleans. I think this is fine, if needed we could also add layout hints
to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
used to be responsible for this. Code that didn't handle these so far never
used macros I think, so this change should be invisible.
* Remove manual property split layout from autogenerated operator properties
layout.
* Padding of checkboxes is tweaked to make their label visually more connected
to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
`.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
Maniphest Task: https://developer.blender.org/T65965
Differential Revision: https://developer.blender.org/D7427
Reviewed by: Brecht Van Lommel, William Reynish, Pablo Vazques
2020-04-17 16:40:25 +02:00
|
|
|
RNA_boolean_set(&props_ptr, "all", but_anim->rnaindex == -1);
|
2018-06-16 14:48:21 +02:00
|
|
|
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
|
|
|
|
WM_operator_properties_free(&props_ptr);
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-07 14:34:11 +02:00
|
|
|
SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->but.active);
|
2018-06-18 08:25:05 +02:00
|
|
|
wm->op_undo_depth--;
|
2018-06-16 14:48:21 +02:00
|
|
|
}
|