2011-02-23 10:52:22 +00:00
|
|
|
/*
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +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,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
*/
|
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup edinterface
|
2011-02-27 20:29:51 +00:00
|
|
|
*/
|
|
|
|
|
|
2016-03-24 23:28:46 +11:00
|
|
|
#include <ctype.h>
|
2009-12-29 15:40:26 +00:00
|
|
|
#include <stddef.h>
|
2020-03-19 09:33:03 +01:00
|
|
|
#include <stdlib.h>
|
2009-06-07 13:20:41 +00:00
|
|
|
#include <string.h>
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_brush_types.h"
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
#include "DNA_cachefile_types.h"
|
2019-04-02 17:44:18 +02:00
|
|
|
#include "DNA_constraint_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_curveprofile_types.h"
|
|
|
|
|
#include "DNA_gpencil_modifier_types.h"
|
2013-03-18 16:34:57 +00:00
|
|
|
#include "DNA_node_types.h"
|
2018-02-07 11:14:08 +11:00
|
|
|
#include "DNA_object_force_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_object_types.h"
|
|
|
|
|
#include "DNA_scene_types.h"
|
2018-07-31 10:22:19 +02:00
|
|
|
#include "DNA_shader_fx_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_texture_types.h"
|
2009-06-24 17:22:22 +00:00
|
|
|
|
2020-07-07 10:08:42 +02:00
|
|
|
#include "BLI_alloca.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_fnmatch.h"
|
2013-01-24 21:57:13 +00:00
|
|
|
#include "BLI_listbase.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_math.h"
|
2018-09-18 17:44:14 +02:00
|
|
|
#include "BLI_path_util.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_rect.h"
|
|
|
|
|
#include "BLI_string.h"
|
2020-09-09 13:44:39 +02:00
|
|
|
#include "BLI_string_search.h"
|
2016-01-18 01:39:09 +01:00
|
|
|
#include "BLI_timecode.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_utildefines.h"
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
#include "BLF_api.h"
|
2015-08-16 17:32:01 +10:00
|
|
|
#include "BLT_translation.h"
|
2011-11-09 14:13:17 +00:00
|
|
|
|
2019-04-02 17:44:18 +02:00
|
|
|
#include "BKE_action.h"
|
2017-12-07 15:36:26 +11:00
|
|
|
#include "BKE_colorband.h"
|
2010-01-04 17:28:37 +00:00
|
|
|
#include "BKE_colortools.h"
|
2019-04-02 17:44:18 +02:00
|
|
|
#include "BKE_constraint.h"
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
#include "BKE_context.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_curveprofile.h"
|
2009-06-27 01:15:31 +00:00
|
|
|
#include "BKE_global.h"
|
2018-07-31 10:22:19 +02:00
|
|
|
#include "BKE_gpencil_modifier.h"
|
2017-03-30 17:01:23 +02:00
|
|
|
#include "BKE_idprop.h"
|
2020-03-20 12:19:44 +11:00
|
|
|
#include "BKE_idtype.h"
|
2017-03-30 17:01:23 +02:00
|
|
|
#include "BKE_layer.h"
|
2020-02-10 12:58:59 +01:00
|
|
|
#include "BKE_lib_id.h"
|
|
|
|
|
#include "BKE_lib_override.h"
|
2014-05-03 18:51:53 +09:00
|
|
|
#include "BKE_linestyle.h"
|
2009-09-16 18:47:42 +00:00
|
|
|
#include "BKE_main.h"
|
2013-01-24 21:57:13 +00:00
|
|
|
#include "BKE_modifier.h"
|
|
|
|
|
#include "BKE_object.h"
|
2013-01-27 14:28:45 +00:00
|
|
|
#include "BKE_packedFile.h"
|
2018-11-07 18:00:24 +01:00
|
|
|
#include "BKE_particle.h"
|
2010-07-14 14:11:03 +00:00
|
|
|
#include "BKE_report.h"
|
2020-01-28 14:34:35 +01:00
|
|
|
#include "BKE_scene.h"
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
#include "BKE_screen.h"
|
2018-07-31 10:22:19 +02:00
|
|
|
#include "BKE_shader_fx.h"
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
|
2017-06-08 10:14:53 +02:00
|
|
|
#include "DEG_depsgraph.h"
|
|
|
|
|
#include "DEG_depsgraph_build.h"
|
|
|
|
|
|
2019-09-06 01:22:35 +02:00
|
|
|
#include "ED_fileselect.h"
|
2011-08-08 08:22:01 +00:00
|
|
|
#include "ED_object.h"
|
Sorry, three commits in one, became difficult to untangle..
Editors Modules
* render/ module added in editors, moved the preview render code there and
also shading related operators.
* physics/ module made more consistent with other modules. renaming files,
making a single physics_ops.c for operators and keymaps. Also move all
particle related operators here now.
* space_buttons/ now should have only operators relevant to the buttons
specificially.
Updates & Notifiers
* Material/Texture/World/Lamp can now be passed to DAG_id_flush_update,
which will go back to a callback in editors. Eventually these should
be in the depsgraph itself, but for now this gives a unified call for
doing updates.
* GLSL materials are now refreshed on changes. There's still various
cases missing,
* Preview icons now hook into this system, solving various update cases
that were missed before.
* Also fixes issue in my last commit, where some preview would not render,
problem is avoided in the new system.
Icon Rendering
* On systems with support for non-power of two textures, an OpenGL texture
is now used instead of glDrawPixels. This avoids problems with icons get
clipped on region borders. On my Linux desktop, this gives an 1.1x speedup,
and on my Mac laptop a 2.3x speedup overall in redrawing the full window,
with the default setup. The glDrawPixels implementation on Mac seems to
have a lot of overhread.
* Preview icons are now drawn using proper premul alpha, and never faded so
you can see them clearly.
* Also tried to fix issue with texture node preview rendering, globals can't
be used with threads reliably.
2009-09-29 19:12:12 +00:00
|
|
|
#include "ED_render.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "ED_screen.h"
|
2018-04-02 15:02:08 +02:00
|
|
|
#include "ED_undo.h"
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
|
|
|
|
|
#include "RNA_access.h"
|
|
|
|
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
2018-09-18 17:44:14 +02:00
|
|
|
#include "BLO_readfile.h"
|
|
|
|
|
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
#include "UI_interface.h"
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
#include "UI_interface_icons.h"
|
2019-11-25 11:42:49 +01:00
|
|
|
#include "UI_view2d.h"
|
2009-06-25 15:41:27 +00:00
|
|
|
#include "interface_intern.h"
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
|
2016-01-18 01:39:09 +01:00
|
|
|
#include "PIL_time.h"
|
|
|
|
|
|
2017-10-21 16:47:25 +02:00
|
|
|
/* we may want to make this optional, disable for now. */
|
|
|
|
|
// #define USE_OP_RESET_BUT
|
|
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
/* defines for templateID/TemplateSearch */
|
2021-03-18 15:00:55 +01:00
|
|
|
#define TEMPLATE_SEARCH_TEXTBUT_MIN_WIDTH (UI_UNIT_X * 6)
|
2017-05-12 01:42:42 +02:00
|
|
|
#define TEMPLATE_SEARCH_TEXTBUT_HEIGHT UI_UNIT_Y
|
|
|
|
|
|
2011-02-13 14:16:36 +00:00
|
|
|
void UI_template_fix_linking(void)
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:42:04 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Header Template
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
void uiTemplateHeader(uiLayout *layout, bContext *C)
|
|
|
|
|
{
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutAbsoluteBlock(layout);
|
2019-09-06 16:42:04 +10:00
|
|
|
ED_area_header_switchbutton(C, block, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Search Menu Helpers
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2021-03-18 15:00:55 +01:00
|
|
|
static int template_search_textbut_width(PointerRNA *ptr, PropertyRNA *name_prop)
|
|
|
|
|
{
|
|
|
|
|
char str[UI_MAX_DRAW_STR];
|
|
|
|
|
int buf_len = 0;
|
|
|
|
|
|
|
|
|
|
BLI_assert(RNA_property_type(name_prop) == PROP_STRING);
|
|
|
|
|
|
|
|
|
|
const char *name = RNA_property_string_get_alloc(ptr, name_prop, str, sizeof(str), &buf_len);
|
|
|
|
|
|
|
|
|
|
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
|
|
|
|
|
const int margin = UI_UNIT_X * 0.75f;
|
|
|
|
|
const int estimated_width = UI_fontstyle_string_width(fstyle, name) + margin;
|
|
|
|
|
|
|
|
|
|
if (name != str) {
|
|
|
|
|
MEM_freeN((void *)name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Clamp to some min/max width. */
|
|
|
|
|
return CLAMPIS(
|
|
|
|
|
estimated_width, TEMPLATE_SEARCH_TEXTBUT_MIN_WIDTH, TEMPLATE_SEARCH_TEXTBUT_MIN_WIDTH * 3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int template_search_textbut_height(void)
|
|
|
|
|
{
|
|
|
|
|
return TEMPLATE_SEARCH_TEXTBUT_HEIGHT;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
/**
|
|
|
|
|
* Add a block button for the search menu for templateID and templateSearch.
|
|
|
|
|
*/
|
|
|
|
|
static void template_add_button_search_menu(const bContext *C,
|
|
|
|
|
uiLayout *layout,
|
|
|
|
|
uiBlock *block,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
PropertyRNA *prop,
|
|
|
|
|
uiBlockCreateFunc block_func,
|
|
|
|
|
void *block_argN,
|
|
|
|
|
const char *const tip,
|
2018-07-31 10:22:19 +02:00
|
|
|
const bool use_previews,
|
|
|
|
|
const bool editable,
|
|
|
|
|
const bool live_icon)
|
2017-05-12 01:42:42 +02:00
|
|
|
{
|
2020-08-26 10:11:13 +10:00
|
|
|
const PointerRNA active_ptr = RNA_property_pointer_get(ptr, prop);
|
2017-05-12 01:42:42 +02:00
|
|
|
ID *id = (active_ptr.data && RNA_struct_is_ID(active_ptr.type)) ? active_ptr.data : NULL;
|
2019-08-23 09:52:12 +02:00
|
|
|
const ID *idfrom = ptr->owner_id;
|
2017-05-12 01:42:42 +02:00
|
|
|
const StructRNA *type = active_ptr.type ? active_ptr.type : RNA_property_pointer_type(ptr, prop);
|
|
|
|
|
uiBut *but;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
if (use_previews) {
|
|
|
|
|
ARegion *region = CTX_wm_region(C);
|
2019-04-18 21:13:22 +02:00
|
|
|
/* Ugly tool header exception. */
|
|
|
|
|
const bool use_big_size = (region->regiontype != RGN_TYPE_TOOL_HEADER);
|
2019-01-15 23:24:20 +11:00
|
|
|
/* Ugly exception for screens here,
|
|
|
|
|
* drawing their preview in icon size looks ugly/useless */
|
2017-05-12 01:42:42 +02:00
|
|
|
const bool use_preview_icon = use_big_size || (id && (GS(id->name) != ID_SCR));
|
|
|
|
|
const short width = UI_UNIT_X * (use_big_size ? 6 : 1.6f);
|
2017-10-07 15:57:14 +11:00
|
|
|
const short height = UI_UNIT_Y * (use_big_size ? 6 : 1);
|
2019-11-26 19:43:36 +01:00
|
|
|
uiLayout *col = NULL;
|
|
|
|
|
|
|
|
|
|
if (use_big_size) {
|
|
|
|
|
/* Assume column layout here. To be more correct, we should check if the layout passed to
|
|
|
|
|
* template_id is a column one, but this should work well in practice. */
|
|
|
|
|
col = uiLayoutColumn(layout, true);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, width, height, tip);
|
|
|
|
|
if (use_preview_icon) {
|
2020-08-26 10:11:13 +10:00
|
|
|
const int icon = id ? ui_id_icon_get(C, id, use_big_size) : RNA_struct_ui_icon(type);
|
2017-05-12 01:42:42 +02:00
|
|
|
ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
|
|
|
|
|
UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if ((idfrom && idfrom->lib) || !editable) {
|
2017-05-12 01:42:42 +02:00
|
|
|
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2017-05-12 01:42:42 +02:00
|
|
|
if (use_big_size) {
|
2019-11-26 19:43:36 +01:00
|
|
|
uiLayoutRow(col ? col : layout, true);
|
2017-05-12 01:42:42 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, tip);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-31 10:22:19 +02:00
|
|
|
if (live_icon) {
|
2020-08-26 10:11:13 +10:00
|
|
|
const int icon = id ? ui_id_icon_get(C, id, false) : RNA_struct_ui_icon(type);
|
2018-07-31 10:22:19 +02:00
|
|
|
ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
|
|
|
|
|
}
|
2017-05-12 01:42:42 +02:00
|
|
|
if (id) {
|
|
|
|
|
/* default dragging of icon for id browse buttons */
|
|
|
|
|
UI_but_drag_set_id(but, id);
|
|
|
|
|
}
|
|
|
|
|
UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if ((idfrom && idfrom->lib) || !editable) {
|
2017-05-12 01:42:42 +02:00
|
|
|
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2017-05-12 01:42:42 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uiBlock *template_common_search_menu(const bContext *C,
|
|
|
|
|
ARegion *region,
|
2020-05-07 23:16:05 +10:00
|
|
|
uiButSearchUpdateFn search_update_fn,
|
2017-05-12 01:42:42 +02:00
|
|
|
void *search_arg,
|
2020-05-08 12:01:35 +10:00
|
|
|
uiButHandleFunc search_exec_fn,
|
2017-05-12 01:42:42 +02:00
|
|
|
void *active_item,
|
2021-01-26 22:06:45 +01:00
|
|
|
uiButSearchTooltipFn item_tooltip_fn,
|
2018-07-31 10:22:19 +02:00
|
|
|
const int preview_rows,
|
|
|
|
|
const int preview_cols,
|
2018-07-31 20:11:55 +10:00
|
|
|
float scale)
|
2017-05-12 01:42:42 +02:00
|
|
|
{
|
|
|
|
|
static char search[256];
|
|
|
|
|
wmWindow *win = CTX_wm_window(C);
|
|
|
|
|
uiBut *but;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
/* clear initial search string, then all items show */
|
|
|
|
|
search[0] = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
|
2017-05-12 01:42:42 +02:00
|
|
|
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
|
2018-09-11 11:01:39 +10:00
|
|
|
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
/* preview thumbnails */
|
|
|
|
|
if (preview_rows > 0 && preview_cols > 0) {
|
2018-07-31 10:22:19 +02:00
|
|
|
const int w = 4 * U.widget_unit * preview_cols * scale;
|
|
|
|
|
const int h = 5 * U.widget_unit * preview_rows * scale;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
/* fake button, it holds space for search items */
|
|
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
but = uiDefSearchBut(block,
|
|
|
|
|
search,
|
|
|
|
|
0,
|
|
|
|
|
ICON_VIEWZOOM,
|
|
|
|
|
sizeof(search),
|
|
|
|
|
10,
|
|
|
|
|
0,
|
|
|
|
|
w,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
preview_rows,
|
|
|
|
|
preview_cols,
|
|
|
|
|
"");
|
|
|
|
|
}
|
|
|
|
|
/* list view */
|
|
|
|
|
else {
|
|
|
|
|
const int searchbox_width = UI_searchbox_size_x();
|
|
|
|
|
const int searchbox_height = UI_searchbox_size_y();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
/* fake button, it holds space for search items */
|
|
|
|
|
uiDefBut(block,
|
|
|
|
|
UI_BTYPE_LABEL,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
10,
|
|
|
|
|
15,
|
|
|
|
|
searchbox_width,
|
|
|
|
|
searchbox_height,
|
|
|
|
|
NULL,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
NULL);
|
|
|
|
|
but = uiDefSearchBut(block,
|
|
|
|
|
search,
|
|
|
|
|
0,
|
|
|
|
|
ICON_VIEWZOOM,
|
|
|
|
|
sizeof(search),
|
|
|
|
|
10,
|
|
|
|
|
0,
|
|
|
|
|
searchbox_width,
|
|
|
|
|
UI_UNIT_Y - 1,
|
|
|
|
|
0,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2017-05-12 01:42:42 +02:00
|
|
|
"");
|
|
|
|
|
}
|
2020-04-14 18:46:13 +10:00
|
|
|
UI_but_func_search_set(but,
|
|
|
|
|
ui_searchbox_create_generic,
|
2020-05-07 23:16:05 +10:00
|
|
|
search_update_fn,
|
2020-04-14 18:46:13 +10:00
|
|
|
search_arg,
|
2021-04-14 11:11:51 -05:00
|
|
|
false,
|
2020-04-14 18:46:13 +10:00
|
|
|
NULL,
|
2020-05-08 12:01:35 +10:00
|
|
|
search_exec_fn,
|
2020-04-14 18:46:13 +10:00
|
|
|
active_item);
|
2021-01-26 22:06:45 +01:00
|
|
|
UI_but_func_search_set_tooltip(but, item_tooltip_fn);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
|
|
|
|
|
UI_block_direction_set(block, UI_DIR_DOWN);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
/* give search-field focus */
|
|
|
|
|
UI_but_focus_on_enter_event(win, but);
|
|
|
|
|
/* this type of search menu requires undo */
|
|
|
|
|
but->flag |= UI_BUT_UNDO;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
return block;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Search Callbacks
|
|
|
|
|
* \{ */
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
|
2009-06-07 13:20:41 +00:00
|
|
|
typedef struct TemplateID {
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
PointerRNA ptr;
|
|
|
|
|
PropertyRNA *prop;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-27 01:15:31 +00:00
|
|
|
ListBase *idlb;
|
2018-01-03 21:54:02 +11:00
|
|
|
short idcode;
|
|
|
|
|
short filter;
|
2010-01-03 08:37:18 +00:00
|
|
|
int prv_rows, prv_cols;
|
2013-04-04 02:05:11 +00:00
|
|
|
bool preview;
|
2018-07-31 10:22:19 +02:00
|
|
|
float scale;
|
2009-06-07 13:20:41 +00:00
|
|
|
} TemplateID;
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
|
2021-06-24 15:56:58 +10:00
|
|
|
/* Search browse menu, assign. */
|
2020-05-08 12:01:35 +10:00
|
|
|
static void template_ID_set_property_exec_fn(bContext *C, void *arg_template, void *item)
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
{
|
2017-12-08 14:50:45 +01:00
|
|
|
TemplateID *template_ui = (TemplateID *)arg_template;
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
|
2009-06-27 01:15:31 +00:00
|
|
|
/* ID */
|
2012-03-24 06:38:07 +00:00
|
|
|
if (item) {
|
2009-06-27 01:15:31 +00:00
|
|
|
PointerRNA idptr;
|
2009-06-11 17:21:27 +00:00
|
|
|
|
|
|
|
|
RNA_id_pointer_create(item, &idptr);
|
2019-05-20 18:06:09 +10:00
|
|
|
RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
|
2017-12-08 14:50:45 +01:00
|
|
|
RNA_property_update(C, &template_ui->ptr, template_ui->prop);
|
2009-06-27 01:15:31 +00:00
|
|
|
}
|
2009-06-11 17:21:27 +00:00
|
|
|
}
|
|
|
|
|
|
2020-09-09 13:44:39 +02:00
|
|
|
static bool id_search_allows_id(TemplateID *template_ui, const int flag, ID *id, const char *query)
|
2018-01-03 21:54:02 +11:00
|
|
|
{
|
2019-08-23 09:52:12 +02:00
|
|
|
ID *id_from = template_ui->ptr.owner_id;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-09 13:44:39 +02:00
|
|
|
/* Do self check. */
|
|
|
|
|
if ((flag & PROP_ID_SELF_CHECK) && id == id_from) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-09 13:44:39 +02:00
|
|
|
/* Use filter. */
|
|
|
|
|
if (RNA_property_type(template_ui->prop) == PROP_POINTER) {
|
|
|
|
|
PointerRNA ptr;
|
|
|
|
|
RNA_id_pointer_create(id, &ptr);
|
|
|
|
|
if (RNA_property_pointer_poll(&template_ui->ptr, template_ui->prop, &ptr) == 0) {
|
|
|
|
|
return false;
|
2018-01-03 21:54:02 +11:00
|
|
|
}
|
2020-09-09 13:44:39 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-05 16:23:34 +11:00
|
|
|
/* Hide dot prefixed data-blocks, but only if filter does not force them visible. */
|
2020-09-09 13:44:39 +02:00
|
|
|
if (U.uiflag & USER_HIDE_DOT) {
|
|
|
|
|
if ((id->name[2] == '.') && (query[0] != '.')) {
|
|
|
|
|
return false;
|
2018-01-03 21:54:02 +11:00
|
|
|
}
|
2020-09-09 13:44:39 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-09 13:44:39 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
2020-06-29 17:19:43 +02:00
|
|
|
|
2020-09-09 13:44:39 +02:00
|
|
|
static bool id_search_add(const bContext *C, TemplateID *template_ui, uiSearchItems *items, ID *id)
|
|
|
|
|
{
|
|
|
|
|
/* +1 is needed because BKE_id_ui_prefix used 3 letter prefix
|
|
|
|
|
* followed by ID_NAME-2 characters from id->name
|
|
|
|
|
*/
|
|
|
|
|
char name_ui[MAX_ID_FULL_NAME_UI];
|
|
|
|
|
int iconid = ui_id_icon_get(C, id, template_ui->preview);
|
|
|
|
|
const bool use_lib_prefix = template_ui->preview || iconid;
|
|
|
|
|
const bool has_sep_char = (id->lib != NULL);
|
|
|
|
|
|
|
|
|
|
/* When using previews, the library hint (linked, overridden, missing) is added with a
|
|
|
|
|
* character prefix, otherwise we can use a icon. */
|
|
|
|
|
int name_prefix_offset;
|
|
|
|
|
BKE_id_full_name_ui_prefix_get(name_ui, id, use_lib_prefix, UI_SEP_CHAR, &name_prefix_offset);
|
|
|
|
|
if (!use_lib_prefix) {
|
2020-09-18 10:24:14 +10:00
|
|
|
iconid = UI_icon_from_library(id);
|
2018-01-03 21:54:02 +11:00
|
|
|
}
|
2020-09-09 13:44:39 +02:00
|
|
|
|
|
|
|
|
if (!UI_search_item_add(items,
|
|
|
|
|
name_ui,
|
|
|
|
|
id,
|
|
|
|
|
iconid,
|
|
|
|
|
has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0,
|
|
|
|
|
name_prefix_offset)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-03 21:54:02 +11:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-11 17:21:27 +00:00
|
|
|
/* ID Search browse menu, do the search */
|
2010-11-17 09:45:45 +00:00
|
|
|
static void id_search_cb(const bContext *C,
|
|
|
|
|
void *arg_template,
|
|
|
|
|
const char *str,
|
UI: Expose an "is first search" boolean to search button callbacks
Currently when you open an RNA collection search button, like a
vertex group selector, the search filter isn't applied until you
start typing, in order to display every option at the start.
Otherwise they wouldn't be visible, since the search filter would
run for the current text.
Currently this check happens in one place, but it relies on the
`changed` value of `uiBut`. This is fine in the interface directory,
but anywhere else it would require exposing `uiBut.changed`, which
is probably too low-level to expose.
The solution is adding an `is_first` argument to the search callbacks,
which is nice for a few reasons:
- They work at a higher level of abstraction, meaning they don't
have to worry about how exactly to tell if this is the first
search.
- It makes it easier to do special behavior when the search menu
is first opened.
- Then, obviously, it makes that state accessible without including
`interface_intern.h`.
Needed for attribute search: T85658
Differential Revision: https://developer.blender.org/D10528
2021-03-02 11:42:05 -06:00
|
|
|
uiSearchItems *items,
|
|
|
|
|
const bool UNUSED(is_first))
|
2009-06-11 17:21:27 +00:00
|
|
|
{
|
2017-12-08 14:50:45 +01:00
|
|
|
TemplateID *template_ui = (TemplateID *)arg_template;
|
|
|
|
|
ListBase *lb = template_ui->idlb;
|
2020-08-26 10:11:13 +10:00
|
|
|
const int flag = RNA_property_flag(template_ui->prop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-09 13:44:39 +02:00
|
|
|
StringSearch *search = BLI_string_search_new();
|
|
|
|
|
|
2009-06-27 01:15:31 +00:00
|
|
|
/* ID listbase */
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH (ID *, id, lb) {
|
2020-09-09 13:44:39 +02:00
|
|
|
if (id_search_allows_id(template_ui, flag, id, str)) {
|
|
|
|
|
BLI_string_search_add(search, id->name + 2, id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ID **filtered_ids;
|
2021-01-04 17:02:13 +11:00
|
|
|
const int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_ids);
|
2020-09-09 13:44:39 +02:00
|
|
|
|
|
|
|
|
for (int i = 0; i < filtered_amount; i++) {
|
|
|
|
|
if (!id_search_add(C, template_ui, items, filtered_ids[i])) {
|
2018-01-03 21:54:02 +11:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-09 13:44:39 +02:00
|
|
|
|
|
|
|
|
MEM_freeN(filtered_ids);
|
|
|
|
|
BLI_string_search_free(search);
|
2018-01-03 21:54:02 +11:00
|
|
|
}
|
2010-07-31 01:06:08 +00:00
|
|
|
|
2018-01-03 21:54:02 +11:00
|
|
|
/**
|
|
|
|
|
* Use id tags for filtering.
|
|
|
|
|
*/
|
|
|
|
|
static void id_search_cb_tagged(const bContext *C,
|
|
|
|
|
void *arg_template,
|
|
|
|
|
const char *str,
|
|
|
|
|
uiSearchItems *items)
|
|
|
|
|
{
|
|
|
|
|
TemplateID *template_ui = (TemplateID *)arg_template;
|
|
|
|
|
ListBase *lb = template_ui->idlb;
|
2020-08-26 10:11:13 +10:00
|
|
|
const int flag = RNA_property_flag(template_ui->prop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-09 13:44:39 +02:00
|
|
|
StringSearch *search = BLI_string_search_new();
|
|
|
|
|
|
2018-01-03 21:54:02 +11:00
|
|
|
/* ID listbase */
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH (ID *, id, lb) {
|
2018-01-03 21:54:02 +11:00
|
|
|
if (id->tag & LIB_TAG_DOIT) {
|
2020-09-09 13:44:39 +02:00
|
|
|
if (id_search_allows_id(template_ui, flag, id, str)) {
|
|
|
|
|
BLI_string_search_add(search, id->name + 2, id);
|
2010-08-03 06:51:36 +00:00
|
|
|
}
|
2018-01-03 21:54:02 +11:00
|
|
|
id->tag &= ~LIB_TAG_DOIT;
|
2009-07-21 01:26:17 +00:00
|
|
|
}
|
2009-06-11 17:21:27 +00:00
|
|
|
}
|
2020-09-09 13:44:39 +02:00
|
|
|
|
|
|
|
|
ID **filtered_ids;
|
2021-01-04 17:02:13 +11:00
|
|
|
const int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_ids);
|
2020-09-09 13:44:39 +02:00
|
|
|
|
|
|
|
|
for (int i = 0; i < filtered_amount; i++) {
|
|
|
|
|
if (!id_search_add(C, template_ui, items, filtered_ids[i])) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(filtered_ids);
|
|
|
|
|
BLI_string_search_free(search);
|
2009-06-11 17:21:27 +00:00
|
|
|
}
|
2010-08-03 06:51:36 +00:00
|
|
|
|
2018-01-03 21:54:02 +11:00
|
|
|
/**
|
|
|
|
|
* A version of 'id_search_cb' that lists scene objects.
|
|
|
|
|
*/
|
|
|
|
|
static void id_search_cb_objects_from_scene(const bContext *C,
|
|
|
|
|
void *arg_template,
|
|
|
|
|
const char *str,
|
UI: Expose an "is first search" boolean to search button callbacks
Currently when you open an RNA collection search button, like a
vertex group selector, the search filter isn't applied until you
start typing, in order to display every option at the start.
Otherwise they wouldn't be visible, since the search filter would
run for the current text.
Currently this check happens in one place, but it relies on the
`changed` value of `uiBut`. This is fine in the interface directory,
but anywhere else it would require exposing `uiBut.changed`, which
is probably too low-level to expose.
The solution is adding an `is_first` argument to the search callbacks,
which is nice for a few reasons:
- They work at a higher level of abstraction, meaning they don't
have to worry about how exactly to tell if this is the first
search.
- It makes it easier to do special behavior when the search menu
is first opened.
- Then, obviously, it makes that state accessible without including
`interface_intern.h`.
Needed for attribute search: T85658
Differential Revision: https://developer.blender.org/D10528
2021-03-02 11:42:05 -06:00
|
|
|
uiSearchItems *items,
|
|
|
|
|
const bool UNUSED(is_first))
|
2018-01-03 21:54:02 +11:00
|
|
|
{
|
|
|
|
|
TemplateID *template_ui = (TemplateID *)arg_template;
|
|
|
|
|
ListBase *lb = template_ui->idlb;
|
|
|
|
|
Scene *scene = NULL;
|
2019-08-23 09:52:12 +02:00
|
|
|
ID *id_from = template_ui->ptr.owner_id;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-01-03 21:54:02 +11:00
|
|
|
if (id_from && GS(id_from->name) == ID_SCE) {
|
|
|
|
|
scene = (Scene *)id_from;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
scene = CTX_data_scene(C);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-01-03 21:54:02 +11:00
|
|
|
BKE_main_id_flag_listbase(lb, LIB_TAG_DOIT, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-03-01 19:00:54 +11:00
|
|
|
FOREACH_SCENE_OBJECT_BEGIN (scene, ob_iter) {
|
2018-01-04 00:09:10 +11:00
|
|
|
ob_iter->id.tag |= LIB_TAG_DOIT;
|
2009-06-11 17:21:27 +00:00
|
|
|
}
|
2018-03-09 11:44:42 +11:00
|
|
|
FOREACH_SCENE_OBJECT_END;
|
2018-01-03 21:54:02 +11:00
|
|
|
id_search_cb_tagged(C, arg_template, str, items);
|
2009-06-11 17:21:27 +00:00
|
|
|
}
|
|
|
|
|
|
2021-01-26 22:06:45 +01:00
|
|
|
static ARegion *template_ID_search_menu_item_tooltip(
|
|
|
|
|
bContext *C, ARegion *region, const rcti *item_rect, void *arg, void *active)
|
|
|
|
|
{
|
|
|
|
|
TemplateID *template_ui = arg;
|
|
|
|
|
ID *active_id = active;
|
|
|
|
|
StructRNA *type = RNA_property_pointer_type(&template_ui->ptr, template_ui->prop);
|
|
|
|
|
|
|
|
|
|
uiSearchItemTooltipData tooltip_data = {0};
|
|
|
|
|
|
|
|
|
|
tooltip_data.name = active_id->name + 2;
|
|
|
|
|
BLI_snprintf(tooltip_data.description,
|
|
|
|
|
sizeof(tooltip_data.description),
|
|
|
|
|
TIP_("Choose %s data-block to be assigned to this user"),
|
|
|
|
|
RNA_struct_ui_name(type));
|
|
|
|
|
if (ID_IS_LINKED(active_id)) {
|
|
|
|
|
BLI_snprintf(tooltip_data.hint,
|
|
|
|
|
sizeof(tooltip_data.hint),
|
|
|
|
|
TIP_("Source library: %s\n%s"),
|
|
|
|
|
active_id->lib->id.name + 2,
|
|
|
|
|
active_id->lib->filepath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return UI_tooltip_create_from_search_item_generic(C, region, item_rect, &tooltip_data);
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-11 17:21:27 +00:00
|
|
|
/* ID Search browse menu, open */
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *id_search_menu(bContext *C, ARegion *region, void *arg_litem)
|
2009-06-11 17:21:27 +00:00
|
|
|
{
|
2017-12-08 14:50:45 +01:00
|
|
|
static TemplateID template_ui;
|
2017-05-12 01:42:42 +02:00
|
|
|
PointerRNA active_item_ptr;
|
2020-05-07 23:16:05 +10:00
|
|
|
void (*id_search_update_fn)(
|
UI: Expose an "is first search" boolean to search button callbacks
Currently when you open an RNA collection search button, like a
vertex group selector, the search filter isn't applied until you
start typing, in order to display every option at the start.
Otherwise they wouldn't be visible, since the search filter would
run for the current text.
Currently this check happens in one place, but it relies on the
`changed` value of `uiBut`. This is fine in the interface directory,
but anywhere else it would require exposing `uiBut.changed`, which
is probably too low-level to expose.
The solution is adding an `is_first` argument to the search callbacks,
which is nice for a few reasons:
- They work at a higher level of abstraction, meaning they don't
have to worry about how exactly to tell if this is the first
search.
- It makes it easier to do special behavior when the search menu
is first opened.
- Then, obviously, it makes that state accessible without including
`interface_intern.h`.
Needed for attribute search: T85658
Differential Revision: https://developer.blender.org/D10528
2021-03-02 11:42:05 -06:00
|
|
|
const bContext *, void *, const char *, uiSearchItems *, const bool) = id_search_cb;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-11 17:21:27 +00:00
|
|
|
/* arg_litem is malloced, can be freed by parent button */
|
2017-12-08 14:50:45 +01:00
|
|
|
template_ui = *((TemplateID *)arg_litem);
|
2017-12-08 14:54:59 +01:00
|
|
|
active_item_ptr = RNA_property_pointer_get(&template_ui.ptr, template_ui.prop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-01-03 21:54:02 +11:00
|
|
|
if (template_ui.filter) {
|
|
|
|
|
/* Currently only used for objects. */
|
|
|
|
|
if (template_ui.idcode == ID_OB) {
|
|
|
|
|
if (template_ui.filter == UI_TEMPLATE_ID_FILTER_AVAILABLE) {
|
2020-05-07 23:16:05 +10:00
|
|
|
id_search_update_fn = id_search_cb_objects_from_scene;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-01-03 21:54:02 +11:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
return template_common_search_menu(C,
|
2020-03-06 16:56:42 +01:00
|
|
|
region,
|
2020-05-07 23:16:05 +10:00
|
|
|
id_search_update_fn,
|
2018-07-01 20:15:21 +02:00
|
|
|
&template_ui,
|
2020-05-08 12:01:35 +10:00
|
|
|
template_ID_set_property_exec_fn,
|
2018-07-01 20:15:21 +02:00
|
|
|
active_item_ptr.data,
|
2021-01-26 22:06:45 +01:00
|
|
|
template_ID_search_menu_item_tooltip,
|
2018-07-31 10:22:19 +02:00
|
|
|
template_ui.prv_rows,
|
|
|
|
|
template_ui.prv_cols,
|
|
|
|
|
template_ui.scale);
|
2009-06-11 17:21:27 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name ID Template
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2009-10-14 09:08:53 +00:00
|
|
|
/* This is for browsing and editing the ID-blocks used */
|
2009-06-11 17:21:27 +00:00
|
|
|
|
2009-10-01 23:32:57 +00:00
|
|
|
/* for new/open operators */
|
2016-06-24 10:05:09 +10:00
|
|
|
void UI_context_active_but_prop_get_templateID(bContext *C,
|
2018-07-10 08:34:19 +02:00
|
|
|
PointerRNA *r_ptr,
|
|
|
|
|
PropertyRNA **r_prop)
|
2009-10-01 23:32:57 +00:00
|
|
|
{
|
2018-07-03 12:15:25 +02:00
|
|
|
uiBut *but = UI_context_active_but_get(C);
|
2009-10-01 23:32:57 +00:00
|
|
|
|
2018-07-10 08:34:19 +02:00
|
|
|
memset(r_ptr, 0, sizeof(*r_ptr));
|
|
|
|
|
*r_prop = NULL;
|
2018-07-10 08:16:45 +02:00
|
|
|
|
2018-07-03 12:15:25 +02:00
|
|
|
if (but && but->func_argN) {
|
2021-02-17 16:59:50 -06:00
|
|
|
TemplateID *template_ui = but->func_argN;
|
2018-07-03 12:15:25 +02:00
|
|
|
*r_ptr = template_ui->ptr;
|
|
|
|
|
*r_prop = template_ui->prop;
|
2009-10-01 23:32:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-27 01:15:31 +00:00
|
|
|
static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
|
|
|
|
|
{
|
2017-12-08 14:50:45 +01:00
|
|
|
TemplateID *template_ui = (TemplateID *)arg_litem;
|
|
|
|
|
PointerRNA idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
|
2012-03-30 01:51:25 +00:00
|
|
|
ID *id = idptr.data;
|
2020-08-26 10:11:13 +10:00
|
|
|
const int event = POINTER_AS_INT(arg_event);
|
2020-06-24 12:51:08 +02:00
|
|
|
const char *undo_push_label = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-30 01:51:25 +00:00
|
|
|
switch (event) {
|
2009-06-27 01:15:31 +00:00
|
|
|
case UI_ID_BROWSE:
|
|
|
|
|
case UI_ID_PIN:
|
2020-07-11 15:10:05 +10:00
|
|
|
RNA_warning("warning, id event %d shouldn't come here", event);
|
2009-06-30 19:20:45 +00:00
|
|
|
break;
|
2009-06-27 01:15:31 +00:00
|
|
|
case UI_ID_OPEN:
|
|
|
|
|
case UI_ID_ADD_NEW:
|
2014-11-09 21:20:40 +01:00
|
|
|
/* these call UI_context_active_but_prop_get_templateID */
|
2009-06-27 01:15:31 +00:00
|
|
|
break;
|
|
|
|
|
case UI_ID_DELETE:
|
|
|
|
|
memset(&idptr, 0, sizeof(idptr));
|
2019-05-20 18:06:09 +10:00
|
|
|
RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
|
2017-12-08 14:50:45 +01:00
|
|
|
RNA_property_update(C, &template_ui->ptr, template_ui->prop);
|
2021-01-13 15:08:09 +01:00
|
|
|
|
|
|
|
|
if (id && CTX_wm_window(C)->eventstate->shift) {
|
|
|
|
|
/* only way to force-remove data (on save) */
|
|
|
|
|
id_us_clear_real(id);
|
|
|
|
|
id_fake_user_clear(id);
|
|
|
|
|
id->us = 0;
|
|
|
|
|
undo_push_label = "Delete Data-Block";
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-27 01:15:31 +00:00
|
|
|
break;
|
2021-01-13 15:08:09 +01:00
|
|
|
case UI_ID_FAKE_USER:
|
2012-03-24 06:38:07 +00:00
|
|
|
if (id) {
|
2021-01-13 15:08:09 +01:00
|
|
|
if (id->flag & LIB_FAKEUSER) {
|
|
|
|
|
id_us_plus(id);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
id_us_min(id);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2021-01-13 15:08:09 +01:00
|
|
|
undo_push_label = "Fake User";
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return;
|
2013-03-09 03:46:30 +00:00
|
|
|
}
|
2009-06-27 01:15:31 +00:00
|
|
|
break;
|
2021-01-13 15:08:09 +01:00
|
|
|
case UI_ID_LOCAL:
|
|
|
|
|
if (id) {
|
2016-11-30 15:25:54 +01:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2021-01-13 15:08:09 +01:00
|
|
|
if (CTX_wm_window(C)->eventstate->shift) {
|
|
|
|
|
if (ID_IS_OVERRIDABLE_LIBRARY(id)) {
|
|
|
|
|
/* Only remap that specific ID usage to overriding local data-block. */
|
|
|
|
|
ID *override_id = BKE_lib_override_library_create_from_id(bmain, id, false);
|
|
|
|
|
if (override_id != NULL) {
|
2021-05-27 22:44:02 +10:00
|
|
|
BKE_main_id_newptr_and_tag_clear(bmain);
|
2021-01-13 15:08:09 +01:00
|
|
|
|
|
|
|
|
if (GS(override_id->name) == ID_OB) {
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
if (!BKE_collection_has_object_recursive(scene->master_collection,
|
|
|
|
|
(Object *)override_id)) {
|
|
|
|
|
BKE_collection_object_add_from(
|
|
|
|
|
bmain, scene, (Object *)id, (Object *)override_id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Assign new pointer, takes care of updates/notifiers */
|
|
|
|
|
RNA_id_pointer_create(override_id, &idptr);
|
2019-09-05 20:43:52 +02:00
|
|
|
}
|
2021-01-13 15:08:09 +01:00
|
|
|
undo_push_label = "Make Library Override";
|
2017-12-18 12:29:08 +01:00
|
|
|
}
|
2021-01-13 15:08:09 +01:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (BKE_lib_id_make_local(bmain, id, false, 0)) {
|
2021-05-27 22:44:02 +10:00
|
|
|
BKE_main_id_newptr_and_tag_clear(bmain);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-13 15:08:09 +01:00
|
|
|
/* reassign to get get proper updates/notifiers */
|
|
|
|
|
idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
|
|
|
|
|
undo_push_label = "Make Local";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (undo_push_label != NULL) {
|
|
|
|
|
RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
|
|
|
|
|
RNA_property_update(C, &template_ui->ptr, template_ui->prop);
|
2020-07-13 17:43:22 +02:00
|
|
|
}
|
UI: Redesigned data-block selectors
The previous design is rather old and has a couple of problems:
* Scalability: The current solution of adding little icon buttons next to the
data-block name field doesn't scale well. It only works if there's a small
number of operations. We need to be able to place more items there for better
data-block management. Especially with the introduction of library overrides.
* Discoverability: It's not obvious what some of the icons do. They appear and
disappear, but it's not obvious why some are available at times and others
not.
* Unclear Status: Currently their library status (linked, indirectly linked,
broken link, library override) isn't really clear.
* Unusual behavior: Some of the icon buttons allow Shift or Ctrl clicking to
invoke alternative behaviors. This is not a usual pattern in Blender.
This patch does the following changes:
* Adds a menu to the right of the name button to access all kinds of operations
(create, delete, unlink, user management, library overrides, etc).
* Make good use of the "disabled hint" for tooltips, to explain why buttons are
disabled. The UI team wants to establish this as a good practise.
* Use superimposed icons for duplicate and unlink, rather than extra buttons
(uses less space, looks less distracting and is a nice + consistent design
language).
* Remove fake user and user count button, they are available from the menu now.
* Support tooltips for superimposed icons (committed mouse hover feedback to
master already).
* Slightly increase size of the name button - it was already a bit small
before, and the move from real buttons to superimposed icons reduces usable
space for the name itself.
* More clearly differentiate between duplicate and creating a new data-block.
The latter is only available in the menu.
* Display library status icon on the left (linked, missing library, overridden,
asset)
* Disables "Make Single User" button - in review we weren't sure if there are
good use-cases for it, so better to see if we can remove it.
Note that I do expect some aspects of this design to change still. I think some
changes are problematic, but others disagreed. I will open a feedback thread on
devtalk to see what others think.
Differential Revision: https://developer.blender.org/D8554
Reviewed by: Bastien Montagne
Design discussed and agreed on with the UI team, also see T79959.
2020-12-18 18:12:11 +01:00
|
|
|
}
|
|
|
|
|
break;
|
2021-01-13 15:08:09 +01:00
|
|
|
case UI_ID_OVERRIDE:
|
2020-06-30 10:52:02 +02:00
|
|
|
if (id && ID_IS_OVERRIDE_LIBRARY(id)) {
|
2020-02-10 18:05:19 +01:00
|
|
|
BKE_lib_override_library_free(&id->override_library, true);
|
2017-12-18 12:29:08 +01:00
|
|
|
/* reassign to get get proper updates/notifiers */
|
|
|
|
|
idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
|
2019-05-20 18:06:09 +10:00
|
|
|
RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
|
2017-12-18 12:29:08 +01:00
|
|
|
RNA_property_update(C, &template_ui->ptr, template_ui->prop);
|
2021-01-13 15:08:09 +01:00
|
|
|
undo_push_label = "Override Data-Block";
|
2017-12-09 09:41:00 +01:00
|
|
|
}
|
|
|
|
|
break;
|
2009-09-04 21:02:43 +00:00
|
|
|
case UI_ID_ALONE:
|
2012-03-24 06:38:07 +00:00
|
|
|
if (id) {
|
2018-07-01 19:57:31 +02:00
|
|
|
const bool do_scene_obj = ((GS(id->name) == ID_OB) &&
|
2019-03-26 14:30:45 +01:00
|
|
|
(template_ui->ptr.type == &RNA_LayerObjects));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-09-04 21:02:43 +00:00
|
|
|
/* make copy */
|
2012-03-24 06:38:07 +00:00
|
|
|
if (do_scene_obj) {
|
2013-04-24 23:09:25 +00:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2012-03-30 01:51:25 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2013-04-24 23:09:25 +00:00
|
|
|
ED_object_single_user(bmain, scene, (struct Object *)id);
|
2019-03-26 14:30:45 +01:00
|
|
|
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
2017-06-08 10:14:53 +02:00
|
|
|
DEG_relations_tag_update(bmain);
|
2011-08-08 08:22:01 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2020-03-15 21:48:35 +11:00
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
|
id_single_user(C, id, &template_ui->ptr, template_ui->prop);
|
|
|
|
|
DEG_relations_tag_update(bmain);
|
2009-09-04 21:02:43 +00:00
|
|
|
}
|
2020-06-24 12:51:08 +02:00
|
|
|
undo_push_label = "Make Single User";
|
2009-09-04 21:02:43 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
#if 0
|
2009-06-27 01:15:31 +00:00
|
|
|
case UI_ID_AUTO_NAME:
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2020-06-24 12:51:08 +02:00
|
|
|
|
|
|
|
|
if (undo_push_label != NULL) {
|
|
|
|
|
ED_undo_push(C, undo_push_label);
|
|
|
|
|
}
|
2009-06-27 01:15:31 +00:00
|
|
|
}
|
2009-06-11 17:21:27 +00:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
static const char *template_id_browse_tip(const StructRNA *type)
|
2010-12-24 10:15:57 +00:00
|
|
|
{
|
2012-03-24 06:38:07 +00:00
|
|
|
if (type) {
|
2020-09-18 11:06:41 +10:00
|
|
|
switch ((ID_Type)RNA_type_to_ID_code(type)) {
|
2011-09-19 15:10:38 +00:00
|
|
|
case ID_SCE:
|
|
|
|
|
return N_("Browse Scene to be linked");
|
2012-11-23 15:33:44 +00:00
|
|
|
case ID_OB:
|
|
|
|
|
return N_("Browse Object to be linked");
|
|
|
|
|
case ID_ME:
|
|
|
|
|
return N_("Browse Mesh Data to be linked");
|
|
|
|
|
case ID_CU:
|
|
|
|
|
return N_("Browse Curve Data to be linked");
|
|
|
|
|
case ID_MB:
|
|
|
|
|
return N_("Browse Metaball Data to be linked");
|
|
|
|
|
case ID_MA:
|
|
|
|
|
return N_("Browse Material to be linked");
|
|
|
|
|
case ID_TE:
|
|
|
|
|
return N_("Browse Texture to be linked");
|
|
|
|
|
case ID_IM:
|
|
|
|
|
return N_("Browse Image to be linked");
|
2012-11-26 02:32:34 +00:00
|
|
|
case ID_LS:
|
|
|
|
|
return N_("Browse Line Style Data to be linked");
|
2012-11-23 15:33:44 +00:00
|
|
|
case ID_LT:
|
|
|
|
|
return N_("Browse Lattice Data to be linked");
|
2018-06-27 14:41:53 +02:00
|
|
|
case ID_LA:
|
|
|
|
|
return N_("Browse Light Data to be linked");
|
2012-11-23 15:33:44 +00:00
|
|
|
case ID_CA:
|
|
|
|
|
return N_("Browse Camera Data to be linked");
|
|
|
|
|
case ID_WO:
|
|
|
|
|
return N_("Browse World Settings to be linked");
|
2014-06-22 23:47:05 +10:00
|
|
|
case ID_SCR:
|
|
|
|
|
return N_("Choose Screen layout");
|
2011-09-19 15:10:38 +00:00
|
|
|
case ID_TXT:
|
|
|
|
|
return N_("Browse Text to be linked");
|
|
|
|
|
case ID_SPK:
|
|
|
|
|
return N_("Browse Speaker Data to be linked");
|
2012-11-23 15:33:44 +00:00
|
|
|
case ID_SO:
|
|
|
|
|
return N_("Browse Sound to be linked");
|
|
|
|
|
case ID_AR:
|
|
|
|
|
return N_("Browse Armature data to be linked");
|
|
|
|
|
case ID_AC:
|
|
|
|
|
return N_("Browse Action to be linked");
|
|
|
|
|
case ID_NT:
|
|
|
|
|
return N_("Browse Node Tree to be linked");
|
|
|
|
|
case ID_BR:
|
|
|
|
|
return N_("Browse Brush to be linked");
|
2016-12-28 17:30:58 +01:00
|
|
|
case ID_PA:
|
|
|
|
|
return N_("Browse Particle Settings to be linked");
|
2012-11-23 15:33:44 +00:00
|
|
|
case ID_GD:
|
|
|
|
|
return N_("Browse Grease Pencil Data to be linked");
|
2014-12-15 11:46:25 +01:00
|
|
|
case ID_MC:
|
|
|
|
|
return N_("Browse Movie Clip to be linked");
|
|
|
|
|
case ID_MSK:
|
|
|
|
|
return N_("Browse Mask to be linked");
|
2014-07-21 12:02:05 +02:00
|
|
|
case ID_PAL:
|
|
|
|
|
return N_("Browse Palette Data to be linked");
|
|
|
|
|
case ID_PC:
|
|
|
|
|
return N_("Browse Paint Curve Data to be linked");
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
case ID_CF:
|
|
|
|
|
return N_("Browse Cache Files to be linked");
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
case ID_WS:
|
|
|
|
|
return N_("Browse Workspace to be linked");
|
2017-06-12 20:59:54 +10:00
|
|
|
case ID_LP:
|
|
|
|
|
return N_("Browse LightProbe to be linked");
|
2020-03-17 14:41:48 +01:00
|
|
|
case ID_HA:
|
|
|
|
|
return N_("Browse Hair Data to be linked");
|
|
|
|
|
case ID_PT:
|
|
|
|
|
return N_("Browse Point Cloud Data to be linked");
|
|
|
|
|
case ID_VO:
|
|
|
|
|
return N_("Browse Volume Data to be linked");
|
2020-04-20 10:37:38 +02:00
|
|
|
case ID_SIM:
|
2020-04-20 11:21:08 +02:00
|
|
|
return N_("Browse Simulation to be linked");
|
2020-09-18 11:06:41 +10:00
|
|
|
|
|
|
|
|
/* Use generic text. */
|
|
|
|
|
case ID_LI:
|
|
|
|
|
case ID_IP:
|
|
|
|
|
case ID_KE:
|
|
|
|
|
case ID_VF:
|
|
|
|
|
case ID_GR:
|
|
|
|
|
case ID_WM:
|
|
|
|
|
break;
|
2010-12-24 10:15:57 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2011-09-19 15:10:38 +00:00
|
|
|
return N_("Browse ID data to be linked");
|
2010-12-24 10:15:57 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-31 14:20:03 +10:00
|
|
|
/**
|
|
|
|
|
* \return a type-based i18n context, needed e.g. by "New" button.
|
2012-11-23 15:33:44 +00:00
|
|
|
* In most languages, this adjective takes different form based on gender of type name...
|
|
|
|
|
*/
|
2012-12-18 18:25:48 +00:00
|
|
|
#ifdef WITH_INTERNATIONAL
|
2012-11-23 15:33:44 +00:00
|
|
|
static const char *template_id_context(StructRNA *type)
|
|
|
|
|
{
|
|
|
|
|
if (type) {
|
2020-03-19 19:37:00 +01:00
|
|
|
return BKE_idtype_idcode_to_translation_context(RNA_type_to_ID_code(type));
|
2012-11-23 15:33:44 +00:00
|
|
|
}
|
2015-08-16 17:32:01 +10:00
|
|
|
return BLT_I18NCONTEXT_DEFAULT;
|
2012-11-23 15:33:44 +00:00
|
|
|
}
|
2020-05-07 08:58:41 +10:00
|
|
|
#else
|
|
|
|
|
# define template_id_context(type) 0
|
2012-12-18 18:25:48 +00:00
|
|
|
#endif
|
2012-11-23 15:33:44 +00:00
|
|
|
|
2021-01-13 15:08:09 +01:00
|
|
|
static uiBut *template_id_def_new_but(uiBlock *block,
|
|
|
|
|
const ID *id,
|
|
|
|
|
const TemplateID *template_ui,
|
|
|
|
|
StructRNA *type,
|
|
|
|
|
const char *const newop,
|
|
|
|
|
const bool editable,
|
|
|
|
|
const bool id_open,
|
|
|
|
|
const bool use_tab_but,
|
|
|
|
|
int but_height)
|
UI: Redesigned data-block selectors
The previous design is rather old and has a couple of problems:
* Scalability: The current solution of adding little icon buttons next to the
data-block name field doesn't scale well. It only works if there's a small
number of operations. We need to be able to place more items there for better
data-block management. Especially with the introduction of library overrides.
* Discoverability: It's not obvious what some of the icons do. They appear and
disappear, but it's not obvious why some are available at times and others
not.
* Unclear Status: Currently their library status (linked, indirectly linked,
broken link, library override) isn't really clear.
* Unusual behavior: Some of the icon buttons allow Shift or Ctrl clicking to
invoke alternative behaviors. This is not a usual pattern in Blender.
This patch does the following changes:
* Adds a menu to the right of the name button to access all kinds of operations
(create, delete, unlink, user management, library overrides, etc).
* Make good use of the "disabled hint" for tooltips, to explain why buttons are
disabled. The UI team wants to establish this as a good practise.
* Use superimposed icons for duplicate and unlink, rather than extra buttons
(uses less space, looks less distracting and is a nice + consistent design
language).
* Remove fake user and user count button, they are available from the menu now.
* Support tooltips for superimposed icons (committed mouse hover feedback to
master already).
* Slightly increase size of the name button - it was already a bit small
before, and the move from real buttons to superimposed icons reduces usable
space for the name itself.
* More clearly differentiate between duplicate and creating a new data-block.
The latter is only available in the menu.
* Display library status icon on the left (linked, missing library, overridden,
asset)
* Disables "Make Single User" button - in review we weren't sure if there are
good use-cases for it, so better to see if we can remove it.
Note that I do expect some aspects of this design to change still. I think some
changes are problematic, but others disagreed. I will open a feedback thread on
devtalk to see what others think.
Differential Revision: https://developer.blender.org/D8554
Reviewed by: Bastien Montagne
Design discussed and agreed on with the UI team, also see T79959.
2020-12-18 18:12:11 +01:00
|
|
|
{
|
2021-01-13 15:08:09 +01:00
|
|
|
ID *idfrom = template_ui->ptr.owner_id;
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
uiBut *but;
|
|
|
|
|
const int w = id ? UI_UNIT_X : id_open ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
|
|
|
|
|
const int but_type = use_tab_but ? UI_BTYPE_TAB : UI_BTYPE_BUT;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
/* i18n markup, does nothing! */
|
2018-07-01 20:15:21 +02:00
|
|
|
BLT_I18N_MSGID_MULTI_CTXT("New",
|
|
|
|
|
BLT_I18NCONTEXT_DEFAULT,
|
|
|
|
|
BLT_I18NCONTEXT_ID_SCENE,
|
|
|
|
|
BLT_I18NCONTEXT_ID_OBJECT,
|
|
|
|
|
BLT_I18NCONTEXT_ID_MESH,
|
|
|
|
|
BLT_I18NCONTEXT_ID_CURVE,
|
|
|
|
|
BLT_I18NCONTEXT_ID_METABALL,
|
|
|
|
|
BLT_I18NCONTEXT_ID_MATERIAL,
|
|
|
|
|
BLT_I18NCONTEXT_ID_TEXTURE,
|
|
|
|
|
BLT_I18NCONTEXT_ID_IMAGE,
|
|
|
|
|
BLT_I18NCONTEXT_ID_LATTICE,
|
2019-02-12 21:51:51 +01:00
|
|
|
BLT_I18NCONTEXT_ID_LIGHT,
|
2018-07-01 20:15:21 +02:00
|
|
|
BLT_I18NCONTEXT_ID_CAMERA,
|
|
|
|
|
BLT_I18NCONTEXT_ID_WORLD,
|
|
|
|
|
BLT_I18NCONTEXT_ID_SCREEN,
|
|
|
|
|
BLT_I18NCONTEXT_ID_TEXT, );
|
|
|
|
|
BLT_I18N_MSGID_MULTI_CTXT("New",
|
|
|
|
|
BLT_I18NCONTEXT_ID_SPEAKER,
|
|
|
|
|
BLT_I18NCONTEXT_ID_SOUND,
|
|
|
|
|
BLT_I18NCONTEXT_ID_ARMATURE,
|
|
|
|
|
BLT_I18NCONTEXT_ID_ACTION,
|
|
|
|
|
BLT_I18NCONTEXT_ID_NODETREE,
|
|
|
|
|
BLT_I18NCONTEXT_ID_BRUSH,
|
|
|
|
|
BLT_I18NCONTEXT_ID_PARTICLESETTINGS,
|
|
|
|
|
BLT_I18NCONTEXT_ID_GPENCIL,
|
|
|
|
|
BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE,
|
2019-02-12 22:13:42 +01:00
|
|
|
BLT_I18NCONTEXT_ID_WORKSPACE,
|
2020-03-17 14:41:48 +01:00
|
|
|
BLT_I18NCONTEXT_ID_LIGHTPROBE,
|
|
|
|
|
BLT_I18NCONTEXT_ID_HAIR,
|
|
|
|
|
BLT_I18NCONTEXT_ID_POINTCLOUD,
|
2020-04-20 10:37:38 +02:00
|
|
|
BLT_I18NCONTEXT_ID_VOLUME,
|
|
|
|
|
BLT_I18NCONTEXT_ID_SIMULATION, );
|
2020-03-17 14:41:48 +01:00
|
|
|
/* Note: BLT_I18N_MSGID_MULTI_CTXT takes a maximum number of parameters,
|
|
|
|
|
* check the definition to see if a new call must be added when the limit
|
|
|
|
|
* is exceeded. */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-13 15:08:09 +01:00
|
|
|
if (newop) {
|
2018-07-01 20:15:21 +02:00
|
|
|
but = uiDefIconTextButO(block,
|
2021-01-13 15:08:09 +01:00
|
|
|
but_type,
|
|
|
|
|
newop,
|
2018-07-01 20:15:21 +02:00
|
|
|
WM_OP_INVOKE_DEFAULT,
|
2021-01-13 15:08:09 +01:00
|
|
|
(id && !use_tab_but) ? ICON_DUPLICATE : ICON_ADD,
|
|
|
|
|
(id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
|
2018-07-01 20:15:21 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
w,
|
2021-01-13 15:08:09 +01:00
|
|
|
but_height,
|
2018-07-01 20:15:21 +02:00
|
|
|
NULL);
|
2018-09-19 12:14:36 +10:00
|
|
|
UI_but_funcN_set(
|
2021-01-13 15:08:09 +01:00
|
|
|
but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ADD_NEW));
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2018-07-01 20:15:21 +02:00
|
|
|
but = uiDefIconTextBut(block,
|
2021-01-13 15:08:09 +01:00
|
|
|
but_type,
|
2018-10-31 18:30:30 +01:00
|
|
|
0,
|
2021-01-13 15:08:09 +01:00
|
|
|
(id && !use_tab_but) ? ICON_DUPLICATE : ICON_ADD,
|
|
|
|
|
(id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
|
2018-07-01 20:15:21 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
w,
|
2021-01-13 15:08:09 +01:00
|
|
|
but_height,
|
2018-07-01 20:15:21 +02:00
|
|
|
NULL,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
NULL);
|
2021-01-13 15:08:09 +01:00
|
|
|
UI_but_funcN_set(
|
|
|
|
|
but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ADD_NEW));
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-13 15:08:09 +01:00
|
|
|
if ((idfrom && idfrom->lib) || !editable) {
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
|
|
|
|
}
|
UI: Redesigned data-block selectors
The previous design is rather old and has a couple of problems:
* Scalability: The current solution of adding little icon buttons next to the
data-block name field doesn't scale well. It only works if there's a small
number of operations. We need to be able to place more items there for better
data-block management. Especially with the introduction of library overrides.
* Discoverability: It's not obvious what some of the icons do. They appear and
disappear, but it's not obvious why some are available at times and others
not.
* Unclear Status: Currently their library status (linked, indirectly linked,
broken link, library override) isn't really clear.
* Unusual behavior: Some of the icon buttons allow Shift or Ctrl clicking to
invoke alternative behaviors. This is not a usual pattern in Blender.
This patch does the following changes:
* Adds a menu to the right of the name button to access all kinds of operations
(create, delete, unlink, user management, library overrides, etc).
* Make good use of the "disabled hint" for tooltips, to explain why buttons are
disabled. The UI team wants to establish this as a good practise.
* Use superimposed icons for duplicate and unlink, rather than extra buttons
(uses less space, looks less distracting and is a nice + consistent design
language).
* Remove fake user and user count button, they are available from the menu now.
* Support tooltips for superimposed icons (committed mouse hover feedback to
master already).
* Slightly increase size of the name button - it was already a bit small
before, and the move from real buttons to superimposed icons reduces usable
space for the name itself.
* More clearly differentiate between duplicate and creating a new data-block.
The latter is only available in the menu.
* Display library status icon on the left (linked, missing library, overridden,
asset)
* Disables "Make Single User" button - in review we weren't sure if there are
good use-cases for it, so better to see if we can remove it.
Note that I do expect some aspects of this design to change still. I think some
changes are problematic, but others disagreed. I will open a feedback thread on
devtalk to see what others think.
Differential Revision: https://developer.blender.org/D8554
Reviewed by: Bastien Montagne
Design discussed and agreed on with the UI team, also see T79959.
2020-12-18 18:12:11 +01:00
|
|
|
|
2021-01-13 15:08:09 +01:00
|
|
|
#ifndef WITH_INTERNATIONAL
|
|
|
|
|
UNUSED_VARS(type);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
#endif
|
UI: Redesigned data-block selectors
The previous design is rather old and has a couple of problems:
* Scalability: The current solution of adding little icon buttons next to the
data-block name field doesn't scale well. It only works if there's a small
number of operations. We need to be able to place more items there for better
data-block management. Especially with the introduction of library overrides.
* Discoverability: It's not obvious what some of the icons do. They appear and
disappear, but it's not obvious why some are available at times and others
not.
* Unclear Status: Currently their library status (linked, indirectly linked,
broken link, library override) isn't really clear.
* Unusual behavior: Some of the icon buttons allow Shift or Ctrl clicking to
invoke alternative behaviors. This is not a usual pattern in Blender.
This patch does the following changes:
* Adds a menu to the right of the name button to access all kinds of operations
(create, delete, unlink, user management, library overrides, etc).
* Make good use of the "disabled hint" for tooltips, to explain why buttons are
disabled. The UI team wants to establish this as a good practise.
* Use superimposed icons for duplicate and unlink, rather than extra buttons
(uses less space, looks less distracting and is a nice + consistent design
language).
* Remove fake user and user count button, they are available from the menu now.
* Support tooltips for superimposed icons (committed mouse hover feedback to
master already).
* Slightly increase size of the name button - it was already a bit small
before, and the move from real buttons to superimposed icons reduces usable
space for the name itself.
* More clearly differentiate between duplicate and creating a new data-block.
The latter is only available in the menu.
* Display library status icon on the left (linked, missing library, overridden,
asset)
* Disables "Make Single User" button - in review we weren't sure if there are
good use-cases for it, so better to see if we can remove it.
Note that I do expect some aspects of this design to change still. I think some
changes are problematic, but others disagreed. I will open a feedback thread on
devtalk to see what others think.
Differential Revision: https://developer.blender.org/D8554
Reviewed by: Bastien Montagne
Design discussed and agreed on with the UI team, also see T79959.
2020-12-18 18:12:11 +01:00
|
|
|
|
2021-01-13 15:08:09 +01:00
|
|
|
return but;
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
|
|
|
|
|
2020-06-02 14:09:01 -04:00
|
|
|
static void template_ID(const bContext *C,
|
2018-01-03 21:54:02 +11:00
|
|
|
uiLayout *layout,
|
|
|
|
|
TemplateID *template_ui,
|
|
|
|
|
StructRNA *type,
|
|
|
|
|
int flag,
|
2021-01-13 15:08:09 +01:00
|
|
|
const char *newop,
|
|
|
|
|
const char *openop,
|
|
|
|
|
const char *unlinkop,
|
2019-11-25 19:41:30 +01:00
|
|
|
const char *text,
|
2018-11-02 17:30:09 +01:00
|
|
|
const bool live_icon,
|
|
|
|
|
const bool hide_buttons)
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
{
|
|
|
|
|
uiBut *but;
|
2017-12-08 14:36:07 +01:00
|
|
|
const bool editable = RNA_property_editable(&template_ui->ptr, template_ui->prop);
|
2017-12-08 14:39:17 +01:00
|
|
|
const bool use_previews = template_ui->preview = (flag & UI_ID_PREVIEWS) != 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-17 16:59:50 -06:00
|
|
|
PointerRNA idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
|
|
|
|
|
ID *id = idptr.data;
|
|
|
|
|
ID *idfrom = template_ui->ptr.owner_id;
|
2021-01-13 15:08:09 +01:00
|
|
|
// lb = template_ui->idlb;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-05 16:23:34 +11:00
|
|
|
/* Allow operators to take the ID from context. */
|
2020-12-11 22:20:31 +01:00
|
|
|
uiLayoutSetContextPointer(layout, "id", &idptr);
|
|
|
|
|
|
2021-02-17 16:59:50 -06:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_begin(block);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (idptr.type) {
|
2012-03-30 01:51:25 +00:00
|
|
|
type = idptr.type;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-11-25 19:41:30 +01:00
|
|
|
if (text) {
|
2021-02-05 16:23:34 +11:00
|
|
|
/* Add label respecting the separated layout property split state. */
|
2020-04-05 14:19:24 +02:00
|
|
|
uiItemL_respect_property_split(layout, text, ICON_NONE);
|
2019-11-25 19:41:30 +01:00
|
|
|
}
|
|
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
if (flag & UI_ID_BROWSE) {
|
|
|
|
|
template_add_button_search_menu(C,
|
2017-12-08 14:39:17 +01:00
|
|
|
layout,
|
|
|
|
|
block,
|
|
|
|
|
&template_ui->ptr,
|
|
|
|
|
template_ui->prop,
|
|
|
|
|
id_search_menu,
|
|
|
|
|
MEM_dupallocN(template_ui),
|
|
|
|
|
TIP_(template_id_browse_tip(type)),
|
2018-07-31 10:22:19 +02:00
|
|
|
use_previews,
|
|
|
|
|
editable,
|
|
|
|
|
live_icon);
|
2009-07-09 19:45:27 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
/* text button with name */
|
2012-03-24 06:38:07 +00:00
|
|
|
if (id) {
|
2021-01-13 15:08:09 +01:00
|
|
|
char name[UI_MAX_NAME_STR];
|
|
|
|
|
const bool user_alert = (id->us <= 0);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-03-18 15:00:55 +01:00
|
|
|
const int width = template_search_textbut_width(&idptr,
|
|
|
|
|
RNA_struct_find_property(&idptr, "name"));
|
|
|
|
|
const int height = template_search_textbut_height();
|
|
|
|
|
|
2021-01-13 15:08:09 +01:00
|
|
|
// text_idbutton(id, name);
|
|
|
|
|
name[0] = '\0';
|
|
|
|
|
but = uiDefButR(block,
|
|
|
|
|
UI_BTYPE_TEXT,
|
|
|
|
|
0,
|
|
|
|
|
name,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2021-03-18 15:00:55 +01:00
|
|
|
width,
|
|
|
|
|
height,
|
2021-01-13 15:08:09 +01:00
|
|
|
&idptr,
|
|
|
|
|
"name",
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
-1,
|
|
|
|
|
RNA_struct_ui_description(type));
|
|
|
|
|
UI_but_funcN_set(
|
|
|
|
|
but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_RENAME));
|
|
|
|
|
if (user_alert) {
|
|
|
|
|
UI_but_flag_enable(but, UI_BUT_REDALERT);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-13 15:08:09 +01:00
|
|
|
if (id->lib) {
|
|
|
|
|
if (id->tag & LIB_TAG_INDIRECT) {
|
|
|
|
|
but = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_LIBRARY_DATA_INDIRECT,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
UI: Redesigned data-block selectors
The previous design is rather old and has a couple of problems:
* Scalability: The current solution of adding little icon buttons next to the
data-block name field doesn't scale well. It only works if there's a small
number of operations. We need to be able to place more items there for better
data-block management. Especially with the introduction of library overrides.
* Discoverability: It's not obvious what some of the icons do. They appear and
disappear, but it's not obvious why some are available at times and others
not.
* Unclear Status: Currently their library status (linked, indirectly linked,
broken link, library override) isn't really clear.
* Unusual behavior: Some of the icon buttons allow Shift or Ctrl clicking to
invoke alternative behaviors. This is not a usual pattern in Blender.
This patch does the following changes:
* Adds a menu to the right of the name button to access all kinds of operations
(create, delete, unlink, user management, library overrides, etc).
* Make good use of the "disabled hint" for tooltips, to explain why buttons are
disabled. The UI team wants to establish this as a good practise.
* Use superimposed icons for duplicate and unlink, rather than extra buttons
(uses less space, looks less distracting and is a nice + consistent design
language).
* Remove fake user and user count button, they are available from the menu now.
* Support tooltips for superimposed icons (committed mouse hover feedback to
master already).
* Slightly increase size of the name button - it was already a bit small
before, and the move from real buttons to superimposed icons reduces usable
space for the name itself.
* More clearly differentiate between duplicate and creating a new data-block.
The latter is only available in the menu.
* Display library status icon on the left (linked, missing library, overridden,
asset)
* Disables "Make Single User" button - in review we weren't sure if there are
good use-cases for it, so better to see if we can remove it.
Note that I do expect some aspects of this design to change still. I think some
changes are problematic, but others disagreed. I will open a feedback thread on
devtalk to see what others think.
Differential Revision: https://developer.blender.org/D8554
Reviewed by: Bastien Montagne
Design discussed and agreed on with the UI team, also see T79959.
2020-12-18 18:12:11 +01:00
|
|
|
NULL,
|
2021-01-13 15:08:09 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
TIP_("Indirect library data-block, cannot change"));
|
|
|
|
|
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
const bool disabled = (!BKE_lib_id_make_local(CTX_data_main(C), id, true /* test */, 0) ||
|
|
|
|
|
(idfrom && idfrom->lib));
|
|
|
|
|
but = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_LIBRARY_DATA_DIRECT,
|
UI: Redesigned data-block selectors
The previous design is rather old and has a couple of problems:
* Scalability: The current solution of adding little icon buttons next to the
data-block name field doesn't scale well. It only works if there's a small
number of operations. We need to be able to place more items there for better
data-block management. Especially with the introduction of library overrides.
* Discoverability: It's not obvious what some of the icons do. They appear and
disappear, but it's not obvious why some are available at times and others
not.
* Unclear Status: Currently their library status (linked, indirectly linked,
broken link, library override) isn't really clear.
* Unusual behavior: Some of the icon buttons allow Shift or Ctrl clicking to
invoke alternative behaviors. This is not a usual pattern in Blender.
This patch does the following changes:
* Adds a menu to the right of the name button to access all kinds of operations
(create, delete, unlink, user management, library overrides, etc).
* Make good use of the "disabled hint" for tooltips, to explain why buttons are
disabled. The UI team wants to establish this as a good practise.
* Use superimposed icons for duplicate and unlink, rather than extra buttons
(uses less space, looks less distracting and is a nice + consistent design
language).
* Remove fake user and user count button, they are available from the menu now.
* Support tooltips for superimposed icons (committed mouse hover feedback to
master already).
* Slightly increase size of the name button - it was already a bit small
before, and the move from real buttons to superimposed icons reduces usable
space for the name itself.
* More clearly differentiate between duplicate and creating a new data-block.
The latter is only available in the menu.
* Display library status icon on the left (linked, missing library, overridden,
asset)
* Disables "Make Single User" button - in review we weren't sure if there are
good use-cases for it, so better to see if we can remove it.
Note that I do expect some aspects of this design to change still. I think some
changes are problematic, but others disagreed. I will open a feedback thread on
devtalk to see what others think.
Differential Revision: https://developer.blender.org/D8554
Reviewed by: Bastien Montagne
Design discussed and agreed on with the UI team, also see T79959.
2020-12-18 18:12:11 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
2021-01-13 15:08:09 +01:00
|
|
|
NULL,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
TIP_("Direct linked library data-block, click to make local, "
|
|
|
|
|
"Shift + Click to create a library override"));
|
|
|
|
|
if (disabled) {
|
|
|
|
|
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
UI_but_funcN_set(
|
|
|
|
|
but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_LOCAL));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (ID_IS_OVERRIDE_LIBRARY(id)) {
|
|
|
|
|
but = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_LIBRARY_DATA_OVERRIDE,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
TIP_("Library override of linked data-block, click to make fully local"));
|
|
|
|
|
UI_but_funcN_set(
|
|
|
|
|
but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OVERRIDE));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((ID_REAL_USERS(id) > 1) && (hide_buttons == false)) {
|
|
|
|
|
char numstr[32];
|
|
|
|
|
short numstr_len;
|
|
|
|
|
|
2021-05-27 17:16:08 +10:00
|
|
|
numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", ID_REAL_USERS(id));
|
2021-01-13 15:08:09 +01:00
|
|
|
|
|
|
|
|
but = uiDefBut(
|
|
|
|
|
block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
numstr,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
numstr_len * 0.2f * UI_UNIT_X + UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
TIP_("Display number of users of this data (click to make a single-user copy)"));
|
|
|
|
|
but->flag |= UI_BUT_UNDO;
|
|
|
|
|
|
|
|
|
|
UI_but_funcN_set(
|
|
|
|
|
but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ALONE));
|
|
|
|
|
if ((!BKE_id_copy_is_allowed(id)) || (idfrom && idfrom->lib) || (!editable) ||
|
|
|
|
|
/* object in editmode - don't change data */
|
|
|
|
|
(idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT))) {
|
|
|
|
|
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (user_alert) {
|
|
|
|
|
UI_but_flag_enable(but, UI_BUT_REDALERT);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-04 14:46:32 +02:00
|
|
|
if (id->lib == NULL && !(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_OB, ID_WS)) &&
|
2021-01-13 15:08:09 +01:00
|
|
|
(hide_buttons == false)) {
|
|
|
|
|
uiDefIconButR(block,
|
|
|
|
|
UI_BTYPE_ICON_TOGGLE,
|
|
|
|
|
0,
|
|
|
|
|
ICON_FAKE_USER_OFF,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
&idptr,
|
|
|
|
|
"use_fake_user",
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
-1,
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((flag & UI_ID_ADD_NEW) && (hide_buttons == false)) {
|
|
|
|
|
template_id_def_new_but(
|
|
|
|
|
block, id, template_ui, type, newop, editable, flag & UI_ID_OPEN, false, UI_UNIT_X);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Due to space limit in UI - skip the "open" icon for packed data, and allow to unpack.
|
|
|
|
|
* Only for images, sound and fonts */
|
|
|
|
|
if (id && BKE_packedfile_id_check(id)) {
|
|
|
|
|
but = uiDefIconButO(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
"FILE_OT_unpack_item",
|
|
|
|
|
WM_OP_INVOKE_REGION_WIN,
|
|
|
|
|
ICON_PACKAGE,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
TIP_("Packed File, click to unpack"));
|
|
|
|
|
UI_but_operator_ptr_get(but);
|
|
|
|
|
|
|
|
|
|
RNA_string_set(but->opptr, "id_name", id->name + 2);
|
|
|
|
|
RNA_int_set(but->opptr, "id_type", GS(id->name));
|
|
|
|
|
}
|
|
|
|
|
else if (flag & UI_ID_OPEN) {
|
|
|
|
|
const int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
|
|
|
|
|
|
|
|
|
|
if (openop) {
|
|
|
|
|
but = uiDefIconTextButO(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
openop,
|
|
|
|
|
WM_OP_INVOKE_DEFAULT,
|
|
|
|
|
ICON_FILEBROWSER,
|
|
|
|
|
(id) ? "" : IFACE_("Open"),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
w,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL);
|
|
|
|
|
UI_but_funcN_set(
|
|
|
|
|
but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OPEN));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
but = uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_FILEBROWSER,
|
|
|
|
|
(id) ? "" : IFACE_("Open"),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
w,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
NULL);
|
|
|
|
|
UI_but_funcN_set(
|
|
|
|
|
but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OPEN));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((idfrom && idfrom->lib) || !editable) {
|
|
|
|
|
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* delete button */
|
|
|
|
|
/* don't use RNA_property_is_unlink here */
|
|
|
|
|
if (id && (flag & UI_ID_DELETE) && (hide_buttons == false)) {
|
|
|
|
|
/* allow unlink if 'unlinkop' is passed, even when 'PROP_NEVER_UNLINK' is set */
|
|
|
|
|
but = NULL;
|
|
|
|
|
|
|
|
|
|
if (unlinkop) {
|
|
|
|
|
but = uiDefIconButO(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
unlinkop,
|
|
|
|
|
WM_OP_INVOKE_DEFAULT,
|
|
|
|
|
ICON_X,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL);
|
|
|
|
|
/* so we can access the template from operators, font unlinking needs this */
|
|
|
|
|
UI_but_funcN_set(but, NULL, MEM_dupallocN(template_ui), NULL);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if ((RNA_property_flag(template_ui->prop) & PROP_NEVER_UNLINK) == 0) {
|
|
|
|
|
but = uiDefIconBut(
|
|
|
|
|
block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_X,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
TIP_("Unlink data-block "
|
|
|
|
|
"(Shift + Click to set users to zero, data will then not be saved)"));
|
|
|
|
|
UI_but_funcN_set(
|
|
|
|
|
but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_DELETE));
|
|
|
|
|
|
|
|
|
|
if (RNA_property_flag(template_ui->prop) & PROP_NEVER_NULL) {
|
|
|
|
|
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (but) {
|
|
|
|
|
if ((idfrom && idfrom->lib) || !editable) {
|
|
|
|
|
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2021-01-13 15:08:09 +01:00
|
|
|
if (template_ui->idcode == ID_TE) {
|
|
|
|
|
uiTemplateTextureShow(layout, C, &template_ui->ptr, template_ui->prop);
|
|
|
|
|
}
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_end(block);
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
}
|
|
|
|
|
|
2018-08-23 19:58:54 +02:00
|
|
|
ID *UI_context_active_but_get_tab_ID(bContext *C)
|
|
|
|
|
{
|
|
|
|
|
uiBut *but = UI_context_active_but_get(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-08-23 19:58:54 +02:00
|
|
|
if (but && but->type == UI_BTYPE_TAB) {
|
|
|
|
|
return but->custom_data;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
return NULL;
|
2018-08-23 19:58:54 +02:00
|
|
|
}
|
|
|
|
|
|
2020-06-02 14:09:01 -04:00
|
|
|
static void template_ID_tabs(const bContext *C,
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
uiLayout *layout,
|
|
|
|
|
TemplateID *template,
|
|
|
|
|
StructRNA *type,
|
|
|
|
|
int flag,
|
2021-01-13 15:08:09 +01:00
|
|
|
const char *newop,
|
2018-08-28 15:12:14 +02:00
|
|
|
const char *menu)
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
{
|
|
|
|
|
const ARegion *region = CTX_wm_region(C);
|
|
|
|
|
const PointerRNA active_ptr = RNA_property_pointer_get(&template->ptr, template->prop);
|
2020-05-26 12:56:53 +02:00
|
|
|
MenuType *mt = menu ? WM_menutype_find(menu, false) : NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-10-29 21:20:58 +01:00
|
|
|
const int but_align = ui_but_align_opposite_to_area_align_get(region);
|
2018-04-21 10:06:12 +02:00
|
|
|
const int but_height = UI_UNIT_Y * 1.1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2020-03-15 17:32:25 +11:00
|
|
|
const uiStyle *style = UI_style_get_dpi();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-08-23 16:13:52 +02:00
|
|
|
ListBase ordered;
|
|
|
|
|
BKE_id_ordered_list(&ordered, template->idlb);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-03 19:15:01 +02:00
|
|
|
LISTBASE_FOREACH (LinkData *, link, &ordered) {
|
2018-08-23 16:13:52 +02:00
|
|
|
ID *id = link->data;
|
2020-10-07 08:59:13 -07:00
|
|
|
const int name_width = UI_fontstyle_string_width(&style->widget, id->name + 2);
|
2018-08-23 19:58:54 +02:00
|
|
|
const int but_width = name_width + UI_UNIT_X;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-08-23 19:58:54 +02:00
|
|
|
uiButTab *tab = (uiButTab *)uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_TAB,
|
|
|
|
|
0,
|
|
|
|
|
id->name + 2,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
but_width,
|
|
|
|
|
but_height,
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
&template->ptr,
|
|
|
|
|
template->prop,
|
|
|
|
|
0,
|
|
|
|
|
0.0f,
|
|
|
|
|
sizeof(id->name) - 2,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
"");
|
2020-05-08 12:01:35 +10:00
|
|
|
UI_but_funcN_set(&tab->but, template_ID_set_property_exec_fn, MEM_dupallocN(template), id);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
tab->but.custom_data = (void *)id;
|
2018-08-23 16:13:52 +02:00
|
|
|
tab->but.dragpoin = id;
|
2018-08-23 19:58:54 +02:00
|
|
|
tab->menu = mt;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
UI_but_drawflag_enable(&tab->but, but_align);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-08-23 16:13:52 +02:00
|
|
|
BLI_freelistN(&ordered);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
if (flag & UI_ID_ADD_NEW) {
|
2021-01-13 15:08:09 +01:00
|
|
|
const bool editable = RNA_property_editable(&template->ptr, template->prop);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
uiBut *but;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
if (active_ptr.type) {
|
|
|
|
|
type = active_ptr.type;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-13 15:08:09 +01:00
|
|
|
but = template_id_def_new_but(block,
|
|
|
|
|
active_ptr.data,
|
|
|
|
|
template,
|
|
|
|
|
type,
|
|
|
|
|
newop,
|
|
|
|
|
editable,
|
|
|
|
|
flag & UI_ID_OPEN,
|
|
|
|
|
true,
|
|
|
|
|
but_height);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
UI_but_drawflag_enable(but, but_align);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-05 03:13:47 +10:00
|
|
|
static void ui_template_id(uiLayout *layout,
|
2020-06-02 14:09:01 -04:00
|
|
|
const bContext *C,
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
const char *newop,
|
|
|
|
|
const char *openop,
|
|
|
|
|
const char *unlinkop,
|
2020-05-26 13:24:28 +02:00
|
|
|
/* Only respected by tabs (use_tabs). */
|
|
|
|
|
const char *menu,
|
2019-11-25 19:41:30 +01:00
|
|
|
const char *text,
|
2018-07-31 10:22:19 +02:00
|
|
|
int flag,
|
|
|
|
|
int prv_rows,
|
|
|
|
|
int prv_cols,
|
|
|
|
|
int filter,
|
|
|
|
|
bool use_tabs,
|
2018-11-02 17:30:09 +01:00
|
|
|
float scale,
|
|
|
|
|
const bool live_icon,
|
|
|
|
|
const bool hide_buttons)
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
{
|
2021-02-17 16:59:50 -06:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!prop || RNA_property_type(prop) != PROP_POINTER) {
|
2011-09-09 01:29:53 +00:00
|
|
|
RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-17 16:59:50 -06:00
|
|
|
TemplateID *template_ui = MEM_callocN(sizeof(TemplateID), "TemplateID");
|
2017-12-08 14:36:07 +01:00
|
|
|
template_ui->ptr = *ptr;
|
|
|
|
|
template_ui->prop = prop;
|
|
|
|
|
template_ui->prv_rows = prv_rows;
|
|
|
|
|
template_ui->prv_cols = prv_cols;
|
2018-07-31 10:22:19 +02:00
|
|
|
template_ui->scale = scale;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-01-03 21:54:02 +11:00
|
|
|
if ((flag & UI_ID_PIN) == 0) {
|
|
|
|
|
template_ui->filter = filter;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
template_ui->filter = 0;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-13 15:08:09 +01:00
|
|
|
if (newop) {
|
2009-06-27 01:15:31 +00:00
|
|
|
flag |= UI_ID_ADD_NEW;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
if (openop) {
|
2009-09-04 21:02:43 +00:00
|
|
|
flag |= UI_ID_OPEN;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-17 16:59:50 -06:00
|
|
|
StructRNA *type = RNA_property_pointer_type(ptr, prop);
|
|
|
|
|
short idcode = RNA_type_to_ID_code(type);
|
2018-01-03 21:54:02 +11:00
|
|
|
template_ui->idcode = idcode;
|
2017-12-08 14:36:07 +01:00
|
|
|
template_ui->idlb = which_libbase(CTX_data_main(C), idcode);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-10-14 09:08:53 +00:00
|
|
|
/* create UI elements for this template
|
2018-11-14 12:53:15 +11:00
|
|
|
* - template_ID makes a copy of the template data and assigns it to the relevant buttons
|
2009-10-14 09:08:53 +00:00
|
|
|
*/
|
2017-12-08 14:36:07 +01:00
|
|
|
if (template_ui->idlb) {
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
if (use_tabs) {
|
2019-11-25 19:41:30 +01:00
|
|
|
layout = uiLayoutRow(layout, true);
|
2021-01-13 15:08:09 +01:00
|
|
|
template_ID_tabs(C, layout, template_ui, type, flag, newop, menu);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2019-11-25 19:41:30 +01:00
|
|
|
layout = uiLayoutRow(layout, true);
|
2021-01-13 15:08:09 +01:00
|
|
|
template_ID(C,
|
|
|
|
|
layout,
|
|
|
|
|
template_ui,
|
|
|
|
|
type,
|
|
|
|
|
flag,
|
|
|
|
|
newop,
|
|
|
|
|
openop,
|
|
|
|
|
unlinkop,
|
|
|
|
|
text,
|
|
|
|
|
live_icon,
|
|
|
|
|
hide_buttons);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
2009-06-07 13:20:41 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-12-08 14:36:07 +01:00
|
|
|
MEM_freeN(template_ui);
|
2010-01-03 08:37:18 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-05 03:13:47 +10:00
|
|
|
void uiTemplateID(uiLayout *layout,
|
2020-06-02 14:09:01 -04:00
|
|
|
const bContext *C,
|
2015-05-05 03:13:47 +10:00
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
const char *newop,
|
2018-07-31 10:22:19 +02:00
|
|
|
const char *openop,
|
|
|
|
|
const char *unlinkop,
|
2018-07-31 20:11:55 +10:00
|
|
|
int filter,
|
2019-11-25 19:41:30 +01:00
|
|
|
const bool live_icon,
|
|
|
|
|
const char *text)
|
2010-01-03 08:37:18 +00:00
|
|
|
{
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
ui_template_id(layout,
|
|
|
|
|
C,
|
|
|
|
|
ptr,
|
|
|
|
|
propname,
|
|
|
|
|
newop,
|
|
|
|
|
openop,
|
|
|
|
|
unlinkop,
|
2020-05-26 13:24:28 +02:00
|
|
|
NULL,
|
2019-11-25 19:41:30 +01:00
|
|
|
text,
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE,
|
2018-11-02 17:30:09 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
filter,
|
|
|
|
|
false,
|
|
|
|
|
1.0f,
|
|
|
|
|
live_icon,
|
|
|
|
|
false);
|
2010-01-13 06:35:12 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-05 03:13:47 +10:00
|
|
|
void uiTemplateIDBrowse(uiLayout *layout,
|
|
|
|
|
bContext *C,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
const char *newop,
|
2018-01-03 21:54:02 +11:00
|
|
|
const char *openop,
|
|
|
|
|
const char *unlinkop,
|
2019-11-25 19:41:30 +01:00
|
|
|
int filter,
|
|
|
|
|
const char *text)
|
2010-01-13 06:35:12 +00:00
|
|
|
{
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
ui_template_id(layout,
|
|
|
|
|
C,
|
|
|
|
|
ptr,
|
|
|
|
|
propname,
|
|
|
|
|
newop,
|
|
|
|
|
openop,
|
|
|
|
|
unlinkop,
|
2020-05-26 13:24:28 +02:00
|
|
|
NULL,
|
2019-11-25 19:41:30 +01:00
|
|
|
text,
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
UI_ID_BROWSE | UI_ID_RENAME,
|
2018-11-02 17:30:09 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
filter,
|
|
|
|
|
false,
|
|
|
|
|
1.0f,
|
|
|
|
|
false,
|
|
|
|
|
false);
|
2010-01-03 08:37:18 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-05 03:13:47 +10:00
|
|
|
void uiTemplateIDPreview(uiLayout *layout,
|
|
|
|
|
bContext *C,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
const char *newop,
|
2018-11-02 17:30:09 +01:00
|
|
|
const char *openop,
|
|
|
|
|
const char *unlinkop,
|
|
|
|
|
int rows,
|
|
|
|
|
int cols,
|
|
|
|
|
int filter,
|
2018-11-03 15:55:33 +11:00
|
|
|
const bool hide_buttons)
|
2010-01-03 08:37:18 +00:00
|
|
|
{
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
ui_template_id(layout,
|
|
|
|
|
C,
|
|
|
|
|
ptr,
|
|
|
|
|
propname,
|
|
|
|
|
newop,
|
|
|
|
|
openop,
|
|
|
|
|
unlinkop,
|
2019-11-25 19:41:30 +01:00
|
|
|
NULL,
|
2020-05-26 13:24:28 +02:00
|
|
|
NULL,
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE | UI_ID_PREVIEWS,
|
2018-11-02 17:30:09 +01:00
|
|
|
rows,
|
|
|
|
|
cols,
|
|
|
|
|
filter,
|
|
|
|
|
false,
|
|
|
|
|
1.0f,
|
|
|
|
|
false,
|
|
|
|
|
hide_buttons);
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void uiTemplateGpencilColorPreview(uiLayout *layout,
|
2018-11-21 06:21:58 +11:00
|
|
|
bContext *C,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
int rows,
|
|
|
|
|
int cols,
|
|
|
|
|
float scale,
|
|
|
|
|
int filter)
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
|
|
|
|
ui_template_id(layout,
|
2018-11-21 06:21:58 +11:00
|
|
|
C,
|
|
|
|
|
ptr,
|
|
|
|
|
propname,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
2019-11-25 19:41:30 +01:00
|
|
|
NULL,
|
2020-05-26 13:24:28 +02:00
|
|
|
NULL,
|
2018-11-21 06:21:58 +11:00
|
|
|
UI_ID_BROWSE | UI_ID_PREVIEWS | UI_ID_DELETE,
|
|
|
|
|
rows,
|
|
|
|
|
cols,
|
|
|
|
|
filter,
|
|
|
|
|
false,
|
|
|
|
|
scale < 0.5f ? 0.5f : scale,
|
|
|
|
|
false,
|
|
|
|
|
false);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Version of #uiTemplateID using tabs.
|
|
|
|
|
*/
|
|
|
|
|
void uiTemplateIDTabs(uiLayout *layout,
|
|
|
|
|
bContext *C,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
2018-08-28 15:12:14 +02:00
|
|
|
const char *newop,
|
2020-05-26 13:24:28 +02:00
|
|
|
const char *menu,
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
int filter)
|
|
|
|
|
{
|
|
|
|
|
ui_template_id(layout,
|
|
|
|
|
C,
|
|
|
|
|
ptr,
|
|
|
|
|
propname,
|
2018-08-28 15:12:14 +02:00
|
|
|
newop,
|
|
|
|
|
NULL,
|
2020-05-26 13:24:28 +02:00
|
|
|
NULL,
|
|
|
|
|
menu,
|
2019-11-25 19:41:30 +01:00
|
|
|
NULL,
|
2018-08-28 15:12:14 +02:00
|
|
|
UI_ID_BROWSE | UI_ID_RENAME,
|
2018-11-02 17:30:09 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
filter,
|
|
|
|
|
true,
|
|
|
|
|
1.0f,
|
|
|
|
|
false,
|
|
|
|
|
false);
|
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed.
This means the layout engine now works at button level, and makes it
easier to write templates. Otherwise you had to store all info and
create the buttons later.
* Added interface_templates.c as a separate file to put templates in.
These can contain regular buttons, and can be put in a Free layout,
which means you can specify manual coordinates, but still get nested
correct inside other layouts.
* API was changed to allow better nesting. Previously items were added
in the last added layout specifier, i.e. one level up in the layout
hierarchy. This doesn't work well in always, so now when creating things
like rows or columns it always returns a layout which you have to add
the items in. All py scripts were updated to follow this.
* Computing the layout now goes in two passes, first estimating the
required width/height of all nested layouts, and then in the second
pass using the results of that to decide on the actual locations.
* Enum and array buttons now follow the direction of the layout, i.e.
they are vertical or horizontal depending if they are in a column or row.
* Color properties now get a color picker, and only get the additional
RGB sliders with Expand=True.
* File/directory string properties now get a button next to them for
opening the file browse, though this is not implemented yet.
* Layout items can now be aligned, set align=True when creating a column,
row, etc.
* Buttons now get a minimum width of one icon (avoids squashing icon
buttons).
* Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name ID Chooser Template
|
|
|
|
|
* \{ */
|
2009-10-14 09:08:53 +00:00
|
|
|
|
2015-05-31 14:20:03 +10:00
|
|
|
/**
|
2019-04-17 08:44:38 +02:00
|
|
|
* This is for selecting the type of ID-block to use,
|
|
|
|
|
* and then from the relevant type choosing the block to use.
|
2009-10-15 10:13:59 +00:00
|
|
|
*
|
2019-04-17 08:44:38 +02:00
|
|
|
* \param propname: property identifier for property that ID-pointer gets stored to.
|
|
|
|
|
* \param proptypename: property identifier for property
|
|
|
|
|
* used to determine the type of ID-pointer that can be used.
|
2009-10-14 09:08:53 +00:00
|
|
|
*/
|
2015-05-05 03:13:47 +10:00
|
|
|
void uiTemplateAnyID(uiLayout *layout,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
const char *proptypename,
|
|
|
|
|
const char *text)
|
2009-10-14 09:08:53 +00:00
|
|
|
{
|
|
|
|
|
/* get properties... */
|
2021-02-17 16:59:50 -06:00
|
|
|
PropertyRNA *propID = RNA_struct_find_property(ptr, propname);
|
|
|
|
|
PropertyRNA *propType = RNA_struct_find_property(ptr, proptypename);
|
2009-10-14 09:08:53 +00:00
|
|
|
|
|
|
|
|
if (!propID || RNA_property_type(propID) != PROP_POINTER) {
|
2011-09-09 01:29:53 +00:00
|
|
|
RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
2009-10-14 09:08:53 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2012-10-21 05:46:41 +00:00
|
|
|
if (!propType || RNA_property_type(propType) != PROP_ENUM) {
|
2011-09-09 01:29:53 +00:00
|
|
|
RNA_warning(
|
|
|
|
|
"pointer-type property not found: %s.%s", RNA_struct_identifier(ptr->type), proptypename);
|
2009-10-14 09:08:53 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2009-10-14 09:08:53 +00:00
|
|
|
/* Start drawing UI Elements using standard defines */
|
2019-01-15 23:24:20 +11:00
|
|
|
|
|
|
|
|
/* NOTE: split amount here needs to be synced with normal labels */
|
2021-02-17 16:59:50 -06:00
|
|
|
uiLayout *split = uiLayoutSplit(layout, 0.33f, false);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2013-03-16 03:59:03 +00:00
|
|
|
/* FIRST PART ................................................ */
|
2021-02-17 16:59:50 -06:00
|
|
|
uiLayout *row = uiLayoutRow(split, false);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2009-10-14 09:08:53 +00:00
|
|
|
/* Label - either use the provided text, or will become "ID-Block:" */
|
2012-06-04 16:42:58 +00:00
|
|
|
if (text) {
|
2019-03-25 10:15:20 +11:00
|
|
|
if (text[0]) {
|
2012-06-04 16:42:58 +00:00
|
|
|
uiItemL(row, text, ICON_NONE);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2012-06-04 16:42:58 +00:00
|
|
|
}
|
2013-03-16 03:59:03 +00:00
|
|
|
else {
|
2013-02-19 15:45:56 +00:00
|
|
|
uiItemL(row, IFACE_("ID-Block:"), ICON_NONE);
|
2013-03-16 03:59:03 +00:00
|
|
|
}
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2013-03-16 03:59:03 +00:00
|
|
|
/* SECOND PART ................................................ */
|
2014-01-04 17:16:19 +11:00
|
|
|
row = uiLayoutRow(split, true);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2009-10-14 09:08:53 +00:00
|
|
|
/* ID-Type Selector - just have a menu of icons */
|
2019-01-15 23:24:20 +11:00
|
|
|
|
|
|
|
|
/* HACK: special group just for the enum,
|
|
|
|
|
* otherwise we get ugly layout with text included too... */
|
2021-02-17 16:59:50 -06:00
|
|
|
uiLayout *sub = uiLayoutRow(row, true);
|
2019-01-15 23:24:20 +11:00
|
|
|
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2013-03-16 03:59:03 +00:00
|
|
|
uiItemFullR(sub, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2009-10-14 09:08:53 +00:00
|
|
|
/* ID-Block Selector - just use pointer widget... */
|
2019-01-15 23:24:20 +11:00
|
|
|
|
|
|
|
|
/* HACK: special group to counteract the effects of the previous enum,
|
|
|
|
|
* which now pushes everything too far right. */
|
|
|
|
|
sub = uiLayoutRow(row, true);
|
|
|
|
|
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_EXPAND);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2013-03-16 03:59:03 +00:00
|
|
|
uiItemFullR(sub, ptr, propID, 0, 0, 0, "", ICON_NONE);
|
2009-10-14 09:08:53 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Search Template
|
|
|
|
|
* \{ */
|
2017-05-12 01:42:42 +02:00
|
|
|
|
|
|
|
|
typedef struct TemplateSearch {
|
|
|
|
|
uiRNACollectionSearch search_data;
|
|
|
|
|
|
|
|
|
|
bool use_previews;
|
|
|
|
|
int preview_rows, preview_cols;
|
|
|
|
|
} TemplateSearch;
|
|
|
|
|
|
2020-05-08 12:01:35 +10:00
|
|
|
static void template_search_exec_fn(bContext *C, void *arg_template, void *item)
|
2017-05-12 01:42:42 +02:00
|
|
|
{
|
|
|
|
|
TemplateSearch *template_search = arg_template;
|
|
|
|
|
uiRNACollectionSearch *coll_search = &template_search->search_data;
|
|
|
|
|
StructRNA *type = RNA_property_pointer_type(&coll_search->target_ptr, coll_search->target_prop);
|
|
|
|
|
PointerRNA item_ptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
RNA_pointer_create(NULL, type, item, &item_ptr);
|
2019-05-20 18:06:09 +10:00
|
|
|
RNA_property_pointer_set(&coll_search->target_ptr, coll_search->target_prop, item_ptr, NULL);
|
2017-05-12 01:42:42 +02:00
|
|
|
RNA_property_update(C, &coll_search->target_ptr, coll_search->target_prop);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uiBlock *template_search_menu(bContext *C, ARegion *region, void *arg_template)
|
|
|
|
|
{
|
|
|
|
|
static TemplateSearch template_search;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
/* arg_template is malloced, can be freed by parent button */
|
|
|
|
|
template_search = *((TemplateSearch *)arg_template);
|
2020-10-04 22:44:19 -05:00
|
|
|
PointerRNA active_ptr = RNA_property_pointer_get(&template_search.search_data.target_ptr,
|
|
|
|
|
template_search.search_data.target_prop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
return template_common_search_menu(C,
|
2018-07-01 20:15:21 +02:00
|
|
|
region,
|
2020-05-07 23:16:05 +10:00
|
|
|
ui_rna_collection_search_update_fn,
|
2018-07-01 20:15:21 +02:00
|
|
|
&template_search,
|
2020-05-08 12:01:35 +10:00
|
|
|
template_search_exec_fn,
|
2018-07-01 20:15:21 +02:00
|
|
|
active_ptr.data,
|
2021-01-26 22:06:45 +01:00
|
|
|
NULL,
|
2018-07-31 10:22:19 +02:00
|
|
|
template_search.preview_rows,
|
|
|
|
|
template_search.preview_cols,
|
|
|
|
|
1.0f);
|
2017-05-12 01:42:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void template_search_add_button_searchmenu(const bContext *C,
|
|
|
|
|
uiLayout *layout,
|
|
|
|
|
uiBlock *block,
|
2018-07-31 10:22:19 +02:00
|
|
|
TemplateSearch *template_search,
|
|
|
|
|
const bool editable,
|
|
|
|
|
const bool live_icon)
|
2017-05-12 01:42:42 +02:00
|
|
|
{
|
|
|
|
|
const char *ui_description = RNA_property_ui_description(
|
|
|
|
|
template_search->search_data.target_prop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
template_add_button_search_menu(C,
|
|
|
|
|
layout,
|
|
|
|
|
block,
|
|
|
|
|
&template_search->search_data.target_ptr,
|
|
|
|
|
template_search->search_data.target_prop,
|
|
|
|
|
template_search_menu,
|
|
|
|
|
MEM_dupallocN(template_search),
|
|
|
|
|
ui_description,
|
2018-07-31 10:22:19 +02:00
|
|
|
template_search->use_previews,
|
|
|
|
|
editable,
|
|
|
|
|
live_icon);
|
2017-05-12 01:42:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void template_search_add_button_name(uiBlock *block,
|
|
|
|
|
PointerRNA *active_ptr,
|
2021-01-13 15:08:09 +01:00
|
|
|
const StructRNA *type)
|
2017-05-12 01:42:42 +02:00
|
|
|
{
|
2021-03-18 15:00:55 +01:00
|
|
|
PropertyRNA *name_prop = RNA_struct_name_property(type);
|
|
|
|
|
const int width = template_search_textbut_width(active_ptr, name_prop);
|
|
|
|
|
const int height = template_search_textbut_height();
|
|
|
|
|
uiDefAutoButR(block, active_ptr, name_prop, 0, "", ICON_NONE, 0, 0, width, height);
|
2021-01-13 15:08:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void template_search_add_button_operator(uiBlock *block,
|
|
|
|
|
const char *const operator_name,
|
|
|
|
|
const int opcontext,
|
|
|
|
|
const int icon,
|
|
|
|
|
const bool editable)
|
|
|
|
|
{
|
|
|
|
|
if (!operator_name) {
|
|
|
|
|
return;
|
2017-05-12 01:42:42 +02:00
|
|
|
}
|
2021-01-13 15:08:09 +01:00
|
|
|
|
|
|
|
|
uiBut *but = uiDefIconButO(
|
|
|
|
|
block, UI_BTYPE_BUT, operator_name, opcontext, icon, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
|
|
|
|
|
|
|
|
|
|
if (!editable) {
|
|
|
|
|
UI_but_drawflag_enable(but, UI_BUT_DISABLED);
|
2017-05-12 01:42:42 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void template_search_buttons(const bContext *C,
|
|
|
|
|
uiLayout *layout,
|
|
|
|
|
TemplateSearch *template_search,
|
|
|
|
|
const char *newop,
|
|
|
|
|
const char *unlinkop)
|
|
|
|
|
{
|
|
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
|
|
|
|
uiRNACollectionSearch *search_data = &template_search->search_data;
|
|
|
|
|
StructRNA *type = RNA_property_pointer_type(&search_data->target_ptr, search_data->target_prop);
|
|
|
|
|
const bool editable = RNA_property_editable(&search_data->target_ptr, search_data->target_prop);
|
|
|
|
|
PointerRNA active_ptr = RNA_property_pointer_get(&search_data->target_ptr,
|
|
|
|
|
search_data->target_prop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
if (active_ptr.type) {
|
|
|
|
|
/* can only get correct type when there is an active item */
|
|
|
|
|
type = active_ptr.type;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
uiLayoutRow(layout, true);
|
|
|
|
|
UI_block_align_begin(block);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-31 10:22:19 +02:00
|
|
|
template_search_add_button_searchmenu(C, layout, block, template_search, editable, false);
|
2021-01-13 15:08:09 +01:00
|
|
|
template_search_add_button_name(block, &active_ptr, type);
|
|
|
|
|
template_search_add_button_operator(
|
|
|
|
|
block, newop, WM_OP_INVOKE_DEFAULT, ICON_DUPLICATE, editable);
|
|
|
|
|
template_search_add_button_operator(block, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, editable);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
UI_block_align_end(block);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static PropertyRNA *template_search_get_searchprop(PointerRNA *targetptr,
|
|
|
|
|
PropertyRNA *targetprop,
|
|
|
|
|
PointerRNA *searchptr,
|
|
|
|
|
const char *const searchpropname)
|
|
|
|
|
{
|
|
|
|
|
PropertyRNA *searchprop;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
if (searchptr && !searchptr->data) {
|
|
|
|
|
searchptr = NULL;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
if (!searchptr && !searchpropname) {
|
|
|
|
|
/* both NULL means we don't use a custom rna collection to search in */
|
|
|
|
|
}
|
|
|
|
|
else if (!searchptr && searchpropname) {
|
|
|
|
|
RNA_warning("searchpropname defined (%s) but searchptr is missing", searchpropname);
|
|
|
|
|
}
|
|
|
|
|
else if (searchptr && !searchpropname) {
|
|
|
|
|
RNA_warning("searchptr defined (%s) but searchpropname is missing",
|
|
|
|
|
RNA_struct_identifier(searchptr->type));
|
|
|
|
|
}
|
|
|
|
|
else if (!(searchprop = RNA_struct_find_property(searchptr, searchpropname))) {
|
|
|
|
|
RNA_warning("search collection property not found: %s.%s",
|
|
|
|
|
RNA_struct_identifier(searchptr->type),
|
|
|
|
|
searchpropname);
|
|
|
|
|
}
|
|
|
|
|
else if (RNA_property_type(searchprop) != PROP_COLLECTION) {
|
|
|
|
|
RNA_warning("search collection property is not a collection type: %s.%s",
|
|
|
|
|
RNA_struct_identifier(searchptr->type),
|
|
|
|
|
searchpropname);
|
|
|
|
|
}
|
|
|
|
|
/* check if searchprop has same type as targetprop */
|
|
|
|
|
else if (RNA_property_pointer_type(searchptr, searchprop) !=
|
|
|
|
|
RNA_property_pointer_type(targetptr, targetprop)) {
|
|
|
|
|
RNA_warning("search collection items from %s.%s are not of type %s",
|
|
|
|
|
RNA_struct_identifier(searchptr->type),
|
|
|
|
|
searchpropname,
|
|
|
|
|
RNA_struct_identifier(RNA_property_pointer_type(targetptr, targetprop)));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return searchprop;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-12 01:42:42 +02:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static TemplateSearch *template_search_setup(PointerRNA *ptr,
|
|
|
|
|
const char *const propname,
|
|
|
|
|
PointerRNA *searchptr,
|
|
|
|
|
const char *const searchpropname)
|
|
|
|
|
{
|
2021-02-17 16:59:50 -06:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
2017-05-12 01:42:42 +02:00
|
|
|
|
|
|
|
|
if (!prop || RNA_property_type(prop) != PROP_POINTER) {
|
|
|
|
|
RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2021-02-17 16:59:50 -06:00
|
|
|
PropertyRNA *searchprop = template_search_get_searchprop(ptr, prop, searchptr, searchpropname);
|
2017-05-12 01:42:42 +02:00
|
|
|
|
2021-02-17 16:59:50 -06:00
|
|
|
TemplateSearch *template_search = MEM_callocN(sizeof(*template_search), __func__);
|
2017-05-12 01:42:42 +02:00
|
|
|
template_search->search_data.target_ptr = *ptr;
|
|
|
|
|
template_search->search_data.target_prop = prop;
|
|
|
|
|
template_search->search_data.search_ptr = *searchptr;
|
|
|
|
|
template_search->search_data.search_prop = searchprop;
|
|
|
|
|
|
|
|
|
|
return template_search;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Search menu to pick an item from a collection.
|
|
|
|
|
* A version of uiTemplateID that works for non-ID types.
|
|
|
|
|
*/
|
|
|
|
|
void uiTemplateSearch(uiLayout *layout,
|
|
|
|
|
bContext *C,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
PointerRNA *searchptr,
|
|
|
|
|
const char *searchpropname,
|
|
|
|
|
const char *newop,
|
|
|
|
|
const char *unlinkop)
|
|
|
|
|
{
|
|
|
|
|
TemplateSearch *template_search = template_search_setup(
|
|
|
|
|
ptr, propname, searchptr, searchpropname);
|
2017-12-04 16:17:54 +11:00
|
|
|
if (template_search != NULL) {
|
|
|
|
|
template_search_buttons(C, layout, template_search, newop, unlinkop);
|
|
|
|
|
MEM_freeN(template_search);
|
|
|
|
|
}
|
2017-05-12 01:42:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void uiTemplateSearchPreview(uiLayout *layout,
|
|
|
|
|
bContext *C,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
PointerRNA *searchptr,
|
|
|
|
|
const char *searchpropname,
|
|
|
|
|
const char *newop,
|
|
|
|
|
const char *unlinkop,
|
|
|
|
|
const int rows,
|
|
|
|
|
const int cols)
|
|
|
|
|
{
|
|
|
|
|
TemplateSearch *template_search = template_search_setup(
|
|
|
|
|
ptr, propname, searchptr, searchpropname);
|
|
|
|
|
|
2017-12-04 16:17:54 +11:00
|
|
|
if (template_search != NULL) {
|
|
|
|
|
template_search->use_previews = true;
|
|
|
|
|
template_search->preview_rows = rows;
|
|
|
|
|
template_search->preview_cols = cols;
|
2017-05-12 01:42:42 +02:00
|
|
|
|
2017-12-04 16:17:54 +11:00
|
|
|
template_search_buttons(C, layout, template_search, newop, unlinkop);
|
2017-05-12 01:42:42 +02:00
|
|
|
|
2017-12-04 16:17:54 +11:00
|
|
|
MEM_freeN(template_search);
|
|
|
|
|
}
|
2017-05-12 01:42:42 +02:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name RNA Path Builder Template
|
|
|
|
|
* \{ */
|
2009-10-15 10:13:59 +00:00
|
|
|
|
2009-11-11 09:59:51 +00:00
|
|
|
/* ---------- */
|
|
|
|
|
|
2015-05-31 14:20:03 +10:00
|
|
|
/**
|
|
|
|
|
* This is creating/editing RNA-Paths
|
2009-10-15 10:13:59 +00:00
|
|
|
*
|
|
|
|
|
* - ptr: struct which holds the path property
|
|
|
|
|
* - propname: property identifier for property that path gets stored to
|
|
|
|
|
* - root_ptr: struct that path gets built from
|
|
|
|
|
*/
|
2018-07-01 19:57:31 +02:00
|
|
|
void uiTemplatePathBuilder(uiLayout *layout,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
PointerRNA *UNUSED(root_ptr),
|
|
|
|
|
const char *text)
|
2009-10-15 10:13:59 +00:00
|
|
|
{
|
|
|
|
|
/* check that properties are valid */
|
2021-02-17 16:59:50 -06:00
|
|
|
PropertyRNA *propPath = RNA_struct_find_property(ptr, propname);
|
2009-10-15 10:13:59 +00:00
|
|
|
if (!propPath || RNA_property_type(propPath) != PROP_STRING) {
|
2011-09-09 01:29:53 +00:00
|
|
|
RNA_warning("path property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
2009-10-15 10:13:59 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2009-10-15 10:13:59 +00:00
|
|
|
/* Start drawing UI Elements using standard defines */
|
2021-02-17 16:59:50 -06:00
|
|
|
uiLayout *row = uiLayoutRow(layout, true);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2009-10-15 10:13:59 +00:00
|
|
|
/* Path (existing string) Widget */
|
2010-03-23 15:31:12 +00:00
|
|
|
uiItemR(row, ptr, propname, 0, text, ICON_RNA);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2019-01-15 23:24:20 +11:00
|
|
|
/* TODO: attach something to this to make allow
|
|
|
|
|
* searching of nested properties to 'build' the path */
|
2009-10-15 10:13:59 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2020-06-05 10:41:03 -04:00
|
|
|
/** \name Modifiers Template
|
|
|
|
|
*
|
|
|
|
|
* Template for building the panel layout for the active object's modifiers.
|
2019-09-06 16:12:47 +10:00
|
|
|
* \{ */
|
2009-05-21 15:34:09 +00:00
|
|
|
|
2020-06-05 10:41:03 -04:00
|
|
|
static void modifier_panel_id(void *md_link, char *r_name)
|
2009-05-27 00:03:49 +00:00
|
|
|
{
|
2020-06-05 10:41:03 -04:00
|
|
|
ModifierData *md = (ModifierData *)md_link;
|
|
|
|
|
BKE_modifier_type_panel_id(md->type, r_name);
|
2009-05-21 15:34:09 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-05 10:41:03 -04:00
|
|
|
void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C)
|
2016-12-28 17:30:58 +01:00
|
|
|
{
|
2020-06-05 10:41:03 -04:00
|
|
|
ARegion *region = CTX_wm_region(C);
|
2016-12-28 17:30:58 +01:00
|
|
|
|
2020-07-03 11:58:43 -04:00
|
|
|
Object *ob = ED_object_active_context(C);
|
2020-06-05 10:41:03 -04:00
|
|
|
ListBase *modifiers = &ob->modifiers;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-26 10:11:13 +10:00
|
|
|
const bool panels_match = UI_panel_list_matches_data(region, modifiers, modifier_panel_id);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-05 10:41:03 -04:00
|
|
|
if (!panels_match) {
|
|
|
|
|
UI_panels_free_instanced(C, region);
|
|
|
|
|
ModifierData *md = modifiers->first;
|
|
|
|
|
for (int i = 0; md; i++, md = md->next) {
|
|
|
|
|
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
|
2020-06-29 15:00:25 -04:00
|
|
|
if (mti->panelRegister == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-29 15:00:25 -04:00
|
|
|
char panel_idname[MAX_NAME];
|
|
|
|
|
modifier_panel_id(md, panel_idname);
|
|
|
|
|
|
|
|
|
|
/* Create custom data RNA pointer. */
|
|
|
|
|
PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
|
|
|
|
|
RNA_pointer_create(&ob->id, &RNA_Modifier, md, md_ptr);
|
|
|
|
|
|
2020-09-29 17:41:00 -05:00
|
|
|
UI_panel_add_instanced(C, region, ®ion->panels, panel_idname, md_ptr);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2009-05-21 15:34:09 +00:00
|
|
|
}
|
2020-06-09 13:41:50 -04:00
|
|
|
else {
|
2020-06-29 15:00:25 -04:00
|
|
|
/* Assuming there's only one group of instanced panels, update the custom data pointers. */
|
|
|
|
|
Panel *panel = region->panels.first;
|
|
|
|
|
LISTBASE_FOREACH (ModifierData *, md, modifiers) {
|
|
|
|
|
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
|
|
|
|
|
if (mti->panelRegister == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Move to the next instanced panel corresponding to the next modifier. */
|
2020-11-13 13:56:55 -05:00
|
|
|
while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
|
2020-06-29 15:00:25 -04:00
|
|
|
panel = panel->next;
|
|
|
|
|
BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
|
|
|
|
|
RNA_pointer_create(&ob->id, &RNA_Modifier, md, md_ptr);
|
|
|
|
|
UI_panel_custom_data_set(panel, md_ptr);
|
|
|
|
|
|
|
|
|
|
panel = panel->next;
|
|
|
|
|
}
|
2020-06-09 13:41:50 -04:00
|
|
|
}
|
2009-05-21 15:34:09 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
2020-06-19 12:40:48 -04:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Constraints Template
|
|
|
|
|
*
|
|
|
|
|
* Template for building the panel layout for the active object or bone's constraints.
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
/** For building the panel UI for constraints. */
|
|
|
|
|
#define CONSTRAINT_TYPE_PANEL_PREFIX "OBJECT_PT_"
|
|
|
|
|
#define CONSTRAINT_BONE_TYPE_PANEL_PREFIX "BONE_PT_"
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if the panel's ID starts with 'BONE', meaning it is a bone constraint.
|
|
|
|
|
*/
|
|
|
|
|
static bool constraint_panel_is_bone(Panel *panel)
|
|
|
|
|
{
|
|
|
|
|
return (panel->panelname[0] == 'B') && (panel->panelname[1] == 'O') &&
|
|
|
|
|
(panel->panelname[2] == 'N') && (panel->panelname[3] == 'E');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Move a constraint to the index it's moved to after a drag and drop.
|
|
|
|
|
*/
|
|
|
|
|
static void constraint_reorder(bContext *C, Panel *panel, int new_index)
|
|
|
|
|
{
|
2021-01-04 17:02:13 +11:00
|
|
|
const bool constraint_from_bone = constraint_panel_is_bone(panel);
|
2020-09-02 14:13:26 -05:00
|
|
|
|
|
|
|
|
PointerRNA *con_ptr = UI_panel_custom_data_get(panel);
|
|
|
|
|
bConstraint *con = (bConstraint *)con_ptr->data;
|
2020-06-19 12:40:48 -04:00
|
|
|
|
|
|
|
|
PointerRNA props_ptr;
|
|
|
|
|
wmOperatorType *ot = WM_operatortype_find("CONSTRAINT_OT_move_to_index", false);
|
|
|
|
|
WM_operator_properties_create_ptr(&props_ptr, ot);
|
|
|
|
|
RNA_string_set(&props_ptr, "constraint", con->name);
|
|
|
|
|
RNA_int_set(&props_ptr, "index", new_index);
|
|
|
|
|
/* Set owner to #EDIT_CONSTRAINT_OWNER_OBJECT or #EDIT_CONSTRAINT_OWNER_BONE. */
|
|
|
|
|
RNA_enum_set(&props_ptr, "owner", constraint_from_bone ? 1 : 0);
|
|
|
|
|
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
|
|
|
|
|
WM_operator_properties_free(&props_ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the expand flag from the active constraint to use for the panel.
|
|
|
|
|
*/
|
2020-09-02 14:13:26 -05:00
|
|
|
static short get_constraint_expand_flag(const bContext *UNUSED(C), Panel *panel)
|
2020-06-19 12:40:48 -04:00
|
|
|
{
|
2020-09-02 14:13:26 -05:00
|
|
|
PointerRNA *con_ptr = UI_panel_custom_data_get(panel);
|
|
|
|
|
bConstraint *con = (bConstraint *)con_ptr->data;
|
2020-06-19 12:40:48 -04:00
|
|
|
|
|
|
|
|
return con->ui_expand_flag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2020-06-25 23:13:02 +10:00
|
|
|
* Save the expand flag for the panel and sub-panels to the constraint.
|
2020-06-19 12:40:48 -04:00
|
|
|
*/
|
2020-09-02 14:13:26 -05:00
|
|
|
static void set_constraint_expand_flag(const bContext *UNUSED(C), Panel *panel, short expand_flag)
|
2020-06-19 12:40:48 -04:00
|
|
|
{
|
2020-09-02 14:13:26 -05:00
|
|
|
PointerRNA *con_ptr = UI_panel_custom_data_get(panel);
|
|
|
|
|
bConstraint *con = (bConstraint *)con_ptr->data;
|
2020-06-19 12:40:48 -04:00
|
|
|
con->ui_expand_flag = expand_flag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Function with void * argument for #uiListPanelIDFromDataFunc.
|
|
|
|
|
*
|
2020-12-15 12:30:00 +11:00
|
|
|
* \note Constraint panel types are assumed to be named with the struct name field
|
2020-06-19 12:40:48 -04:00
|
|
|
* concatenated to the defined prefix.
|
|
|
|
|
*/
|
|
|
|
|
static void object_constraint_panel_id(void *md_link, char *r_name)
|
|
|
|
|
{
|
|
|
|
|
bConstraint *con = (bConstraint *)md_link;
|
|
|
|
|
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(con->type);
|
|
|
|
|
|
2021-01-04 14:14:13 +01:00
|
|
|
/* Cannot get TypeInfo for invalid/legacy constraints. */
|
|
|
|
|
if (cti == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-19 12:40:48 -04:00
|
|
|
strcpy(r_name, CONSTRAINT_TYPE_PANEL_PREFIX);
|
|
|
|
|
strcat(r_name, cti->structName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void bone_constraint_panel_id(void *md_link, char *r_name)
|
|
|
|
|
{
|
|
|
|
|
bConstraint *con = (bConstraint *)md_link;
|
|
|
|
|
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(con->type);
|
|
|
|
|
|
2021-01-04 14:14:13 +01:00
|
|
|
/* Cannot get TypeInfo for invalid/legacy constraints. */
|
|
|
|
|
if (cti == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-19 12:40:48 -04:00
|
|
|
strcpy(r_name, CONSTRAINT_BONE_TYPE_PANEL_PREFIX);
|
|
|
|
|
strcat(r_name, cti->structName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if the constraint panels don't match the data and rebuild the panels if so.
|
|
|
|
|
*/
|
|
|
|
|
void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_constraints)
|
|
|
|
|
{
|
|
|
|
|
ARegion *region = CTX_wm_region(C);
|
|
|
|
|
|
2020-07-16 14:07:47 -04:00
|
|
|
Object *ob = ED_object_active_context(C);
|
2020-09-09 13:52:37 +02:00
|
|
|
ListBase *constraints = {NULL};
|
|
|
|
|
if (use_bone_constraints) {
|
|
|
|
|
constraints = ED_object_pose_constraint_list(C);
|
|
|
|
|
}
|
2020-09-23 12:13:25 +02:00
|
|
|
else if (ob != NULL) {
|
|
|
|
|
constraints = &ob->constraints;
|
2020-09-09 13:52:37 +02:00
|
|
|
}
|
2020-06-19 12:40:48 -04:00
|
|
|
|
|
|
|
|
/* Switch between the bone panel ID function and the object panel ID function. */
|
|
|
|
|
uiListPanelIDFromDataFunc panel_id_func = use_bone_constraints ? bone_constraint_panel_id :
|
|
|
|
|
object_constraint_panel_id;
|
|
|
|
|
|
2020-08-26 10:11:13 +10:00
|
|
|
const bool panels_match = UI_panel_list_matches_data(region, constraints, panel_id_func);
|
2020-06-19 12:40:48 -04:00
|
|
|
|
|
|
|
|
if (!panels_match) {
|
|
|
|
|
UI_panels_free_instanced(C, region);
|
|
|
|
|
bConstraint *con = (constraints == NULL) ? NULL : constraints->first;
|
|
|
|
|
for (int i = 0; con; i++, con = con->next) {
|
2021-03-18 09:35:12 +11:00
|
|
|
/* Don't show invalid/legacy constraints. */
|
2021-01-04 14:14:13 +01:00
|
|
|
if (con->type == CONSTRAINT_TYPE_NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-03-18 09:35:12 +11:00
|
|
|
/* Don't show temporary constraints (AutoIK and target-less IK constraints). */
|
2020-09-14 23:10:56 +02:00
|
|
|
if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
|
|
|
|
|
bKinematicConstraint *data = con->data;
|
|
|
|
|
if (data->flag & CONSTRAINT_IK_TEMP) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-19 12:40:48 -04:00
|
|
|
char panel_idname[MAX_NAME];
|
|
|
|
|
panel_id_func(con, panel_idname);
|
|
|
|
|
|
2020-07-16 14:07:47 -04:00
|
|
|
/* Create custom data RNA pointer. */
|
|
|
|
|
PointerRNA *con_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
|
|
|
|
|
RNA_pointer_create(&ob->id, &RNA_Constraint, con, con_ptr);
|
|
|
|
|
|
2020-09-29 17:41:00 -05:00
|
|
|
Panel *new_panel = UI_panel_add_instanced(C, region, ®ion->panels, panel_idname, con_ptr);
|
2020-07-16 14:07:47 -04:00
|
|
|
|
2020-06-19 12:40:48 -04:00
|
|
|
if (new_panel) {
|
2020-07-16 14:07:47 -04:00
|
|
|
/* Set the list panel functionality function pointers since we don't do it with python. */
|
2020-06-19 12:40:48 -04:00
|
|
|
new_panel->type->set_list_data_expand_flag = set_constraint_expand_flag;
|
|
|
|
|
new_panel->type->get_list_data_expand_flag = get_constraint_expand_flag;
|
|
|
|
|
new_panel->type->reorder = constraint_reorder;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2020-07-16 14:07:47 -04:00
|
|
|
/* Assuming there's only one group of instanced panels, update the custom data pointers. */
|
|
|
|
|
Panel *panel = region->panels.first;
|
|
|
|
|
LISTBASE_FOREACH (bConstraint *, con, constraints) {
|
2021-03-18 09:35:12 +11:00
|
|
|
/* Don't show invalid/legacy constraints. */
|
2021-01-04 14:14:13 +01:00
|
|
|
if (con->type == CONSTRAINT_TYPE_NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-03-18 09:35:12 +11:00
|
|
|
/* Don't show temporary constraints (AutoIK and target-less IK constraints). */
|
2020-09-14 23:10:56 +02:00
|
|
|
if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
|
|
|
|
|
bKinematicConstraint *data = con->data;
|
|
|
|
|
if (data->flag & CONSTRAINT_IK_TEMP) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-16 14:07:47 -04:00
|
|
|
/* Move to the next instanced panel corresponding to the next constraint. */
|
2020-11-13 13:56:55 -05:00
|
|
|
while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
|
2020-07-16 14:07:47 -04:00
|
|
|
panel = panel->next;
|
|
|
|
|
BLI_assert(panel != NULL); /* There shouldn't be fewer panels than constraint panels. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PointerRNA *con_ptr = MEM_mallocN(sizeof(PointerRNA), "constraint panel customdata");
|
|
|
|
|
RNA_pointer_create(&ob->id, &RNA_Constraint, con, con_ptr);
|
|
|
|
|
UI_panel_custom_data_set(panel, con_ptr);
|
|
|
|
|
|
|
|
|
|
panel = panel->next;
|
|
|
|
|
}
|
2020-06-19 12:40:48 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#undef CONSTRAINT_TYPE_PANEL_PREFIX
|
|
|
|
|
#undef CONSTRAINT_BONE_TYPE_PANEL_PREFIX
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
2020-06-29 21:04:45 -04:00
|
|
|
/** \name Grease Pencil Modifiers Template
|
2019-09-06 16:12:47 +10:00
|
|
|
* \{ */
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2020-06-19 14:42:08 -04:00
|
|
|
/**
|
|
|
|
|
* Function with void * argument for #uiListPanelIDFromDataFunc.
|
|
|
|
|
*/
|
|
|
|
|
static void gpencil_modifier_panel_id(void *md_link, char *r_name)
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
2020-06-19 14:42:08 -04:00
|
|
|
ModifierData *md = (ModifierData *)md_link;
|
|
|
|
|
BKE_gpencil_modifierType_panel_id(md->type, r_name);
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
|
2020-06-19 14:42:08 -04:00
|
|
|
void uiTemplateGpencilModifiers(uiLayout *UNUSED(layout), bContext *C)
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
2020-06-19 14:42:08 -04:00
|
|
|
ARegion *region = CTX_wm_region(C);
|
2020-07-03 11:58:43 -04:00
|
|
|
Object *ob = ED_object_active_context(C);
|
2020-06-19 14:42:08 -04:00
|
|
|
ListBase *modifiers = &ob->greasepencil_modifiers;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-26 10:11:13 +10:00
|
|
|
const bool panels_match = UI_panel_list_matches_data(
|
|
|
|
|
region, modifiers, gpencil_modifier_panel_id);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-19 14:42:08 -04:00
|
|
|
if (!panels_match) {
|
|
|
|
|
UI_panels_free_instanced(C, region);
|
|
|
|
|
GpencilModifierData *md = modifiers->first;
|
|
|
|
|
for (int i = 0; md; i++, md = md->next) {
|
|
|
|
|
const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
|
2020-06-29 21:04:45 -04:00
|
|
|
if (mti->panelRegister == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char panel_idname[MAX_NAME];
|
|
|
|
|
gpencil_modifier_panel_id(md, panel_idname);
|
|
|
|
|
|
|
|
|
|
/* Create custom data RNA pointer. */
|
|
|
|
|
PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
|
|
|
|
|
RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, md_ptr);
|
|
|
|
|
|
2020-09-29 17:41:00 -05:00
|
|
|
UI_panel_add_instanced(C, region, ®ion->panels, panel_idname, md_ptr);
|
2020-06-19 14:42:08 -04:00
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
2020-06-19 14:42:08 -04:00
|
|
|
else {
|
2020-06-29 21:04:45 -04:00
|
|
|
/* Assuming there's only one group of instanced panels, update the custom data pointers. */
|
|
|
|
|
Panel *panel = region->panels.first;
|
|
|
|
|
LISTBASE_FOREACH (ModifierData *, md, modifiers) {
|
|
|
|
|
const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
|
|
|
|
|
if (mti->panelRegister == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Move to the next instanced panel corresponding to the next modifier. */
|
2020-11-13 13:56:55 -05:00
|
|
|
while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
|
2020-06-29 21:04:45 -04:00
|
|
|
panel = panel->next;
|
|
|
|
|
BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
|
|
|
|
|
RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, md_ptr);
|
|
|
|
|
UI_panel_custom_data_set(panel, md_ptr);
|
|
|
|
|
|
|
|
|
|
panel = panel->next;
|
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
2020-06-19 14:42:08 -04:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
#define ERROR_LIBDATA_MESSAGE TIP_("Can't edit external library data")
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
2020-06-19 15:07:13 -04:00
|
|
|
/** \name ShaderFx Template
|
|
|
|
|
*
|
2020-06-29 15:00:25 -04:00
|
|
|
* Template for building the panel layout for the active object's grease pencil shader
|
|
|
|
|
* effects.
|
2019-09-06 16:12:47 +10:00
|
|
|
* \{ */
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2020-06-19 15:07:13 -04:00
|
|
|
/**
|
|
|
|
|
* Function with void * argument for #uiListPanelIDFromDataFunc.
|
|
|
|
|
*/
|
|
|
|
|
static void shaderfx_panel_id(void *fx_v, char *r_idname)
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
2020-06-19 15:07:13 -04:00
|
|
|
ShaderFxData *fx = (ShaderFxData *)fx_v;
|
|
|
|
|
BKE_shaderfxType_panel_id(fx->type, r_idname);
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
|
2020-06-19 15:07:13 -04:00
|
|
|
/**
|
|
|
|
|
* Check if the shader effect panels don't match the data and rebuild the panels if so.
|
|
|
|
|
*/
|
|
|
|
|
void uiTemplateShaderFx(uiLayout *UNUSED(layout), bContext *C)
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
2020-06-19 15:07:13 -04:00
|
|
|
ARegion *region = CTX_wm_region(C);
|
2020-07-03 11:58:43 -04:00
|
|
|
Object *ob = ED_object_active_context(C);
|
2020-06-19 15:07:13 -04:00
|
|
|
ListBase *shaderfx = &ob->shader_fx;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-26 10:11:13 +10:00
|
|
|
const bool panels_match = UI_panel_list_matches_data(region, shaderfx, shaderfx_panel_id);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-19 15:07:13 -04:00
|
|
|
if (!panels_match) {
|
|
|
|
|
UI_panels_free_instanced(C, region);
|
|
|
|
|
ShaderFxData *fx = shaderfx->first;
|
|
|
|
|
for (int i = 0; fx; i++, fx = fx->next) {
|
|
|
|
|
char panel_idname[MAX_NAME];
|
|
|
|
|
shaderfx_panel_id(fx, panel_idname);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-07-06 15:35:21 -04:00
|
|
|
/* Create custom data RNA pointer. */
|
|
|
|
|
PointerRNA *fx_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
|
|
|
|
|
RNA_pointer_create(&ob->id, &RNA_ShaderFx, fx, fx_ptr);
|
|
|
|
|
|
2020-09-29 17:41:00 -05:00
|
|
|
UI_panel_add_instanced(C, region, ®ion->panels, panel_idname, fx_ptr);
|
2020-06-19 15:07:13 -04:00
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
2020-06-19 15:07:13 -04:00
|
|
|
else {
|
2020-07-06 15:35:21 -04:00
|
|
|
/* Assuming there's only one group of instanced panels, update the custom data pointers. */
|
|
|
|
|
Panel *panel = region->panels.first;
|
|
|
|
|
LISTBASE_FOREACH (ShaderFxData *, fx, shaderfx) {
|
|
|
|
|
const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type);
|
|
|
|
|
if (fxi->panelRegister == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Move to the next instanced panel corresponding to the next modifier. */
|
2020-11-13 13:56:55 -05:00
|
|
|
while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
|
2020-07-06 15:35:21 -04:00
|
|
|
panel = panel->next;
|
|
|
|
|
BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PointerRNA *fx_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
|
|
|
|
|
RNA_pointer_create(&ob->id, &RNA_ShaderFx, fx, fx_ptr);
|
|
|
|
|
UI_panel_custom_data_set(panel, fx_ptr);
|
|
|
|
|
|
|
|
|
|
panel = panel->next;
|
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
}
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
|
2019-09-06 16:12:47 +10: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
|
|
|
/** \name Operator Property Buttons Template
|
2019-09-06 16:12:47 +10:00
|
|
|
* \{ */
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
|
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
|
|
|
typedef struct uiTemplateOperatorPropertyPollParam {
|
|
|
|
|
const bContext *C;
|
|
|
|
|
wmOperator *op;
|
|
|
|
|
short flag;
|
|
|
|
|
} uiTemplateOperatorPropertyPollParam;
|
|
|
|
|
|
|
|
|
|
#ifdef USE_OP_RESET_BUT
|
|
|
|
|
static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C),
|
|
|
|
|
void *op_pt,
|
|
|
|
|
void *UNUSED(arg_dummy2))
|
|
|
|
|
{
|
|
|
|
|
WM_operator_properties_reset((wmOperator *)op_pt);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static bool ui_layout_operator_buts_poll_property(struct PointerRNA *UNUSED(ptr),
|
|
|
|
|
struct PropertyRNA *prop,
|
|
|
|
|
void *user_data)
|
|
|
|
|
{
|
|
|
|
|
uiTemplateOperatorPropertyPollParam *params = user_data;
|
|
|
|
|
|
|
|
|
|
if ((params->flag & UI_TEMPLATE_OP_PROPS_HIDE_ADVANCED) &&
|
|
|
|
|
(RNA_property_tags(prop) & OP_PROP_TAG_ADVANCED)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return params->op->type->poll_property(params->C, params->op, prop);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static eAutoPropButsReturn template_operator_property_buts_draw_single(
|
|
|
|
|
const bContext *C,
|
|
|
|
|
wmOperator *op,
|
|
|
|
|
uiLayout *layout,
|
|
|
|
|
const eButLabelAlign label_align,
|
|
|
|
|
int layout_flags)
|
|
|
|
|
{
|
|
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
|
|
|
|
eAutoPropButsReturn return_info = 0;
|
|
|
|
|
|
|
|
|
|
if (!op->properties) {
|
2020-08-26 10:11:13 +10:00
|
|
|
const IDPropertyTemplate val = {0};
|
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
|
|
|
op->properties = IDP_New(IDP_GROUP, &val, "wmOperatorProperties");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* poll() on this operator may still fail,
|
|
|
|
|
* at the moment there is no nice feedback when this happens just fails silently. */
|
|
|
|
|
if (!WM_operator_repeat_check(C, op)) {
|
|
|
|
|
UI_block_lock_set(block, true, "Operator can't' redo");
|
|
|
|
|
return return_info;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
|
|
|
|
|
/* useful for macros where only one of the steps can't be re-done */
|
|
|
|
|
UI_block_lock_clear(block);
|
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 (layout_flags & UI_TEMPLATE_OP_PROPS_SHOW_TITLE) {
|
|
|
|
|
uiItemL(layout, WM_operatortype_name(op->type, op->ptr), ICON_NONE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* menu */
|
|
|
|
|
if (op->type->flag & OPTYPE_PRESET) {
|
|
|
|
|
/* XXX, no simple way to get WM_MT_operator_presets.bl_label
|
|
|
|
|
* from python! Label remains the same always! */
|
|
|
|
|
PointerRNA op_ptr;
|
|
|
|
|
uiLayout *row;
|
|
|
|
|
|
|
|
|
|
block->ui_operator = op;
|
|
|
|
|
|
|
|
|
|
row = uiLayoutRow(layout, true);
|
|
|
|
|
uiItemM(row, "WM_MT_operator_presets", NULL, ICON_NONE);
|
|
|
|
|
|
|
|
|
|
wmOperatorType *ot = WM_operatortype_find("WM_OT_operator_preset_add", false);
|
|
|
|
|
uiItemFullO_ptr(row, ot, "", ICON_ADD, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
|
|
|
|
|
RNA_string_set(&op_ptr, "operator", op->type->idname);
|
|
|
|
|
|
|
|
|
|
uiItemFullO_ptr(row, ot, "", ICON_REMOVE, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
|
|
|
|
|
RNA_string_set(&op_ptr, "operator", op->type->idname);
|
|
|
|
|
RNA_boolean_set(&op_ptr, "remove_active", true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (op->type->ui) {
|
|
|
|
|
op->layout = layout;
|
|
|
|
|
op->type->ui((bContext *)C, op);
|
|
|
|
|
op->layout = NULL;
|
|
|
|
|
|
|
|
|
|
/* UI_LAYOUT_OP_SHOW_EMPTY ignored. retun_info is ignored too. We could
|
|
|
|
|
* allow ot.ui callback to return this, but not needed right now. */
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
|
|
|
|
uiTemplateOperatorPropertyPollParam user_data = {.C = C, .op = op, .flag = layout_flags};
|
|
|
|
|
const bool use_prop_split = (layout_flags & UI_TEMPLATE_OP_PROPS_NO_SPLIT_LAYOUT) == 0;
|
|
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
PointerRNA ptr;
|
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_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
|
|
|
|
|
|
|
|
|
|
uiLayoutSetPropSep(layout, use_prop_split);
|
|
|
|
|
uiLayoutSetPropDecorate(layout, false);
|
|
|
|
|
|
|
|
|
|
/* main draw call */
|
|
|
|
|
return_info = uiDefAutoButsRNA(
|
|
|
|
|
layout,
|
|
|
|
|
&ptr,
|
|
|
|
|
op->type->poll_property ? ui_layout_operator_buts_poll_property : NULL,
|
|
|
|
|
op->type->poll_property ? &user_data : NULL,
|
|
|
|
|
op->type->prop,
|
|
|
|
|
label_align,
|
|
|
|
|
(layout_flags & UI_TEMPLATE_OP_PROPS_COMPACT));
|
|
|
|
|
|
|
|
|
|
if ((return_info & UI_PROP_BUTS_NONE_ADDED) &&
|
|
|
|
|
(layout_flags & UI_TEMPLATE_OP_PROPS_SHOW_EMPTY)) {
|
|
|
|
|
uiItemL(layout, IFACE_("No Properties"), ICON_NONE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef USE_OP_RESET_BUT
|
|
|
|
|
/* its possible that reset can do nothing if all have PROP_SKIP_SAVE enabled
|
|
|
|
|
* but this is not so important if this button is drawn in those cases
|
|
|
|
|
* (which isn't all that likely anyway) - campbell */
|
|
|
|
|
if (op->properties->len) {
|
|
|
|
|
uiBut *but;
|
|
|
|
|
uiLayout *col; /* needed to avoid alignment errors with previous buttons */
|
|
|
|
|
|
|
|
|
|
col = uiLayoutColumn(layout, false);
|
|
|
|
|
block = uiLayoutGetBlock(col);
|
|
|
|
|
but = uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_FILE_REFRESH,
|
|
|
|
|
IFACE_("Reset"),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
TIP_("Reset operator defaults"));
|
|
|
|
|
UI_but_func_set(but, ui_layout_operator_buts__reset_cb, op, NULL);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* set various special settings for buttons */
|
|
|
|
|
|
|
|
|
|
/* Only do this if we're not refreshing an existing UI. */
|
|
|
|
|
if (block->oldblock == NULL) {
|
|
|
|
|
const bool is_popup = (block->flag & UI_BLOCK_KEEP_OPEN) != 0;
|
|
|
|
|
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
|
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
|
|
|
/* no undo for buttons for operator redo panels */
|
|
|
|
|
UI_but_flag_disable(but, UI_BUT_UNDO);
|
|
|
|
|
|
2020-09-30 20:09:02 +10:00
|
|
|
/* only for popups, see T36109. */
|
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 button is operator's default property, and a text-field, enable focus for it
|
|
|
|
|
* - this is used for allowing operators with popups to rename stuff with fewer clicks
|
|
|
|
|
*/
|
|
|
|
|
if (is_popup) {
|
|
|
|
|
if ((but->rnaprop == op->type->prop) && (but->type == UI_BTYPE_TEXT)) {
|
|
|
|
|
UI_but_focus_on_enter_event(CTX_wm_window(C), but);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return return_info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void template_operator_property_buts_draw_recursive(const bContext *C,
|
|
|
|
|
wmOperator *op,
|
|
|
|
|
uiLayout *layout,
|
|
|
|
|
const eButLabelAlign label_align,
|
|
|
|
|
int layout_flags,
|
|
|
|
|
bool *r_has_advanced)
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
{
|
|
|
|
|
if (op->type->flag & OPTYPE_MACRO) {
|
2020-04-03 19:15:01 +02:00
|
|
|
LISTBASE_FOREACH (wmOperator *, macro_op, &op->macro) {
|
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
|
|
|
template_operator_property_buts_draw_recursive(
|
|
|
|
|
C, macro_op, layout, label_align, layout_flags, r_has_advanced);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Might want to make label_align adjustable somehow. */
|
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
|
|
|
eAutoPropButsReturn return_info = template_operator_property_buts_draw_single(
|
|
|
|
|
C, op, layout, label_align, layout_flags);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
if (return_info & UI_PROP_BUTS_ANY_FAILED_CHECK) {
|
2018-04-25 10:08:04 +02:00
|
|
|
if (r_has_advanced) {
|
|
|
|
|
*r_has_advanced = true;
|
|
|
|
|
}
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
static bool ui_layout_operator_properties_only_booleans(const bContext *C,
|
|
|
|
|
wmWindowManager *wm,
|
|
|
|
|
wmOperator *op,
|
|
|
|
|
int layout_flags)
|
|
|
|
|
{
|
|
|
|
|
if (op->type->flag & OPTYPE_MACRO) {
|
|
|
|
|
LISTBASE_FOREACH (wmOperator *, macro_op, &op->macro) {
|
|
|
|
|
if (!ui_layout_operator_properties_only_booleans(C, wm, macro_op, layout_flags)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
uiTemplateOperatorPropertyPollParam user_data = {.C = C, .op = op, .flag = layout_flags};
|
|
|
|
|
PointerRNA ptr;
|
|
|
|
|
|
|
|
|
|
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
|
|
|
|
|
|
|
|
|
|
RNA_STRUCT_BEGIN (&ptr, prop) {
|
|
|
|
|
if (RNA_property_flag(prop) & PROP_HIDDEN) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (op->type->poll_property &&
|
|
|
|
|
!ui_layout_operator_buts_poll_property(&ptr, prop, &user_data)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (RNA_property_type(prop) != PROP_BOOLEAN) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
RNA_STRUCT_END;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Draw Operator property buttons for redoing execution with different settings.
|
|
|
|
|
* This function does not initialize the layout,
|
|
|
|
|
* functions can be called on the layout before and after.
|
|
|
|
|
*/
|
|
|
|
|
void uiTemplateOperatorPropertyButs(
|
|
|
|
|
const bContext *C, uiLayout *layout, wmOperator *op, eButLabelAlign label_align, short flag)
|
|
|
|
|
{
|
|
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
|
|
|
|
|
|
|
|
|
/* If there are only checkbox items, don't use split layout by default. It looks weird if the
|
|
|
|
|
* checkboxes only use half the width. */
|
|
|
|
|
if (ui_layout_operator_properties_only_booleans(C, wm, op, flag)) {
|
|
|
|
|
flag |= UI_TEMPLATE_OP_PROPS_NO_SPLIT_LAYOUT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template_operator_property_buts_draw_recursive(C, op, layout, label_align, flag, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-02 10:59:20 +02:00
|
|
|
void uiTemplateOperatorRedoProperties(uiLayout *layout, const bContext *C)
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
{
|
|
|
|
|
wmOperator *op = WM_operator_last_redo(C);
|
|
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
|
|
|
|
|
|
|
|
|
if (op == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-25 07:52:40 +02:00
|
|
|
/* Disable for now, doesn't fit well in popover. */
|
|
|
|
|
#if 0
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
/* Repeat button with operator name as text. */
|
2019-04-17 08:24:14 +02:00
|
|
|
uiItemFullO(layout,
|
|
|
|
|
"SCREEN_OT_repeat_last",
|
2019-06-04 15:50:15 +02:00
|
|
|
WM_operatortype_name(op->type, op->ptr),
|
2019-04-17 08:24:14 +02:00
|
|
|
ICON_NONE,
|
|
|
|
|
NULL,
|
|
|
|
|
WM_OP_INVOKE_DEFAULT,
|
|
|
|
|
0,
|
|
|
|
|
NULL);
|
2018-04-25 07:52:40 +02:00
|
|
|
#endif
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
|
|
|
|
|
if (WM_operator_repeat_check(C, op)) {
|
2018-06-13 08:24:56 +02:00
|
|
|
int layout_flags = 0;
|
|
|
|
|
if (block->panel == NULL) {
|
|
|
|
|
layout_flags = UI_TEMPLATE_OP_PROPS_SHOW_TITLE;
|
|
|
|
|
}
|
2018-04-25 10:08:04 +02:00
|
|
|
#if 0
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
bool has_advanced = false;
|
2018-04-25 10:08:04 +02:00
|
|
|
#endif
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
|
2018-12-18 17:22:11 +11:00
|
|
|
UI_block_func_handle_set(block, ED_undo_operator_repeat_cb_evt, op);
|
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
|
|
|
template_operator_property_buts_draw_recursive(
|
|
|
|
|
C, op, layout, UI_BUT_LABEL_ALIGN_NONE, layout_flags, NULL /* &has_advanced */);
|
2018-12-18 17:22:11 +11:00
|
|
|
/* Warning! this leaves the handle function for any other users of this block. */
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
|
2018-04-25 10:08:04 +02:00
|
|
|
#if 0
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
if (has_advanced) {
|
|
|
|
|
uiItemO(layout, IFACE_("More..."), ICON_NONE, "SCREEN_OT_redo_last");
|
|
|
|
|
}
|
2018-04-25 10:08:04 +02:00
|
|
|
#endif
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2020-06-19 12:40:48 -04:00
|
|
|
/** \name Constraint Header Template
|
2019-09-06 16:12:47 +10:00
|
|
|
* \{ */
|
2009-05-27 00:03:49 +00:00
|
|
|
|
2020-06-19 15:07:13 -04:00
|
|
|
#define ERROR_LIBDATA_MESSAGE TIP_("Can't edit external library data")
|
|
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static void constraint_active_func(bContext *UNUSED(C), void *ob_v, void *con_v)
|
2009-05-27 00:03:49 +00:00
|
|
|
{
|
2020-06-05 18:57:12 +10:00
|
|
|
ED_object_constraint_active_set(ob_v, con_v);
|
2009-05-27 00:03:49 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-19 12:40:48 -04:00
|
|
|
static void draw_constraint_header(uiLayout *layout, Object *ob, bConstraint *con)
|
2009-05-27 00:03:49 +00:00
|
|
|
{
|
2012-05-05 16:03:57 +00:00
|
|
|
bPoseChannel *pchan = BKE_pose_channel_active(ob);
|
2012-03-30 01:51:25 +00:00
|
|
|
short proxy_protected, xco = 0, yco = 0;
|
2011-03-28 02:34:55 +00:00
|
|
|
// int rb_col; // UNUSED
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-27 00:03:49 +00:00
|
|
|
/* determine whether constraint is proxy protected or not */
|
2019-03-25 10:15:20 +11:00
|
|
|
if (BKE_constraints_proxylocked_owner(ob, pchan)) {
|
2012-03-30 01:51:25 +00:00
|
|
|
proxy_protected = (con->flag & CONSTRAINT_PROXY_LOCAL) == 0;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-30 01:51:25 +00:00
|
|
|
proxy_protected = 0;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-27 00:03:49 +00:00
|
|
|
/* unless button has own callback, it adds this callback to button */
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_func_set(block, constraint_active_func, ob, con);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
PointerRNA ptr;
|
2009-06-03 00:09:30 +00:00
|
|
|
RNA_pointer_create(&ob->id, &RNA_Constraint, con, &ptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-19 12:40:48 -04:00
|
|
|
uiLayoutSetContextPointer(layout, "constraint", &ptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-19 12:40:48 -04:00
|
|
|
/* Constraint type icon. */
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *sub = uiLayoutRow(layout, false);
|
2020-06-19 12:40:48 -04:00
|
|
|
uiLayoutSetEmboss(sub, false);
|
|
|
|
|
uiLayoutSetRedAlert(sub, (con->flag & CONSTRAINT_DISABLE));
|
|
|
|
|
uiItemL(sub, "", RNA_struct_ui_icon(ptr.type));
|
2019-06-04 18:10:47 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (proxy_protected == 0) {
|
2020-06-19 12:40:48 -04:00
|
|
|
uiItemR(layout, &ptr, "name", 0, "", ICON_NONE);
|
2009-05-27 00:03:49 +00:00
|
|
|
}
|
2019-03-25 10:15:20 +11:00
|
|
|
else {
|
2020-06-19 12:40:48 -04:00
|
|
|
uiItemL(layout, con->name, ICON_NONE);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-27 00:03:49 +00:00
|
|
|
/* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
|
|
|
|
|
if (proxy_protected) {
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-15 23:24:20 +11:00
|
|
|
/* draw a ghost icon (for proxy) and also a lock beside it,
|
|
|
|
|
* to show that constraint is "proxy locked" */
|
2019-04-02 17:51:44 +02:00
|
|
|
uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_GHOST_ENABLED,
|
|
|
|
|
xco + 12.2f * UI_UNIT_X,
|
|
|
|
|
yco,
|
|
|
|
|
0.95f * UI_UNIT_X,
|
|
|
|
|
0.95f * UI_UNIT_Y,
|
2012-11-23 15:33:44 +00:00
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
TIP_("Proxy Protected"));
|
2019-04-02 17:44:18 +02:00
|
|
|
uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_LOCKED,
|
|
|
|
|
xco + 13.1f * UI_UNIT_X,
|
|
|
|
|
yco,
|
2014-11-09 21:20:40 +01:00
|
|
|
0.95f * UI_UNIT_X,
|
|
|
|
|
0.95f * UI_UNIT_Y,
|
2018-09-02 18:28:27 +10:00
|
|
|
NULL,
|
2019-04-17 06:17:24 +02:00
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
2018-09-02 18:28:27 +10:00
|
|
|
TIP_("Proxy Protected"));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-09-02 18:28:27 +10:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-09-02 18:28:27 +10:00
|
|
|
else {
|
2010-09-06 07:26:21 +00:00
|
|
|
/* enabled */
|
2020-12-18 17:13:15 -06:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS);
|
2020-06-19 12:40:48 -04:00
|
|
|
uiItemR(layout, &ptr, "mute", 0, "", 0);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-19 12:40:48 -04:00
|
|
|
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-27 00:03:49 +00:00
|
|
|
/* Close 'button' - emboss calls here disable drawing of 'button' behind X */
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
2020-06-19 12:40:48 -04:00
|
|
|
uiItemO(layout, "", ICON_X, "CONSTRAINT_OT_delete");
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS);
|
2020-06-19 12:40:48 -04:00
|
|
|
|
|
|
|
|
/* Some extra padding at the end, so the 'x' icon isn't too close to drag button. */
|
|
|
|
|
uiItemS(layout);
|
2009-05-27 00:03:49 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-27 00:03:49 +00:00
|
|
|
/* Set but-locks for protected settings (magic numbers are used here!) */
|
2019-03-25 10:15:20 +11:00
|
|
|
if (proxy_protected) {
|
2019-06-11 22:25:01 +02:00
|
|
|
UI_block_lock_set(block, true, TIP_("Cannot edit Proxy-Protected Constraint"));
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-27 00:03:49 +00:00
|
|
|
/* clear any locks set up for proxies/lib-linking */
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_lock_clear(block);
|
2009-05-27 00:03:49 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-19 12:40:48 -04:00
|
|
|
void uiTemplateConstraintHeader(uiLayout *layout, PointerRNA *ptr)
|
2009-05-27 00:03:49 +00:00
|
|
|
{
|
|
|
|
|
/* verify we have valid data */
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
|
2011-09-19 12:26:20 +00:00
|
|
|
RNA_warning("Expected constraint on object");
|
2020-06-19 12:40:48 -04:00
|
|
|
return;
|
2009-05-27 00:03:49 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
Object *ob = (Object *)ptr->owner_id;
|
|
|
|
|
bConstraint *con = ptr->data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!ob || !(GS(ob->id.name) == ID_OB)) {
|
2011-09-19 12:26:20 +00:00
|
|
|
RNA_warning("Expected constraint on object");
|
2020-06-19 12:40:48 -04:00
|
|
|
return;
|
2009-05-27 00:03:49 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-11-06 17:17:10 +01:00
|
|
|
UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-19 12:40:48 -04:00
|
|
|
draw_constraint_header(layout, ob, con);
|
2009-05-27 00:03:49 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Preview Template
|
|
|
|
|
* \{ */
|
2009-05-28 23:41:12 +00:00
|
|
|
|
2019-02-27 12:34:56 +11:00
|
|
|
#include "DNA_light_types.h"
|
2009-05-28 23:41:12 +00:00
|
|
|
#include "DNA_material_types.h"
|
2009-07-21 12:57:55 +00:00
|
|
|
#include "DNA_world_types.h"
|
2009-05-28 23:41:12 +00:00
|
|
|
|
|
|
|
|
#define B_MATPRV 1
|
|
|
|
|
|
2009-06-07 11:12:35 +00:00
|
|
|
static void do_preview_buttons(bContext *C, void *arg, int event)
|
|
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
switch (event) {
|
2009-06-07 11:12:35 +00:00
|
|
|
case B_MATPRV:
|
2013-06-24 22:41:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, arg);
|
2009-06-07 11:12:35 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-05 03:13:47 +10:00
|
|
|
void uiTemplatePreview(uiLayout *layout,
|
2018-07-01 15:47:09 +02:00
|
|
|
bContext *C,
|
|
|
|
|
ID *id,
|
|
|
|
|
bool show_buttons,
|
|
|
|
|
ID *parent,
|
|
|
|
|
MTex *slot,
|
2015-05-05 03:13:47 +10:00
|
|
|
const char *preview_id)
|
2009-05-28 23:41:12 +00:00
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
Material *ma = NULL;
|
|
|
|
|
Tex *tex = (Tex *)id;
|
|
|
|
|
short *pr_texture = NULL;
|
2010-04-04 12:09:59 +00:00
|
|
|
PointerRNA material_ptr;
|
|
|
|
|
PointerRNA texture_ptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
char _preview_id[UI_MAX_NAME_STR];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-07-20 01:30:29 +10:00
|
|
|
if (id && !ELEM(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA, ID_LS)) {
|
2018-06-27 14:41:53 +02:00
|
|
|
RNA_warning("Expected ID of type material, texture, light, world or line style");
|
2009-05-28 23:41:12 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-07-21 01:57:46 +00:00
|
|
|
/* decide what to render */
|
2020-10-04 22:44:19 -05:00
|
|
|
ID *pid = id;
|
|
|
|
|
ID *pparent = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (id && (GS(id->name) == ID_TE)) {
|
2019-03-25 10:15:20 +11:00
|
|
|
if (parent && (GS(parent->name) == ID_MA)) {
|
2012-03-30 01:51:25 +00:00
|
|
|
pr_texture = &((Material *)parent)->pr_texture;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-11-23 15:33:44 +00:00
|
|
|
else if (parent && (GS(parent->name) == ID_WO)) {
|
2014-05-03 18:51:53 +09:00
|
|
|
pr_texture = &((World *)parent)->pr_texture;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-03-25 10:15:20 +11:00
|
|
|
else if (parent && (GS(parent->name) == ID_LA)) {
|
2019-02-27 10:46:48 +11:00
|
|
|
pr_texture = &((Light *)parent)->pr_texture;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
else if (parent && (GS(parent->name) == ID_LS)) {
|
2012-03-30 01:51:25 +00:00
|
|
|
pr_texture = &((FreestyleLineStyle *)parent)->pr_texture;
|
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 (pr_texture) {
|
2019-02-27 10:46:48 +11:00
|
|
|
if (*pr_texture == TEX_PR_OTHER) {
|
|
|
|
|
pid = parent;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
else if (*pr_texture == TEX_PR_BOTH) {
|
|
|
|
|
pparent = parent;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!preview_id || (preview_id[0] == '\0')) {
|
2014-05-03 18:51:53 +09:00
|
|
|
/* If no identifier given, generate one from ID type. */
|
2020-03-20 12:23:04 +11:00
|
|
|
BLI_snprintf(
|
|
|
|
|
_preview_id, UI_MAX_NAME_STR, "uiPreview_%s", BKE_idtype_idcode_to_name(GS(id->name)));
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
preview_id = _preview_id;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2014-05-03 18:51:53 +09:00
|
|
|
/* Find or add the uiPreview to the current Region. */
|
2020-10-04 22:44:19 -05:00
|
|
|
ARegion *region = CTX_wm_region(C);
|
|
|
|
|
uiPreview *ui_preview = BLI_findstring(
|
|
|
|
|
®ion->ui_previews, preview_id, offsetof(uiPreview, preview_id));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!ui_preview) {
|
|
|
|
|
ui_preview = MEM_callocN(sizeof(uiPreview), "uiPreview");
|
2012-03-30 01:51:25 +00:00
|
|
|
BLI_strncpy(ui_preview->preview_id, preview_id, sizeof(ui_preview->preview_id));
|
2019-03-25 10:15:20 +11:00
|
|
|
ui_preview->height = (short)(UI_UNIT_Y * 7.6f);
|
2020-03-06 16:56:42 +01:00
|
|
|
BLI_addtail(®ion->ui_previews, ui_preview);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
if (ui_preview->height < UI_UNIT_Y) {
|
|
|
|
|
ui_preview->height = UI_UNIT_Y;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
else if (ui_preview->height > UI_UNIT_Y * 50) { /* Rather high upper limit, yet not insane! */
|
|
|
|
|
ui_preview->height = UI_UNIT_Y * 50;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2009-07-21 01:57:46 +00:00
|
|
|
/* layout */
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
|
|
|
|
uiLayout *row = uiLayoutRow(layout, false);
|
|
|
|
|
uiLayout *col = uiLayoutColumn(row, false);
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
uiLayoutSetKeepAspect(col, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
/* add preview */
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block,
|
2016-02-25 11:54:30 +11:00
|
|
|
UI_BTYPE_EXTRA,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
ui_preview->height,
|
|
|
|
|
pid,
|
2019-04-17 06:17:24 +02:00
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
UI_but_func_drawextra_set(block, ED_preview_draw, pparent, slot);
|
|
|
|
|
UI_block_func_handle_set(block, do_preview_buttons, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
uiDefIconButS(block,
|
|
|
|
|
UI_BTYPE_GRIP,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2014-11-09 21:20:40 +01:00
|
|
|
ICON_GRIP,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
2019-04-14 18:41:10 +02:00
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
(short)(UI_UNIT_Y * 0.3f),
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
&ui_preview->height,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
UI_UNIT_Y * 50.0f,
|
2019-04-17 06:17:24 +02:00
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
"");
|
|
|
|
|
|
2009-07-21 01:57:46 +00:00
|
|
|
/* add buttons */
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
if (pid && show_buttons) {
|
|
|
|
|
if (GS(pid->name) == ID_MA || (pparent && GS(pparent->name) == ID_MA)) {
|
2012-11-23 15:33:44 +00:00
|
|
|
if (GS(pid->name) == ID_MA) {
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
ma = (Material *)pid;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
else {
|
2019-03-25 10:15:20 +11:00
|
|
|
ma = (Material *)pparent;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
Add drag-resize to uiTemplatePreview (mat/tex/etc. preview widget).
This is done by adding a new button type, GRIP, similar to other numbuttons
(scroll, slider, ...), which here controls the preview height.
Then, we add a new DNA struct to be able to save that height in Blend files
(note I choose not to use Panel struct for this, because we would then have the
same limitation we used to have with uiLists, only one preview per panel
and no preview outside panel).
This implies a change to template_preview UI RNA/py API (each preview needs an ID),
but this is backward compatible, as by default datablock type will be used if no ID is
given (which means e.g. all material previews with no ID will have same height).
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D342
2014-04-02 12:59:48 +02:00
|
|
|
/* Create RNA Pointer */
|
2014-01-04 17:16:19 +11:00
|
|
|
RNA_pointer_create(&ma->id, &RNA_Material, ma, &material_ptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
col = uiLayoutColumn(row, true);
|
|
|
|
|
uiLayoutSetScaleX(col, 1.5);
|
2014-11-09 21:20:40 +01:00
|
|
|
uiItemR(col, &material_ptr, "preview_render_type", UI_ITEM_R_EXPAND, "", ICON_NONE);
|
2020-01-28 14:34:35 +01:00
|
|
|
|
|
|
|
|
/* EEVEE preview file has baked lighting so use_preview_world has no effect,
|
|
|
|
|
* just hide the option until this feature is supported. */
|
|
|
|
|
if (!BKE_scene_uses_blender_eevee(CTX_data_scene(C))) {
|
|
|
|
|
uiItemS(col);
|
|
|
|
|
uiItemR(col, &material_ptr, "use_preview_world", 0, "", ICON_WORLD);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-01 19:57:31 +02:00
|
|
|
if (pr_texture) {
|
|
|
|
|
/* Create RNA Pointer */
|
2010-04-04 12:09:59 +00:00
|
|
|
RNA_pointer_create(id, &RNA_Texture, tex, &texture_ptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-01 19:57:31 +02:00
|
|
|
uiLayoutRow(layout, true);
|
|
|
|
|
uiDefButS(block,
|
|
|
|
|
UI_BTYPE_ROW,
|
|
|
|
|
B_MATPRV,
|
|
|
|
|
IFACE_("Texture"),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
pr_texture,
|
|
|
|
|
10,
|
2012-11-23 15:33:44 +00:00
|
|
|
TEX_PR_TEXTURE,
|
2018-07-01 19:57:31 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
2012-03-24 06:38:07 +00:00
|
|
|
if (GS(parent->name) == ID_MA) {
|
|
|
|
|
uiDefButS(block,
|
2015-05-24 22:18:16 +10:00
|
|
|
UI_BTYPE_ROW,
|
2012-03-24 06:38:07 +00:00
|
|
|
B_MATPRV,
|
|
|
|
|
IFACE_("Material"),
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_UNIT_X * 10,
|
2014-04-02 13:09:43 +02:00
|
|
|
UI_UNIT_Y,
|
2012-03-24 06:38:07 +00:00
|
|
|
pr_texture,
|
2019-04-17 06:17:24 +02:00
|
|
|
10,
|
2012-11-23 15:33:44 +00:00
|
|
|
TEX_PR_OTHER,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
}
|
2019-03-25 10:15:20 +11:00
|
|
|
else if (GS(parent->name) == ID_LA) {
|
2010-04-04 12:09:59 +00:00
|
|
|
uiDefButS(block,
|
2011-02-27 18:03:19 +00:00
|
|
|
UI_BTYPE_ROW,
|
|
|
|
|
B_MATPRV,
|
|
|
|
|
CTX_IFACE_(BLT_I18NCONTEXT_ID_LIGHT, "Light"),
|
|
|
|
|
0,
|
2019-04-14 18:41:10 +02:00
|
|
|
0,
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
UI_UNIT_Y,
|
2012-11-23 15:33:44 +00:00
|
|
|
pr_texture,
|
|
|
|
|
10,
|
|
|
|
|
TEX_PR_OTHER,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
}
|
|
|
|
|
else if (GS(parent->name) == ID_WO) {
|
2019-02-12 22:13:42 +01:00
|
|
|
uiDefButS(block,
|
|
|
|
|
UI_BTYPE_ROW,
|
|
|
|
|
B_MATPRV,
|
|
|
|
|
IFACE_("World"),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
UI_UNIT_Y,
|
2012-11-23 15:33:44 +00:00
|
|
|
pr_texture,
|
|
|
|
|
10,
|
|
|
|
|
TEX_PR_OTHER,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
}
|
2014-05-03 18:51:53 +09:00
|
|
|
else if (GS(parent->name) == ID_LS) {
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefButS(block,
|
|
|
|
|
UI_BTYPE_ROW,
|
|
|
|
|
B_MATPRV,
|
|
|
|
|
IFACE_("Line Style"),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
UI_UNIT_Y,
|
2014-05-03 18:51:53 +09:00
|
|
|
pr_texture,
|
|
|
|
|
10,
|
|
|
|
|
TEX_PR_OTHER,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
}
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefButS(block,
|
|
|
|
|
UI_BTYPE_ROW,
|
|
|
|
|
B_MATPRV,
|
|
|
|
|
IFACE_("Both"),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
UI_UNIT_Y,
|
2012-11-23 15:33:44 +00:00
|
|
|
pr_texture,
|
|
|
|
|
10,
|
|
|
|
|
TEX_PR_BOTH,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-12-04 16:55:46 +00:00
|
|
|
/* Alpha button for texture preview */
|
2012-03-30 01:51:25 +00:00
|
|
|
if (*pr_texture != TEX_PR_OTHER) {
|
2014-01-04 17:16:19 +11:00
|
|
|
row = uiLayoutRow(layout, false);
|
2011-02-27 18:03:19 +00:00
|
|
|
uiItemR(row, &texture_ptr, "use_preview_alpha", 0, NULL, ICON_NONE);
|
2009-07-21 01:57:46 +00:00
|
|
|
}
|
2009-05-28 23:41:12 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2009-05-28 23:41:12 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name ColorRamp Template
|
|
|
|
|
* \{ */
|
2009-06-03 00:14:12 +00:00
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
typedef struct RNAUpdateCb {
|
|
|
|
|
PointerRNA ptr;
|
|
|
|
|
PropertyRNA *prop;
|
|
|
|
|
} RNAUpdateCb;
|
|
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
|
2009-09-16 18:47:42 +00:00
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
RNAUpdateCb *cb = (RNAUpdateCb *)arg_cb;
|
2009-09-16 18:47:42 +00:00
|
|
|
|
|
|
|
|
/* we call update here on the pointer property, this way the
|
2012-03-03 16:31:46 +00:00
|
|
|
* owner of the curve mapping can still define its own update
|
|
|
|
|
* and notifier, even if the CurveMapping struct is shared. */
|
2009-09-16 18:47:42 +00:00
|
|
|
RNA_property_update(C, &cb->ptr, cb->prop);
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-19 16:15:05 +00:00
|
|
|
enum {
|
|
|
|
|
CB_FUNC_FLIP,
|
|
|
|
|
CB_FUNC_DISTRIBUTE_LR,
|
|
|
|
|
CB_FUNC_DISTRIBUTE_EVENLY,
|
|
|
|
|
CB_FUNC_RESET,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void colorband_flip_cb(bContext *C, ColorBand *coba)
|
|
|
|
|
{
|
|
|
|
|
CBData data_tmp[MAXCOLORBAND];
|
|
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
for (int a = 0; a < coba->tot; a++) {
|
2018-11-19 16:15:05 +00:00
|
|
|
data_tmp[a] = coba->data[coba->tot - (a + 1)];
|
|
|
|
|
}
|
2020-10-04 22:44:19 -05:00
|
|
|
for (int a = 0; a < coba->tot; a++) {
|
2018-11-19 16:15:05 +00:00
|
|
|
data_tmp[a].pos = 1.0f - data_tmp[a].pos;
|
|
|
|
|
coba->data[a] = data_tmp[a];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* may as well flip the cur*/
|
|
|
|
|
coba->cur = coba->tot - (coba->cur + 1);
|
|
|
|
|
|
|
|
|
|
ED_undo_push(C, "Flip Color Ramp");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void colorband_distribute_cb(bContext *C, ColorBand *coba, bool evenly)
|
|
|
|
|
{
|
|
|
|
|
if (coba->tot > 1) {
|
2020-08-26 10:11:13 +10:00
|
|
|
const int tot = evenly ? coba->tot - 1 : coba->tot;
|
|
|
|
|
const float gap = 1.0f / tot;
|
2018-11-19 16:15:05 +00:00
|
|
|
float pos = 0.0f;
|
2020-10-04 22:44:19 -05:00
|
|
|
for (int a = 0; a < coba->tot; a++) {
|
2018-11-19 16:15:05 +00:00
|
|
|
coba->data[a].pos = pos;
|
|
|
|
|
pos += gap;
|
|
|
|
|
}
|
|
|
|
|
ED_undo_push(C, evenly ? "Distribute Stops Evenly" : "Distribute Stops from Left");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void colorband_tools_dofunc(bContext *C, void *coba_v, int event)
|
|
|
|
|
{
|
|
|
|
|
ColorBand *coba = coba_v;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-11-19 16:15:05 +00:00
|
|
|
switch (event) {
|
|
|
|
|
case CB_FUNC_FLIP:
|
|
|
|
|
colorband_flip_cb(C, coba);
|
|
|
|
|
break;
|
|
|
|
|
case CB_FUNC_DISTRIBUTE_LR:
|
|
|
|
|
colorband_distribute_cb(C, coba, false);
|
|
|
|
|
break;
|
|
|
|
|
case CB_FUNC_DISTRIBUTE_EVENLY:
|
|
|
|
|
colorband_distribute_cb(C, coba, true);
|
|
|
|
|
break;
|
|
|
|
|
case CB_FUNC_RESET:
|
|
|
|
|
BKE_colorband_init(coba, true);
|
|
|
|
|
ED_undo_push(C, "Reset Color Ramp");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *colorband_tools_func(bContext *C, ARegion *region, void *coba_v)
|
2018-11-19 16:15:05 +00:00
|
|
|
{
|
2020-03-15 17:32:25 +11:00
|
|
|
const uiStyle *style = UI_style_get_dpi();
|
2018-11-21 05:32:23 +11:00
|
|
|
ColorBand *coba = coba_v;
|
2020-10-04 22:44:19 -05:00
|
|
|
short yco = 0;
|
2021-01-04 17:02:13 +11:00
|
|
|
const short menuwidth = 10 * UI_UNIT_X;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS_PULLDOWN);
|
2018-11-19 16:15:05 +00:00
|
|
|
UI_block_func_butmenu_set(block, colorband_tools_dofunc, coba);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-18 17:41:37 +11:00
|
|
|
uiLayout *layout = UI_block_layout(block,
|
|
|
|
|
UI_LAYOUT_VERTICAL,
|
|
|
|
|
UI_LAYOUT_MENU,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_MENU_WIDTH_MIN,
|
|
|
|
|
0,
|
|
|
|
|
UI_MENU_PADDING,
|
|
|
|
|
style);
|
|
|
|
|
UI_block_layout_set_current(block, layout);
|
|
|
|
|
{
|
|
|
|
|
PointerRNA coba_ptr;
|
|
|
|
|
RNA_pointer_create(NULL, &RNA_ColorRamp, coba, &coba_ptr);
|
|
|
|
|
uiLayoutSetContextPointer(layout, "color_ramp", &coba_ptr);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-18 17:41:37 +11:00
|
|
|
/* We could move these to operators,
|
|
|
|
|
* although this isn't important unless we want to assign key shortcuts to them. */
|
2018-11-19 16:15:05 +00:00
|
|
|
{
|
|
|
|
|
uiDefIconTextBut(block,
|
2018-11-21 05:32:23 +11:00
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Flip Color Ramp"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
|
|
|
|
menuwidth,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
CB_FUNC_FLIP,
|
|
|
|
|
"");
|
2018-11-19 16:15:05 +00:00
|
|
|
uiDefIconTextBut(block,
|
2018-11-21 05:32:23 +11:00
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Distribute Stops from Left"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
|
|
|
|
menuwidth,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
CB_FUNC_DISTRIBUTE_LR,
|
|
|
|
|
"");
|
2018-11-19 16:15:05 +00:00
|
|
|
uiDefIconTextBut(block,
|
2018-11-21 05:32:23 +11:00
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Distribute Stops Evenly"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
|
|
|
|
menuwidth,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
CB_FUNC_DISTRIBUTE_EVENLY,
|
|
|
|
|
"");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-18 18:20:44 +11:00
|
|
|
uiItemO(layout, IFACE_("Eyedropper"), ICON_EYEDROPPER, "UI_OT_eyedropper_colorramp");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-11-19 16:15:05 +00:00
|
|
|
uiDefIconTextBut(block,
|
2018-11-21 05:32:23 +11:00
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Reset Color Ramp"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
|
|
|
|
menuwidth,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
CB_FUNC_RESET,
|
|
|
|
|
"");
|
2018-11-19 16:15:05 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-11-19 16:15:05 +00:00
|
|
|
UI_block_direction_set(block, UI_DIR_DOWN);
|
|
|
|
|
UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-11-19 16:15:05 +00:00
|
|
|
return block;
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
static void colorband_add_cb(bContext *C, void *cb_v, void *coba_v)
|
2009-06-03 00:14:12 +00:00
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
ColorBand *coba = coba_v;
|
|
|
|
|
float pos = 0.5f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (coba->tot > 1) {
|
2019-03-25 10:15:20 +11:00
|
|
|
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;
|
|
|
|
|
}
|
2010-04-28 09:29:17 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-12-07 15:52:59 +11:00
|
|
|
if (BKE_colorband_element_add(coba, pos)) {
|
2010-07-30 00:20:05 +00:00
|
|
|
rna_update_cb(C, cb_v, NULL);
|
2018-11-19 16:15:05 +00:00
|
|
|
ED_undo_push(C, "Add Color Ramp Stop");
|
2010-07-30 00:20:05 +00:00
|
|
|
}
|
2009-09-16 18:47:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void colorband_del_cb(bContext *C, void *cb_v, void *coba_v)
|
|
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
ColorBand *coba = coba_v;
|
2009-09-16 18:47:42 +00:00
|
|
|
|
2017-12-07 15:52:59 +11:00
|
|
|
if (BKE_colorband_element_remove(coba, coba->cur)) {
|
2018-11-19 16:15:05 +00:00
|
|
|
ED_undo_push(C, "Delete Color Ramp Stop");
|
2010-07-30 00:20:05 +00:00
|
|
|
rna_update_cb(C, cb_v, NULL);
|
2009-09-16 18:47:42 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-02 14:07:24 +00:00
|
|
|
static void colorband_update_cb(bContext *UNUSED(C), void *bt_v, void *coba_v)
|
|
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
uiBut *bt = bt_v;
|
|
|
|
|
ColorBand *coba = coba_v;
|
2012-02-02 14:07:24 +00:00
|
|
|
|
2019-06-12 09:04:10 +10:00
|
|
|
/* Sneaky update here, we need to sort the color-band points to be in order,
|
2012-03-03 16:31:46 +00:00
|
|
|
* however the RNA pointer then is wrong, so we update it */
|
2017-12-07 15:52:59 +11:00
|
|
|
BKE_colorband_update_sort(coba);
|
2012-02-02 14:07:24 +00:00
|
|
|
bt->rnapoin.data = coba->data + coba->cur;
|
|
|
|
|
}
|
2009-09-16 18:47:42 +00:00
|
|
|
|
2015-05-05 03:13:47 +10:00
|
|
|
static void colorband_buttons_layout(uiLayout *layout,
|
|
|
|
|
uiBlock *block,
|
|
|
|
|
ColorBand *coba,
|
|
|
|
|
const rctf *butr,
|
|
|
|
|
RNAUpdateCb *cb,
|
|
|
|
|
int expand)
|
2009-09-16 18:47:42 +00:00
|
|
|
{
|
|
|
|
|
uiBut *bt;
|
2020-08-26 10:11:13 +10:00
|
|
|
const float unit = BLI_rctf_size_x(butr) / 14.0f;
|
|
|
|
|
const float xs = butr->xmin;
|
|
|
|
|
const float ys = butr->ymin;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
PointerRNA ptr;
|
2019-08-23 09:52:12 +02:00
|
|
|
RNA_pointer_create(cb->ptr.owner_id, &RNA_ColorRamp, coba, &ptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *split = uiLayoutSplit(layout, 0.4f, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
|
|
|
|
UI_block_align_begin(block);
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *row = uiLayoutRow(split, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-01 19:57:31 +02:00
|
|
|
bt = uiDefIconTextBut(block,
|
2018-10-01 10:45:50 +02:00
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_ADD,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
2.0f * unit,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
2018-11-19 16:15:05 +00:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
TIP_("Add a new color stop to the color ramp"));
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_funcN_set(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-01 19:57:31 +02:00
|
|
|
bt = uiDefIconTextBut(block,
|
2018-10-01 10:45:50 +02:00
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_REMOVE,
|
|
|
|
|
"",
|
|
|
|
|
xs + 2.0f * unit,
|
|
|
|
|
ys + UI_UNIT_Y,
|
|
|
|
|
2.0f * unit,
|
|
|
|
|
UI_UNIT_Y,
|
2018-07-01 19:57:31 +02:00
|
|
|
NULL,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
TIP_("Delete the active position"));
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_funcN_set(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-11-19 16:15:05 +00:00
|
|
|
bt = uiDefIconBlockBut(block,
|
|
|
|
|
colorband_tools_func,
|
|
|
|
|
coba,
|
|
|
|
|
0,
|
|
|
|
|
ICON_DOWNARROW_HLT,
|
|
|
|
|
xs + 4.0f * unit,
|
|
|
|
|
ys + UI_UNIT_Y,
|
|
|
|
|
2.0f * unit,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
TIP_("Tools"));
|
|
|
|
|
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), coba);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_end(block);
|
|
|
|
|
UI_block_emboss_set(block, UI_EMBOSS);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
row = uiLayoutRow(split, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_begin(block);
|
2014-08-15 15:29:08 +10:00
|
|
|
uiItemR(row, &ptr, "color_mode", 0, "", ICON_NONE);
|
|
|
|
|
if (ELEM(coba->color_mode, COLBAND_BLEND_HSV, COLBAND_BLEND_HSL)) {
|
|
|
|
|
uiItemR(row, &ptr, "hue_interpolation", 0, "", ICON_NONE);
|
|
|
|
|
}
|
|
|
|
|
else { /* COLBAND_BLEND_RGB */
|
|
|
|
|
uiItemR(row, &ptr, "interpolation", 0, "", ICON_NONE);
|
|
|
|
|
}
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_end(block);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
row = uiLayoutRow(layout, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
bt = uiDefBut(block,
|
|
|
|
|
UI_BTYPE_COLORBAND,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
xs,
|
|
|
|
|
ys,
|
|
|
|
|
BLI_rctf_size_x(butr),
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
coba,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
row = uiLayoutRow(layout, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-12-10 17:11:03 +01:00
|
|
|
if (coba->tot) {
|
|
|
|
|
CBData *cbd = coba->data + coba->cur;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-23 09:52:12 +02:00
|
|
|
RNA_pointer_create(cb->ptr.owner_id, &RNA_ColorRampElement, cbd, &ptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-12-13 17:18:48 +01:00
|
|
|
if (!expand) {
|
2014-01-04 17:16:19 +11:00
|
|
|
split = uiLayoutSplit(layout, 0.3f, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
row = uiLayoutRow(split, false);
|
2020-09-04 21:18:45 +02:00
|
|
|
bt = uiDefButS(block,
|
|
|
|
|
UI_BTYPE_NUM,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
5.0f * UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
&coba->cur,
|
|
|
|
|
0.0,
|
|
|
|
|
(float)(MAX2(0, coba->tot - 1)),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
TIP_("Choose active color stop"));
|
|
|
|
|
UI_but_number_step_size_set(bt, 1);
|
|
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
row = uiLayoutRow(split, false);
|
2013-12-13 17:18:48 +01:00
|
|
|
uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE);
|
|
|
|
|
bt = block->buttons.last;
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_func_set(bt, colorband_update_cb, bt, coba);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
row = uiLayoutRow(layout, false);
|
2013-12-13 17:18:48 +01:00
|
|
|
uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
|
2014-03-11 21:19:59 +11:00
|
|
|
bt = block->buttons.last;
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
|
2013-12-13 17:18:48 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2014-01-04 17:16:19 +11:00
|
|
|
split = uiLayoutSplit(layout, 0.5f, false);
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *subsplit = uiLayoutSplit(split, 0.35f, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
row = uiLayoutRow(subsplit, false);
|
2020-09-04 21:18:45 +02:00
|
|
|
bt = uiDefButS(block,
|
|
|
|
|
UI_BTYPE_NUM,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
5.0f * UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
&coba->cur,
|
|
|
|
|
0.0,
|
|
|
|
|
(float)(MAX2(0, coba->tot - 1)),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
TIP_("Choose active color stop"));
|
|
|
|
|
UI_but_number_step_size_set(bt, 1);
|
|
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
row = uiLayoutRow(subsplit, false);
|
2014-08-15 15:29:08 +10:00
|
|
|
uiItemR(row, &ptr, "position", UI_ITEM_R_SLIDER, IFACE_("Pos"), ICON_NONE);
|
2013-12-13 17:18:48 +01:00
|
|
|
bt = block->buttons.last;
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_func_set(bt, colorband_update_cb, bt, coba);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
row = uiLayoutRow(split, false);
|
2013-12-13 17:18:48 +01:00
|
|
|
uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
|
2014-03-11 21:19:59 +11:00
|
|
|
bt = block->buttons.last;
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
|
2013-12-10 17:11:03 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2009-09-16 18:47:42 +00:00
|
|
|
}
|
|
|
|
|
|
2018-07-01 15:47:09 +02:00
|
|
|
void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname, bool expand)
|
2009-09-16 18:47:42 +00:00
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
2009-06-03 00:14:12 +00:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!prop || RNA_property_type(prop) != PROP_POINTER) {
|
2009-09-16 18:47:42 +00:00
|
|
|
return;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2009-09-16 18:47:42 +00:00
|
|
|
|
2021-01-04 17:02:13 +11:00
|
|
|
const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_ColorRamp)) {
|
2009-09-16 18:47:42 +00:00
|
|
|
return;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2009-09-16 18:47:42 +00:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
RNAUpdateCb *cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
|
2012-03-30 01:51:25 +00:00
|
|
|
cb->ptr = *ptr;
|
|
|
|
|
cb->prop = prop;
|
2009-09-16 18:47:42 +00:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
rctf rect;
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
rect.xmin = 0;
|
|
|
|
|
rect.xmax = 10.0f * UI_UNIT_X;
|
|
|
|
|
rect.ymin = 0;
|
|
|
|
|
rect.ymax = 19.5f * UI_UNIT_X;
|
2009-09-16 18:47:42 +00:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutAbsoluteBlock(layout);
|
2014-01-29 19:02:32 +01:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
ID *id = cptr.owner_id;
|
2017-11-06 17:17:10 +01:00
|
|
|
UI_block_lock_set(block, (id && ID_IS_LINKED(id)), ERROR_LIBDATA_MESSAGE);
|
2014-01-29 19:02:32 +01:00
|
|
|
|
2013-12-13 17:18:48 +01:00
|
|
|
colorband_buttons_layout(layout, block, cptr.data, &rect, cb, expand);
|
2009-09-16 18:47:42 +00:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_lock_clear(block);
|
2014-01-29 19:02:32 +01:00
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
MEM_freeN(cb);
|
2009-06-03 00:14:12 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Icon Template
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2018-06-14 10:38:17 +02:00
|
|
|
/**
|
|
|
|
|
* \param icon_scale: Scale of the icon, 1x == button height.
|
|
|
|
|
*/
|
|
|
|
|
void uiTemplateIcon(uiLayout *layout, int icon_value, float icon_scale)
|
|
|
|
|
{
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutAbsoluteBlock(layout);
|
|
|
|
|
uiBut *but = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_LABEL,
|
|
|
|
|
0,
|
|
|
|
|
ICON_X,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * icon_scale,
|
|
|
|
|
UI_UNIT_Y * icon_scale,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
"");
|
2018-06-14 10:38:17 +02:00
|
|
|
ui_def_but_icon(but, icon_value, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
|
|
|
|
|
}
|
2013-01-22 11:18:41 +00:00
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Icon viewer Template
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2015-05-22 21:31:26 +01:00
|
|
|
typedef struct IconViewMenuArgs {
|
|
|
|
|
PointerRNA ptr;
|
|
|
|
|
PropertyRNA *prop;
|
2015-07-14 01:46:25 +10:00
|
|
|
bool show_labels;
|
|
|
|
|
float icon_scale;
|
2015-05-22 21:31:26 +01:00
|
|
|
} IconViewMenuArgs;
|
2013-01-22 11:18:41 +00:00
|
|
|
|
|
|
|
|
/* ID Search browse menu, open */
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *ui_icon_view_menu_cb(bContext *C, ARegion *region, void *arg_litem)
|
2013-01-22 11:18:41 +00:00
|
|
|
{
|
2015-05-22 21:31:26 +01:00
|
|
|
static IconViewMenuArgs args;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-01-22 11:18:41 +00:00
|
|
|
/* arg_litem is malloced, can be freed by parent button */
|
2015-05-22 21:31:26 +01:00
|
|
|
args = *((IconViewMenuArgs *)arg_litem);
|
2021-01-04 17:02:13 +11:00
|
|
|
const int w = UI_UNIT_X * (args.icon_scale);
|
|
|
|
|
const int h = UI_UNIT_X * (args.icon_scale + args.show_labels);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS_PULLDOWN);
|
2016-01-15 15:19:14 +01:00
|
|
|
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NO_FLIP);
|
2018-09-11 10:56:08 +10:00
|
|
|
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
bool free;
|
|
|
|
|
const EnumPropertyItem *item;
|
2015-05-22 21:31:26 +01:00
|
|
|
RNA_property_enum_items(C, &args.ptr, args.prop, &item, NULL, &free);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
for (int a = 0; item[a].identifier; a++) {
|
2021-01-04 17:02:13 +11:00
|
|
|
const int x = (a % 8) * w;
|
|
|
|
|
const int y = -(a / 8) * h;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-04 17:02:13 +11:00
|
|
|
const int icon = item[a].icon;
|
|
|
|
|
const int value = item[a].value;
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBut *but;
|
2015-05-24 22:18:16 +10:00
|
|
|
if (args.show_labels) {
|
|
|
|
|
but = uiDefIconTextButR_prop(block,
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_BTYPE_ROW,
|
2015-05-24 22:18:16 +10:00
|
|
|
0,
|
|
|
|
|
icon,
|
|
|
|
|
item[a].name,
|
|
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
w,
|
|
|
|
|
h,
|
|
|
|
|
&args.ptr,
|
|
|
|
|
args.prop,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
value,
|
|
|
|
|
-1,
|
|
|
|
|
-1,
|
|
|
|
|
NULL);
|
2015-05-22 21:31:26 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2015-05-24 22:18:16 +10:00
|
|
|
but = uiDefIconButR_prop(block,
|
|
|
|
|
UI_BTYPE_ROW,
|
|
|
|
|
0,
|
|
|
|
|
icon,
|
|
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
w,
|
|
|
|
|
h,
|
|
|
|
|
&args.ptr,
|
|
|
|
|
args.prop,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
value,
|
|
|
|
|
-1,
|
|
|
|
|
-1,
|
|
|
|
|
NULL);
|
2015-05-22 21:31:26 +01:00
|
|
|
}
|
2015-05-11 16:29:12 +02:00
|
|
|
ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
|
2013-01-22 11:18:41 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
|
2015-05-08 19:22:41 +01:00
|
|
|
UI_block_direction_set(block, UI_DIR_DOWN);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-01-22 11:18:41 +00:00
|
|
|
if (free) {
|
2017-10-18 15:07:26 +11:00
|
|
|
MEM_freeN((void *)item);
|
2013-01-22 11:18:41 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-01-22 11:18:41 +00:00
|
|
|
return block;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 01:46:25 +10:00
|
|
|
/**
|
|
|
|
|
* \param icon_scale: Scale of the icon, 1x == button height.
|
|
|
|
|
*/
|
2019-01-02 18:18:54 +11:00
|
|
|
void uiTemplateIconView(uiLayout *layout,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
bool show_labels,
|
|
|
|
|
float icon_scale,
|
|
|
|
|
float icon_scale_popup)
|
2013-01-22 11:18:41 +00:00
|
|
|
{
|
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-29 16:22:04 +01:00
|
|
|
if (!prop || RNA_property_type(prop) != PROP_ENUM) {
|
|
|
|
|
RNA_warning(
|
|
|
|
|
"property of type Enum not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
2013-01-22 11:18:41 +00:00
|
|
|
return;
|
2015-04-29 16:22:04 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutAbsoluteBlock(layout);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
int tot_items;
|
|
|
|
|
bool free_items;
|
|
|
|
|
const EnumPropertyItem *items;
|
2015-04-22 22:40:19 +02:00
|
|
|
RNA_property_enum_items(block->evil_C, ptr, prop, &items, &tot_items, &free_items);
|
2021-01-04 17:02:13 +11:00
|
|
|
const int value = RNA_property_enum_get(ptr, prop);
|
2020-10-04 22:44:19 -05:00
|
|
|
int icon = ICON_NONE;
|
2015-04-22 22:40:19 +02:00
|
|
|
RNA_enum_icon_from_value(items, value, &icon);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBut *but;
|
2018-06-12 08:43:09 +02:00
|
|
|
if (RNA_property_editable(ptr, prop)) {
|
2020-10-04 22:44:19 -05:00
|
|
|
IconViewMenuArgs *cb_args = MEM_callocN(sizeof(IconViewMenuArgs), __func__);
|
2018-06-12 08:43:09 +02:00
|
|
|
cb_args->ptr = *ptr;
|
|
|
|
|
cb_args->prop = prop;
|
|
|
|
|
cb_args->show_labels = show_labels;
|
2019-01-02 18:18:54 +11:00
|
|
|
cb_args->icon_scale = icon_scale_popup;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-02 18:18:54 +11:00
|
|
|
but = uiDefBlockButN(block,
|
|
|
|
|
ui_icon_view_menu_cb,
|
|
|
|
|
cb_args,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * icon_scale,
|
|
|
|
|
UI_UNIT_Y * icon_scale,
|
|
|
|
|
"");
|
2018-06-12 08:43:09 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2019-01-02 18:18:54 +11:00
|
|
|
but = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_LABEL,
|
|
|
|
|
0,
|
|
|
|
|
ICON_X,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * icon_scale,
|
|
|
|
|
UI_UNIT_Y * icon_scale,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
"");
|
2018-06-12 08:43:09 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-05-11 16:29:12 +02:00
|
|
|
ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-22 22:40:19 +02:00
|
|
|
if (free_items) {
|
2017-10-18 15:07:26 +11:00
|
|
|
MEM_freeN((void *)items);
|
2015-04-22 22:40:19 +02:00
|
|
|
}
|
2013-01-22 11:18:41 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Histogram Template
|
|
|
|
|
* \{ */
|
2010-01-19 01:32:06 +00:00
|
|
|
|
2010-11-17 09:45:45 +00:00
|
|
|
void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname)
|
2010-01-19 01:32:06 +00:00
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!prop || RNA_property_type(prop) != PROP_POINTER) {
|
2010-01-19 01:32:06 +00:00
|
|
|
return;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-04 17:02:13 +11:00
|
|
|
const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Histogram)) {
|
2010-01-19 01:32:06 +00:00
|
|
|
return;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2020-10-04 22:44:19 -05:00
|
|
|
Histogram *hist = (Histogram *)cptr.data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-02 13:09:43 +02:00
|
|
|
if (hist->height < UI_UNIT_Y) {
|
|
|
|
|
hist->height = UI_UNIT_Y;
|
|
|
|
|
}
|
|
|
|
|
else if (hist->height > UI_UNIT_Y * 20) {
|
|
|
|
|
hist->height = UI_UNIT_Y * 20;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *col = uiLayoutColumn(layout, true);
|
|
|
|
|
uiBlock *block = uiLayoutGetBlock(col);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(
|
|
|
|
|
block, UI_BTYPE_HISTOGRAM, 0, "", 0, 0, UI_UNIT_X * 10, hist->height, hist, 0, 0, 0, 0, "");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-02 13:09:43 +02:00
|
|
|
/* Resize grip. */
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefIconButI(block,
|
|
|
|
|
UI_BTYPE_GRIP,
|
|
|
|
|
0,
|
|
|
|
|
ICON_GRIP,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
(short)(UI_UNIT_Y * 0.3f),
|
|
|
|
|
&hist->height,
|
2014-04-02 13:09:43 +02:00
|
|
|
UI_UNIT_Y,
|
|
|
|
|
UI_UNIT_Y * 20.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
"");
|
2010-04-06 02:05:54 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Waveform Template
|
|
|
|
|
* \{ */
|
2010-04-06 02:05:54 +00:00
|
|
|
|
2010-11-17 09:45:45 +00:00
|
|
|
void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname)
|
2010-04-06 02:05:54 +00:00
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!prop || RNA_property_type(prop) != PROP_POINTER) {
|
2010-04-06 02:05:54 +00:00
|
|
|
return;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-04 17:02:13 +11:00
|
|
|
const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes)) {
|
2010-04-06 02:05:54 +00:00
|
|
|
return;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2020-10-04 22:44:19 -05:00
|
|
|
Scopes *scopes = (Scopes *)cptr.data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *col = uiLayoutColumn(layout, true);
|
|
|
|
|
uiBlock *block = uiLayoutGetBlock(col);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-02 13:09:43 +02:00
|
|
|
if (scopes->wavefrm_height < UI_UNIT_Y) {
|
|
|
|
|
scopes->wavefrm_height = UI_UNIT_Y;
|
|
|
|
|
}
|
|
|
|
|
else if (scopes->wavefrm_height > UI_UNIT_Y * 20) {
|
|
|
|
|
scopes->wavefrm_height = UI_UNIT_Y * 20;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block,
|
|
|
|
|
UI_BTYPE_WAVEFORM,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2014-11-09 21:20:40 +01:00
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
scopes->wavefrm_height,
|
|
|
|
|
scopes,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-02 13:09:43 +02:00
|
|
|
/* Resize grip. */
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefIconButI(block,
|
|
|
|
|
UI_BTYPE_GRIP,
|
|
|
|
|
0,
|
|
|
|
|
ICON_GRIP,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
(short)(UI_UNIT_Y * 0.3f),
|
|
|
|
|
&scopes->wavefrm_height,
|
2014-04-02 13:09:43 +02:00
|
|
|
UI_UNIT_Y,
|
|
|
|
|
UI_UNIT_Y * 20.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
"");
|
2010-04-06 02:05:54 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2019-09-19 13:18:52 +10:00
|
|
|
/** \name Vector-Scope Template
|
2019-09-06 16:12:47 +10:00
|
|
|
* \{ */
|
2010-04-06 02:05:54 +00:00
|
|
|
|
2010-11-17 09:45:45 +00:00
|
|
|
void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propname)
|
2010-04-06 02:05:54 +00:00
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!prop || RNA_property_type(prop) != PROP_POINTER) {
|
2010-04-06 02:05:54 +00:00
|
|
|
return;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-04 17:02:13 +11:00
|
|
|
const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes)) {
|
2010-04-06 02:05:54 +00:00
|
|
|
return;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2020-10-04 22:44:19 -05:00
|
|
|
Scopes *scopes = (Scopes *)cptr.data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-02 13:09:43 +02:00
|
|
|
if (scopes->vecscope_height < UI_UNIT_Y) {
|
|
|
|
|
scopes->vecscope_height = UI_UNIT_Y;
|
|
|
|
|
}
|
|
|
|
|
else if (scopes->vecscope_height > UI_UNIT_Y * 20) {
|
|
|
|
|
scopes->vecscope_height = UI_UNIT_Y * 20;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *col = uiLayoutColumn(layout, true);
|
|
|
|
|
uiBlock *block = uiLayoutGetBlock(col);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-02 13:09:43 +02:00
|
|
|
uiDefBut(block,
|
|
|
|
|
UI_BTYPE_VECTORSCOPE,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2014-11-09 21:20:40 +01:00
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
scopes->vecscope_height,
|
|
|
|
|
scopes,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-02 13:09:43 +02:00
|
|
|
/* Resize grip. */
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefIconButI(block,
|
|
|
|
|
UI_BTYPE_GRIP,
|
|
|
|
|
0,
|
|
|
|
|
ICON_GRIP,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
(short)(UI_UNIT_Y * 0.3f),
|
|
|
|
|
&scopes->vecscope_height,
|
2014-04-02 13:09:43 +02:00
|
|
|
UI_UNIT_Y,
|
|
|
|
|
UI_UNIT_Y * 20.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
"");
|
2010-01-19 01:32:06 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name CurveMapping Template
|
|
|
|
|
* \{ */
|
2009-06-03 00:14:12 +00:00
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static void curvemap_buttons_zoom_in(bContext *C, void *cumap_v, void *UNUSED(arg))
|
2009-06-03 00:14:12 +00:00
|
|
|
{
|
2009-09-16 18:47:42 +00:00
|
|
|
CurveMapping *cumap = cumap_v;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
/* we allow 20 times zoom */
|
2012-09-23 18:50:56 +00:00
|
|
|
if (BLI_rctf_size_x(&cumap->curr) > 0.04f * BLI_rctf_size_x(&cumap->clipr)) {
|
2020-10-04 22:44:19 -05:00
|
|
|
const float dx = 0.1154f * BLI_rctf_size_x(&cumap->curr);
|
|
|
|
|
cumap->curr.xmin += dx;
|
|
|
|
|
cumap->curr.xmax -= dx;
|
|
|
|
|
const float dy = 0.1154f * BLI_rctf_size_y(&cumap->curr);
|
|
|
|
|
cumap->curr.ymin += dy;
|
|
|
|
|
cumap->curr.ymax -= dy;
|
2009-09-16 18:47:42 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static void curvemap_buttons_zoom_out(bContext *C, void *cumap_v, void *UNUSED(unused))
|
2009-09-16 18:47:42 +00:00
|
|
|
{
|
|
|
|
|
CurveMapping *cumap = cumap_v;
|
|
|
|
|
float d, d1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-18 07:38:51 +00:00
|
|
|
/* we allow 20 times zoom, but don't view outside clip */
|
2012-09-23 18:50:56 +00:00
|
|
|
if (BLI_rctf_size_x(&cumap->curr) < 20.0f * BLI_rctf_size_x(&cumap->clipr)) {
|
|
|
|
|
d = d1 = 0.15f * BLI_rctf_size_x(&cumap->curr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (cumap->flag & CUMA_DO_CLIP) {
|
|
|
|
|
if (cumap->curr.xmin - d < cumap->clipr.xmin) {
|
2012-03-30 01:51:25 +00:00
|
|
|
d1 = cumap->curr.xmin - cumap->clipr.xmin;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
}
|
2012-03-30 01:51:25 +00:00
|
|
|
cumap->curr.xmin -= d1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-30 01:51:25 +00:00
|
|
|
d1 = d;
|
2019-03-25 10:15:20 +11:00
|
|
|
if (cumap->flag & CUMA_DO_CLIP) {
|
|
|
|
|
if (cumap->curr.xmax + d > cumap->clipr.xmax) {
|
2012-03-30 01:51:25 +00:00
|
|
|
d1 = -cumap->curr.xmax + cumap->clipr.xmax;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
}
|
2012-03-30 01:51:25 +00:00
|
|
|
cumap->curr.xmax += d1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-09-23 18:50:56 +00:00
|
|
|
d = d1 = 0.15f * BLI_rctf_size_y(&cumap->curr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (cumap->flag & CUMA_DO_CLIP) {
|
|
|
|
|
if (cumap->curr.ymin - d < cumap->clipr.ymin) {
|
2012-03-30 01:51:25 +00:00
|
|
|
d1 = cumap->curr.ymin - cumap->clipr.ymin;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
}
|
2012-03-30 01:51:25 +00:00
|
|
|
cumap->curr.ymin -= d1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-30 01:51:25 +00:00
|
|
|
d1 = d;
|
2019-03-25 10:15:20 +11:00
|
|
|
if (cumap->flag & CUMA_DO_CLIP) {
|
|
|
|
|
if (cumap->curr.ymax + d > cumap->clipr.ymax) {
|
2012-03-30 01:51:25 +00:00
|
|
|
d1 = -cumap->curr.ymax + cumap->clipr.ymax;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
}
|
2012-03-30 01:51:25 +00:00
|
|
|
cumap->curr.ymax += d1;
|
2009-09-16 18:47:42 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static void curvemap_buttons_setclip(bContext *UNUSED(C), void *cumap_v, void *UNUSED(arg))
|
2009-09-16 18:47:42 +00:00
|
|
|
{
|
|
|
|
|
CurveMapping *cumap = cumap_v;
|
|
|
|
|
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemapping_changed(cumap, false);
|
2018-05-23 10:47:12 +02:00
|
|
|
}
|
2009-09-16 18:47:42 +00:00
|
|
|
|
|
|
|
|
static void curvemap_buttons_delete(bContext *C, void *cb_v, void *cumap_v)
|
|
|
|
|
{
|
|
|
|
|
CurveMapping *cumap = cumap_v;
|
|
|
|
|
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemap_remove(cumap->cm + cumap->cur, SELECT);
|
|
|
|
|
BKE_curvemapping_changed(cumap, false);
|
2009-09-16 18:47:42 +00:00
|
|
|
|
|
|
|
|
rna_update_cb(C, cb_v, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *curvemap_clipping_func(bContext *C, ARegion *region, void *cumap_v)
|
2009-09-16 18:47:42 +00:00
|
|
|
{
|
|
|
|
|
CurveMapping *cumap = cumap_v;
|
|
|
|
|
uiBut *bt;
|
2020-08-26 10:11:13 +10:00
|
|
|
const float width = 8 * UI_UNIT_X;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
|
2019-08-27 12:28:34 +02:00
|
|
|
UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT);
|
|
|
|
|
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-01 19:57:31 +02:00
|
|
|
bt = uiDefButBitI(block,
|
2019-08-27 12:28:34 +02:00
|
|
|
UI_BTYPE_CHECKBOX,
|
2018-07-01 19:57:31 +02:00
|
|
|
CUMA_DO_CLIP,
|
|
|
|
|
1,
|
|
|
|
|
IFACE_("Use Clipping"),
|
|
|
|
|
0,
|
|
|
|
|
5 * UI_UNIT_Y,
|
|
|
|
|
width,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
&cumap->flag,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
10,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_func_set(bt, curvemap_buttons_setclip, cumap, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_begin(block);
|
2020-09-04 21:18:45 +02:00
|
|
|
bt = uiDefButF(block,
|
|
|
|
|
UI_BTYPE_NUM,
|
|
|
|
|
0,
|
|
|
|
|
IFACE_("Min X:"),
|
|
|
|
|
0,
|
|
|
|
|
4 * UI_UNIT_Y,
|
|
|
|
|
width,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
&cumap->clipr.xmin,
|
|
|
|
|
-100.0,
|
|
|
|
|
cumap->clipr.xmax,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
UI_but_number_step_size_set(bt, 10);
|
|
|
|
|
UI_but_number_precision_set(bt, 2);
|
|
|
|
|
bt = uiDefButF(block,
|
|
|
|
|
UI_BTYPE_NUM,
|
|
|
|
|
0,
|
|
|
|
|
IFACE_("Min Y:"),
|
|
|
|
|
0,
|
|
|
|
|
3 * UI_UNIT_Y,
|
|
|
|
|
width,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
&cumap->clipr.ymin,
|
|
|
|
|
-100.0,
|
|
|
|
|
cumap->clipr.ymax,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
UI_but_number_step_size_set(bt, 10);
|
|
|
|
|
UI_but_number_precision_set(bt, 2);
|
|
|
|
|
bt = uiDefButF(block,
|
|
|
|
|
UI_BTYPE_NUM,
|
|
|
|
|
0,
|
|
|
|
|
IFACE_("Max X:"),
|
|
|
|
|
0,
|
|
|
|
|
2 * UI_UNIT_Y,
|
|
|
|
|
width,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
&cumap->clipr.xmax,
|
|
|
|
|
cumap->clipr.xmin,
|
|
|
|
|
100.0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
UI_but_number_step_size_set(bt, 10);
|
|
|
|
|
UI_but_number_precision_set(bt, 2);
|
|
|
|
|
bt = uiDefButF(block,
|
|
|
|
|
UI_BTYPE_NUM,
|
|
|
|
|
0,
|
|
|
|
|
IFACE_("Max Y:"),
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
width,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
&cumap->clipr.ymax,
|
|
|
|
|
cumap->clipr.ymin,
|
|
|
|
|
100.0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
UI_but_number_step_size_set(bt, 10);
|
|
|
|
|
UI_but_number_precision_set(bt, 2);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-27 12:28:34 +02:00
|
|
|
UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
|
|
|
|
|
UI_block_direction_set(block, UI_DIR_DOWN);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
return block;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-07 03:21:55 +10:00
|
|
|
/* only for BKE_curvemap_tools_dofunc */
|
2013-04-28 20:51:44 +00:00
|
|
|
enum {
|
|
|
|
|
UICURVE_FUNC_RESET_NEG,
|
|
|
|
|
UICURVE_FUNC_RESET_POS,
|
|
|
|
|
UICURVE_FUNC_RESET_VIEW,
|
|
|
|
|
UICURVE_FUNC_HANDLE_VECTOR,
|
|
|
|
|
UICURVE_FUNC_HANDLE_AUTO,
|
2016-08-01 09:01:43 +10:00
|
|
|
UICURVE_FUNC_HANDLE_AUTO_ANIM,
|
2013-04-28 20:51:44 +00:00
|
|
|
UICURVE_FUNC_EXTEND_HOZ,
|
|
|
|
|
UICURVE_FUNC_EXTEND_EXP,
|
|
|
|
|
};
|
|
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
|
|
|
|
|
{
|
|
|
|
|
CurveMapping *cumap = cumap_v;
|
2012-03-30 01:51:25 +00:00
|
|
|
CurveMap *cuma = cumap->cm + cumap->cur;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-30 01:51:25 +00:00
|
|
|
switch (event) {
|
2013-04-28 20:51:44 +00:00
|
|
|
case UICURVE_FUNC_RESET_NEG:
|
|
|
|
|
case UICURVE_FUNC_RESET_POS: /* reset */
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemap_reset(cuma,
|
|
|
|
|
&cumap->clipr,
|
|
|
|
|
cumap->preset,
|
|
|
|
|
(event == UICURVE_FUNC_RESET_NEG) ? CURVEMAP_SLOPE_NEGATIVE :
|
|
|
|
|
CURVEMAP_SLOPE_POSITIVE);
|
|
|
|
|
BKE_curvemapping_changed(cumap, false);
|
2009-09-16 18:47:42 +00:00
|
|
|
break;
|
2013-04-28 20:51:44 +00:00
|
|
|
case UICURVE_FUNC_RESET_VIEW:
|
2021-03-02 13:13:36 -06:00
|
|
|
BKE_curvemapping_reset_view(cumap);
|
2009-09-16 18:47:42 +00:00
|
|
|
break;
|
2013-04-28 20:51:44 +00:00
|
|
|
case UICURVE_FUNC_HANDLE_VECTOR: /* set vector */
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemap_handle_set(cuma, HD_VECT);
|
|
|
|
|
BKE_curvemapping_changed(cumap, false);
|
2009-09-16 18:47:42 +00:00
|
|
|
break;
|
2013-04-28 20:51:44 +00:00
|
|
|
case UICURVE_FUNC_HANDLE_AUTO: /* set auto */
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemap_handle_set(cuma, HD_AUTO);
|
|
|
|
|
BKE_curvemapping_changed(cumap, false);
|
2009-09-16 18:47:42 +00:00
|
|
|
break;
|
2016-08-01 09:01:43 +10:00
|
|
|
case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* set auto-clamped */
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemap_handle_set(cuma, HD_AUTO_ANIM);
|
|
|
|
|
BKE_curvemapping_changed(cumap, false);
|
2017-02-27 13:32:45 +11:00
|
|
|
break;
|
2013-04-28 20:51:44 +00:00
|
|
|
case UICURVE_FUNC_EXTEND_HOZ: /* extend horiz */
|
2019-11-01 12:09:55 +01:00
|
|
|
cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemapping_changed(cumap, false);
|
2009-09-16 18:47:42 +00:00
|
|
|
break;
|
2013-04-28 20:51:44 +00:00
|
|
|
case UICURVE_FUNC_EXTEND_EXP: /* extend extrapolate */
|
2019-11-01 12:09:55 +01:00
|
|
|
cumap->flag |= CUMA_EXTEND_EXTRAPOLATE;
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemapping_changed(cumap, false);
|
2009-09-16 18:47:42 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2014-05-17 16:48:06 +02:00
|
|
|
ED_undo_push(C, "CurveMap tools");
|
2009-09-16 18:47:42 +00:00
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-25 11:54:30 +11:00
|
|
|
static uiBlock *curvemap_tools_func(
|
2020-03-06 16:56:42 +01:00
|
|
|
bContext *C, ARegion *region, CurveMapping *cumap, bool show_extend, int reset_mode)
|
2009-09-16 18:47:42 +00:00
|
|
|
{
|
2020-10-04 22:44:19 -05:00
|
|
|
short yco = 0;
|
|
|
|
|
const short menuwidth = 10 * UI_UNIT_X;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
|
2016-02-25 11:54:30 +11:00
|
|
|
UI_block_func_butmenu_set(block, curvemap_tools_dofunc, cumap);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-02-25 11:54:30 +11:00
|
|
|
{
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Reset View"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
|
|
|
|
menuwidth,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
UICURVE_FUNC_RESET_VIEW,
|
|
|
|
|
"");
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Vector Handle"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
|
|
|
|
menuwidth,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
UICURVE_FUNC_HANDLE_VECTOR,
|
|
|
|
|
"");
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Auto Handle"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
|
|
|
|
menuwidth,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
UICURVE_FUNC_HANDLE_AUTO,
|
|
|
|
|
"");
|
2016-08-01 09:01:43 +10:00
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Auto Clamped Handle"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
|
|
|
|
menuwidth,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
UICURVE_FUNC_HANDLE_AUTO_ANIM,
|
|
|
|
|
"");
|
2016-02-25 11:54:30 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-02-25 11:54:30 +11:00
|
|
|
if (show_extend) {
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Extend Horizontal"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
|
|
|
|
menuwidth,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
UICURVE_FUNC_EXTEND_HOZ,
|
|
|
|
|
"");
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Extend Extrapolated"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
|
|
|
|
menuwidth,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
UICURVE_FUNC_EXTEND_EXP,
|
|
|
|
|
"");
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-02-25 11:54:30 +11:00
|
|
|
{
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Reset Curve"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
|
|
|
|
menuwidth,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
reset_mode,
|
|
|
|
|
"");
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-11-19 16:15:05 +00:00
|
|
|
UI_block_direction_set(block, UI_DIR_DOWN);
|
|
|
|
|
UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
return block;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *curvemap_tools_posslope_func(bContext *C, ARegion *region, void *cumap_v)
|
2014-06-30 16:20:02 +02:00
|
|
|
{
|
2020-03-06 16:56:42 +01:00
|
|
|
return curvemap_tools_func(C, region, cumap_v, true, UICURVE_FUNC_RESET_POS);
|
2016-02-25 11:54:30 +11:00
|
|
|
}
|
2014-06-30 16:20:02 +02:00
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *curvemap_tools_negslope_func(bContext *C, ARegion *region, void *cumap_v)
|
2016-02-25 11:54:30 +11:00
|
|
|
{
|
2020-03-06 16:56:42 +01:00
|
|
|
return curvemap_tools_func(C, region, cumap_v, true, UICURVE_FUNC_RESET_NEG);
|
2014-06-30 16:20:02 +02:00
|
|
|
}
|
|
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *curvemap_brush_tools_func(bContext *C, ARegion *region, void *cumap_v)
|
2010-01-04 17:28:37 +00:00
|
|
|
{
|
2020-03-06 16:56:42 +01:00
|
|
|
return curvemap_tools_func(C, region, cumap_v, false, UICURVE_FUNC_RESET_NEG);
|
2010-01-04 17:28:37 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *curvemap_brush_tools_negslope_func(bContext *C, ARegion *region, void *cumap_v)
|
2019-05-06 13:03:23 +02:00
|
|
|
{
|
2020-03-06 16:56:42 +01:00
|
|
|
return curvemap_tools_func(C, region, cumap_v, false, UICURVE_FUNC_RESET_POS);
|
2019-05-06 13:03:23 +02:00
|
|
|
}
|
|
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static void curvemap_buttons_redraw(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
|
2009-09-16 18:47:42 +00:00
|
|
|
{
|
|
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-28 01:47:45 +00:00
|
|
|
static void curvemap_buttons_update(bContext *C, void *arg1_v, void *cumap_v)
|
2012-09-04 12:40:47 +00:00
|
|
|
{
|
|
|
|
|
CurveMapping *cumap = cumap_v;
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemapping_changed(cumap, true);
|
2012-09-28 01:47:45 +00:00
|
|
|
rna_update_cb(C, arg1_v, NULL);
|
2012-09-04 12:40:47 +00:00
|
|
|
}
|
|
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v)
|
|
|
|
|
{
|
|
|
|
|
CurveMapping *cumap = cumap_v;
|
2010-03-09 07:41:27 +00:00
|
|
|
cumap->preset = CURVE_PRESET_LINE;
|
2020-10-04 22:44:19 -05:00
|
|
|
for (int a = 0; a < CM_TOT; a++) {
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemap_reset(cumap->cm + a, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2012-03-30 01:51:25 +00:00
|
|
|
cumap->black[0] = cumap->black[1] = cumap->black[2] = 0.0f;
|
|
|
|
|
cumap->white[0] = cumap->white[1] = cumap->white[2] = 1.0f;
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemapping_set_black_white(cumap, NULL, NULL);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemapping_changed(cumap, false);
|
2009-09-16 18:47:42 +00:00
|
|
|
|
|
|
|
|
rna_update_cb(C, cb_v, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-04 12:52:01 +10:00
|
|
|
/**
|
|
|
|
|
* \note Still unsure how this call evolves.
|
|
|
|
|
*
|
|
|
|
|
* \param labeltype: Used for defining which curve-channels to show.
|
|
|
|
|
*/
|
2015-05-05 03:13:47 +10:00
|
|
|
static void curvemap_buttons_layout(uiLayout *layout,
|
2018-07-01 15:47:09 +02:00
|
|
|
PointerRNA *ptr,
|
|
|
|
|
char labeltype,
|
|
|
|
|
bool levels,
|
2018-08-23 10:25:54 +02:00
|
|
|
bool brush,
|
|
|
|
|
bool neg_slope,
|
|
|
|
|
bool tone,
|
|
|
|
|
RNAUpdateCb *cb)
|
2009-09-16 18:47:42 +00:00
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
CurveMapping *cumap = ptr->data;
|
2012-09-04 12:40:47 +00:00
|
|
|
CurveMap *cm = &cumap->cm[cumap->cur];
|
2009-09-16 18:47:42 +00:00
|
|
|
uiBut *bt;
|
2020-08-26 10:11:13 +10:00
|
|
|
const float dx = UI_UNIT_X;
|
2020-09-09 18:41:07 +02:00
|
|
|
int bg = -1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-08-23 10:25:54 +02:00
|
|
|
if (tone) {
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
|
2018-09-25 18:22:01 +02:00
|
|
|
uiItemR(uiLayoutRow(split, false), ptr, "tone", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
|
2018-08-23 10:25:54 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
/* curve chooser */
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *row = uiLayoutRow(layout, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-30 01:51:25 +00:00
|
|
|
if (labeltype == 'v') {
|
2009-09-16 18:47:42 +00:00
|
|
|
/* vector */
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *sub = uiLayoutRow(row, true);
|
2009-09-16 18:47:42 +00:00
|
|
|
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (cumap->cm[0].curve) {
|
2014-11-09 21:20:40 +01:00
|
|
|
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, NULL, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
if (cumap->cm[1].curve) {
|
2014-11-09 21:20:40 +01:00
|
|
|
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, NULL, NULL);
|
2009-08-10 20:48:38 +00:00
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
if (cumap->cm[2].curve) {
|
2014-11-09 21:20:40 +01:00
|
|
|
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, NULL, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2012-03-30 01:51:25 +00:00
|
|
|
else if (labeltype == 'c') {
|
2014-11-09 21:20:40 +01:00
|
|
|
/* color */
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *sub = uiLayoutRow(row, true);
|
2009-09-16 18:47:42 +00:00
|
|
|
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (cumap->cm[3].curve) {
|
2014-11-09 21:20:40 +01:00
|
|
|
bt = uiDefButI(
|
|
|
|
|
block, UI_BTYPE_ROW, 0, "C", 0, 0, dx, dx, &cumap->cur, 0.0, 3.0, 0.0, 0.0, "");
|
|
|
|
|
UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
|
2009-09-16 18:47:42 +00:00
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
if (cumap->cm[0].curve) {
|
2014-11-09 21:20:40 +01:00
|
|
|
bt = uiDefButI(
|
|
|
|
|
block, UI_BTYPE_ROW, 0, "R", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
|
|
|
|
|
UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
|
2009-09-16 18:47:42 +00:00
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
if (cumap->cm[1].curve) {
|
2014-11-09 21:20:40 +01:00
|
|
|
bt = uiDefButI(
|
|
|
|
|
block, UI_BTYPE_ROW, 0, "G", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
|
|
|
|
|
UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
|
2009-09-16 18:47:42 +00:00
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
if (cumap->cm[2].curve) {
|
2014-11-09 21:20:40 +01:00
|
|
|
bt = uiDefButI(
|
|
|
|
|
block, UI_BTYPE_ROW, 0, "B", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
|
|
|
|
|
UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2009-09-16 18:47:42 +00:00
|
|
|
}
|
2012-03-30 01:51:25 +00:00
|
|
|
else if (labeltype == 'h') {
|
2010-01-21 22:23:57 +00:00
|
|
|
/* HSV */
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *sub = uiLayoutRow(row, true);
|
2009-09-16 18:47:42 +00:00
|
|
|
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (cumap->cm[0].curve) {
|
2014-11-09 21:20:40 +01:00
|
|
|
bt = uiDefButI(
|
|
|
|
|
block, UI_BTYPE_ROW, 0, "H", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
|
|
|
|
|
UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
if (cumap->cm[1].curve) {
|
2014-11-09 21:20:40 +01:00
|
|
|
bt = uiDefButI(
|
|
|
|
|
block, UI_BTYPE_ROW, 0, "S", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
|
|
|
|
|
UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
|
2009-09-16 18:47:42 +00:00
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
if (cumap->cm[2].curve) {
|
2014-11-09 21:20:40 +01:00
|
|
|
bt = uiDefButI(
|
|
|
|
|
block, UI_BTYPE_ROW, 0, "V", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
|
|
|
|
|
UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2009-08-10 20:48:38 +00:00
|
|
|
}
|
2010-01-21 22:23:57 +00:00
|
|
|
else {
|
|
|
|
|
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (labeltype == 'h') {
|
2014-11-09 21:20:40 +01:00
|
|
|
bg = UI_GRAD_H;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
/* operation buttons */
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayoutRow(row, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
bt = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_ZOOM_IN,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
dx,
|
|
|
|
|
dx,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
TIP_("Zoom in"));
|
|
|
|
|
UI_but_func_set(bt, curvemap_buttons_zoom_in, cumap, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
bt = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_ZOOM_OUT,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
dx,
|
|
|
|
|
dx,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
TIP_("Zoom out"));
|
|
|
|
|
UI_but_func_set(bt, curvemap_buttons_zoom_out, cumap, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-06 13:03:23 +02:00
|
|
|
if (brush && neg_slope) {
|
|
|
|
|
bt = uiDefIconBlockBut(block,
|
|
|
|
|
curvemap_brush_tools_negslope_func,
|
|
|
|
|
cumap,
|
|
|
|
|
0,
|
|
|
|
|
ICON_DOWNARROW_HLT,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
dx,
|
|
|
|
|
dx,
|
|
|
|
|
TIP_("Tools"));
|
|
|
|
|
}
|
|
|
|
|
else if (brush) {
|
2016-02-25 05:49:25 +11:00
|
|
|
bt = uiDefIconBlockBut(block,
|
2014-11-09 21:20:40 +01:00
|
|
|
curvemap_brush_tools_func,
|
|
|
|
|
cumap,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2014-11-09 21:20:40 +01:00
|
|
|
ICON_DOWNARROW_HLT,
|
2016-02-25 05:49:25 +11:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
dx,
|
|
|
|
|
dx,
|
|
|
|
|
TIP_("Tools"));
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2016-02-25 05:49:25 +11:00
|
|
|
else if (neg_slope) {
|
|
|
|
|
bt = uiDefIconBlockBut(block,
|
2018-10-28 17:51:40 +01:00
|
|
|
curvemap_tools_negslope_func,
|
|
|
|
|
cumap,
|
|
|
|
|
0,
|
|
|
|
|
ICON_DOWNARROW_HLT,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
dx,
|
|
|
|
|
dx,
|
|
|
|
|
TIP_("Tools"));
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2018-10-28 17:51:40 +01:00
|
|
|
bt = uiDefIconBlockBut(block,
|
|
|
|
|
curvemap_tools_posslope_func,
|
|
|
|
|
cumap,
|
|
|
|
|
0,
|
|
|
|
|
ICON_DOWNARROW_HLT,
|
2018-07-01 19:57:31 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
dx,
|
|
|
|
|
dx,
|
|
|
|
|
TIP_("Tools"));
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-04 17:02:13 +11:00
|
|
|
const int icon = (cumap->flag & CUMA_DO_CLIP) ? ICON_CLIPUV_HLT : ICON_CLIPUV_DEHLT;
|
2012-03-30 01:51:25 +00:00
|
|
|
bt = uiDefIconBlockBut(
|
|
|
|
|
block, curvemap_clipping_func, cumap, 0, icon, 0, 0, dx, dx, TIP_("Clipping Options"));
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
bt = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_X,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
dx,
|
|
|
|
|
dx,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
TIP_("Delete points"));
|
|
|
|
|
UI_but_funcN_set(bt, curvemap_buttons_delete, MEM_dupallocN(cb), cumap);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
/* curve itself */
|
2021-01-04 17:02:13 +11:00
|
|
|
const int size = max_ii(uiLayoutGetWidth(layout), UI_UNIT_X);
|
2014-01-04 17:16:19 +11:00
|
|
|
row = uiLayoutRow(layout, false);
|
2020-09-04 19:26:12 +02:00
|
|
|
uiButCurveMapping *curve_but = (uiButCurveMapping *)uiDefBut(
|
|
|
|
|
block, UI_BTYPE_CURVE, 0, "", 0, 0, size, 8.0f * UI_UNIT_X, cumap, 0.0f, 1.0f, 0, 0, "");
|
|
|
|
|
curve_but->gradient_type = bg;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-09-04 12:40:47 +00:00
|
|
|
/* sliders for selected point */
|
2020-10-04 22:44:19 -05:00
|
|
|
CurveMapPoint *cmp = NULL;
|
2020-09-09 18:41:07 +02:00
|
|
|
for (int i = 0; i < cm->totpoint; i++) {
|
2012-09-04 12:40:47 +00:00
|
|
|
if (cm->curve[i].flag & CUMA_SELECT) {
|
|
|
|
|
cmp = &cm->curve[i];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-09-04 12:40:47 +00:00
|
|
|
if (cmp) {
|
2013-01-12 20:19:58 +00:00
|
|
|
rctf bounds;
|
|
|
|
|
if (cumap->flag & CUMA_DO_CLIP) {
|
|
|
|
|
bounds = cumap->clipr;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2013-01-12 20:19:58 +00:00
|
|
|
else {
|
|
|
|
|
bounds.xmin = bounds.ymin = -1000.0;
|
|
|
|
|
bounds.xmax = bounds.ymax = 1000.0;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-01-12 20:19:58 +00:00
|
|
|
uiLayoutRow(layout, true);
|
|
|
|
|
UI_block_funcN_set(block, curvemap_buttons_update, MEM_dupallocN(cb), cumap);
|
2020-09-04 21:18:45 +02:00
|
|
|
bt = uiDefButF(block,
|
|
|
|
|
UI_BTYPE_NUM,
|
|
|
|
|
0,
|
|
|
|
|
"X",
|
|
|
|
|
0,
|
|
|
|
|
2 * UI_UNIT_Y,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
&cmp->x,
|
|
|
|
|
bounds.xmin,
|
|
|
|
|
bounds.xmax,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
UI_but_number_step_size_set(bt, 1);
|
|
|
|
|
UI_but_number_precision_set(bt, 5);
|
|
|
|
|
bt = uiDefButF(block,
|
|
|
|
|
UI_BTYPE_NUM,
|
|
|
|
|
0,
|
|
|
|
|
"Y",
|
|
|
|
|
0,
|
|
|
|
|
1 * UI_UNIT_Y,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
&cmp->y,
|
|
|
|
|
bounds.ymin,
|
|
|
|
|
bounds.ymax,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
UI_but_number_step_size_set(bt, 1);
|
|
|
|
|
UI_but_number_precision_set(bt, 5);
|
2012-09-04 12:40:47 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
/* black/white levels */
|
2012-03-24 06:38:07 +00:00
|
|
|
if (levels) {
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
|
2014-01-04 17:16:19 +11:00
|
|
|
uiItemR(uiLayoutColumn(split, false), ptr, "black_level", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
|
|
|
|
|
uiItemR(uiLayoutColumn(split, false), ptr, "white_level", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
uiLayoutRow(layout, false);
|
2014-11-09 21:20:40 +01:00
|
|
|
bt = uiDefBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
IFACE_("Reset"),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2012-03-30 01:51:25 +00:00
|
|
|
TIP_("Reset Black/White point and curves"));
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_funcN_set(bt, curvemap_buttons_reset, MEM_dupallocN(cb), cumap);
|
2009-09-16 18:47:42 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_funcN_set(block, NULL, NULL, NULL);
|
2009-09-16 18:47:42 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-05 03:13:47 +10:00
|
|
|
void uiTemplateCurveMapping(uiLayout *layout,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
int type,
|
2018-08-23 10:25:54 +02:00
|
|
|
bool levels,
|
|
|
|
|
bool brush,
|
|
|
|
|
bool neg_slope,
|
|
|
|
|
bool tone)
|
2009-09-16 18:47:42 +00:00
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
2014-01-29 19:02:32 +01:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2009-09-16 18:47:42 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!prop) {
|
2011-09-09 01:29:53 +00:00
|
|
|
RNA_warning("curve property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
2009-09-16 18:47:42 +00:00
|
|
|
return;
|
2011-03-27 23:11:22 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (RNA_property_type(prop) != PROP_POINTER) {
|
2011-09-09 01:29:53 +00:00
|
|
|
RNA_warning("curve is not a pointer: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
2009-09-16 18:47:42 +00:00
|
|
|
return;
|
2011-03-27 23:11:22 +00:00
|
|
|
}
|
2009-09-16 18:47:42 +00:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_CurveMapping)) {
|
2009-09-16 18:47:42 +00:00
|
|
|
return;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2009-09-16 18:47:42 +00:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
RNAUpdateCb *cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
|
2012-03-30 01:51:25 +00:00
|
|
|
cb->ptr = *ptr;
|
|
|
|
|
cb->prop = prop;
|
2009-09-16 18:47:42 +00:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
ID *id = cptr.owner_id;
|
2017-11-06 17:17:10 +01:00
|
|
|
UI_block_lock_set(block, (id && ID_IS_LINKED(id)), ERROR_LIBDATA_MESSAGE);
|
2014-01-29 19:02:32 +01:00
|
|
|
|
2018-08-23 10:25:54 +02:00
|
|
|
curvemap_buttons_layout(layout, &cptr, type, levels, brush, neg_slope, tone, cb);
|
2009-09-16 18:47:42 +00:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_lock_clear(block);
|
2014-01-29 19:02:32 +01:00
|
|
|
|
2009-09-16 18:47:42 +00:00
|
|
|
MEM_freeN(cb);
|
2009-06-03 00:14:12 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
2019-11-20 16:12:32 -05:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Curve Profile Template
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void CurveProfile_presets_dofunc(bContext *C, void *profile_v, int event)
|
|
|
|
|
{
|
|
|
|
|
CurveProfile *profile = profile_v;
|
|
|
|
|
|
|
|
|
|
profile->preset = event;
|
|
|
|
|
BKE_curveprofile_reset(profile);
|
2020-06-24 11:50:01 -04:00
|
|
|
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
2019-11-20 16:12:32 -05:00
|
|
|
|
|
|
|
|
ED_undo_push(C, "CurveProfile tools");
|
|
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *CurveProfile_presets_func(bContext *C, ARegion *region, CurveProfile *profile)
|
2019-11-20 16:12:32 -05:00
|
|
|
{
|
|
|
|
|
short yco = 0;
|
|
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
|
2019-11-20 16:12:32 -05:00
|
|
|
UI_block_func_butmenu_set(block, CurveProfile_presets_dofunc, profile);
|
|
|
|
|
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Default"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
2020-10-04 22:44:19 -05:00
|
|
|
0,
|
2019-11-20 16:12:32 -05:00
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
PROF_PRESET_LINE,
|
|
|
|
|
"");
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Support Loops"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
2020-10-04 22:44:19 -05:00
|
|
|
0,
|
2019-11-20 16:12:32 -05:00
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
PROF_PRESET_SUPPORTS,
|
|
|
|
|
"");
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
2020-02-17 13:00:01 +01:00
|
|
|
IFACE_("Cornice Molding"),
|
2019-11-20 16:12:32 -05:00
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
2020-10-04 22:44:19 -05:00
|
|
|
0,
|
2019-11-20 16:12:32 -05:00
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
PROF_PRESET_CORNICE,
|
|
|
|
|
"");
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
2020-02-17 13:00:01 +01:00
|
|
|
IFACE_("Crown Molding"),
|
2019-11-20 16:12:32 -05:00
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
2020-10-04 22:44:19 -05:00
|
|
|
0,
|
2019-11-20 16:12:32 -05:00
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
PROF_PRESET_CROWN,
|
|
|
|
|
"");
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Steps"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
2020-10-04 22:44:19 -05:00
|
|
|
0,
|
2019-11-20 16:12:32 -05:00
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
PROF_PRESET_STEPS,
|
|
|
|
|
"");
|
|
|
|
|
|
|
|
|
|
UI_block_direction_set(block, UI_DIR_DOWN);
|
|
|
|
|
UI_block_bounds_set_text(block, (int)(3.0f * UI_UNIT_X));
|
|
|
|
|
|
|
|
|
|
return block;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *CurveProfile_buttons_presets(bContext *C, ARegion *region, void *profile_v)
|
2019-11-20 16:12:32 -05:00
|
|
|
{
|
2020-03-06 16:56:42 +01:00
|
|
|
return CurveProfile_presets_func(C, region, (CurveProfile *)profile_v);
|
2019-11-20 16:12:32 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Only for CurveProfile tools block */
|
|
|
|
|
enum {
|
|
|
|
|
UIPROFILE_FUNC_RESET,
|
|
|
|
|
UIPROFILE_FUNC_RESET_VIEW,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void CurveProfile_tools_dofunc(bContext *C, void *profile_v, int event)
|
|
|
|
|
{
|
|
|
|
|
CurveProfile *profile = profile_v;
|
|
|
|
|
|
|
|
|
|
switch (event) {
|
|
|
|
|
case UIPROFILE_FUNC_RESET: /* reset */
|
|
|
|
|
BKE_curveprofile_reset(profile);
|
2020-06-24 11:50:01 -04:00
|
|
|
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
2019-11-20 16:12:32 -05:00
|
|
|
break;
|
|
|
|
|
case UIPROFILE_FUNC_RESET_VIEW: /* reset view to clipping rect */
|
2021-03-18 17:25:36 -04:00
|
|
|
BKE_curveprofile_reset_view(profile);
|
2019-11-20 16:12:32 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
ED_undo_push(C, "CurveProfile tools");
|
|
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *CurveProfile_tools_func(bContext *C, ARegion *region, CurveProfile *profile)
|
2019-11-20 16:12:32 -05:00
|
|
|
{
|
|
|
|
|
short yco = 0;
|
|
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
|
2019-11-20 16:12:32 -05:00
|
|
|
UI_block_func_butmenu_set(block, CurveProfile_tools_dofunc, profile);
|
|
|
|
|
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Reset View"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
2020-10-04 22:44:19 -05:00
|
|
|
0,
|
2019-11-20 16:12:32 -05:00
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
UIPROFILE_FUNC_RESET_VIEW,
|
|
|
|
|
"");
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT_MENU,
|
|
|
|
|
1,
|
|
|
|
|
ICON_BLANK1,
|
|
|
|
|
IFACE_("Reset Curve"),
|
|
|
|
|
0,
|
|
|
|
|
yco -= UI_UNIT_Y,
|
2020-10-04 22:44:19 -05:00
|
|
|
0,
|
2019-11-20 16:12:32 -05:00
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
UIPROFILE_FUNC_RESET,
|
|
|
|
|
"");
|
|
|
|
|
|
|
|
|
|
UI_block_direction_set(block, UI_DIR_DOWN);
|
|
|
|
|
UI_block_bounds_set_text(block, (int)(3.0f * UI_UNIT_X));
|
|
|
|
|
|
|
|
|
|
return block;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *CurveProfile_buttons_tools(bContext *C, ARegion *region, void *profile_v)
|
2019-11-20 16:12:32 -05:00
|
|
|
{
|
2020-03-06 16:56:42 +01:00
|
|
|
return CurveProfile_tools_func(C, region, (CurveProfile *)profile_v);
|
2019-11-20 16:12:32 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CurveProfile_buttons_zoom_in(bContext *C, void *profile_v, void *UNUSED(arg))
|
|
|
|
|
{
|
|
|
|
|
CurveProfile *profile = profile_v;
|
|
|
|
|
|
2020-06-24 11:50:01 -04:00
|
|
|
/* Allow a 20x zoom. */
|
2019-11-20 16:12:32 -05:00
|
|
|
if (BLI_rctf_size_x(&profile->view_rect) > 0.04f * BLI_rctf_size_x(&profile->clip_rect)) {
|
2020-10-04 22:44:19 -05:00
|
|
|
const float dx = 0.1154f * BLI_rctf_size_x(&profile->view_rect);
|
|
|
|
|
profile->view_rect.xmin += dx;
|
|
|
|
|
profile->view_rect.xmax -= dx;
|
|
|
|
|
const float dy = 0.1154f * BLI_rctf_size_y(&profile->view_rect);
|
|
|
|
|
profile->view_rect.ymin += dy;
|
|
|
|
|
profile->view_rect.ymax -= dy;
|
2019-11-20 16:12:32 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CurveProfile_buttons_zoom_out(bContext *C, void *profile_v, void *UNUSED(arg))
|
|
|
|
|
{
|
|
|
|
|
CurveProfile *profile = profile_v;
|
|
|
|
|
|
|
|
|
|
/* Allow 20 times zoom, but don't view outside clip */
|
|
|
|
|
if (BLI_rctf_size_x(&profile->view_rect) < 20.0f * BLI_rctf_size_x(&profile->clip_rect)) {
|
2020-10-04 22:44:19 -05:00
|
|
|
float d = 0.15f * BLI_rctf_size_x(&profile->view_rect);
|
|
|
|
|
float d1 = d;
|
2019-11-20 16:12:32 -05:00
|
|
|
|
|
|
|
|
if (profile->flag & PROF_USE_CLIP) {
|
|
|
|
|
if (profile->view_rect.xmin - d < profile->clip_rect.xmin) {
|
|
|
|
|
d1 = profile->view_rect.xmin - profile->clip_rect.xmin;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
profile->view_rect.xmin -= d1;
|
|
|
|
|
|
|
|
|
|
d1 = d;
|
|
|
|
|
if (profile->flag & PROF_USE_CLIP) {
|
|
|
|
|
if (profile->view_rect.xmax + d > profile->clip_rect.xmax) {
|
|
|
|
|
d1 = -profile->view_rect.xmax + profile->clip_rect.xmax;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
profile->view_rect.xmax += d1;
|
|
|
|
|
|
|
|
|
|
d = d1 = 0.15f * BLI_rctf_size_y(&profile->view_rect);
|
|
|
|
|
|
|
|
|
|
if (profile->flag & PROF_USE_CLIP) {
|
|
|
|
|
if (profile->view_rect.ymin - d < profile->clip_rect.ymin) {
|
|
|
|
|
d1 = profile->view_rect.ymin - profile->clip_rect.ymin;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
profile->view_rect.ymin -= d1;
|
|
|
|
|
|
|
|
|
|
d1 = d;
|
|
|
|
|
if (profile->flag & PROF_USE_CLIP) {
|
|
|
|
|
if (profile->view_rect.ymax + d > profile->clip_rect.ymax) {
|
|
|
|
|
d1 = -profile->view_rect.ymax + profile->clip_rect.ymax;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
profile->view_rect.ymax += d1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CurveProfile_clipping_toggle(bContext *C, void *cb_v, void *profile_v)
|
|
|
|
|
{
|
|
|
|
|
CurveProfile *profile = profile_v;
|
|
|
|
|
|
|
|
|
|
profile->flag ^= PROF_USE_CLIP;
|
|
|
|
|
|
2020-06-24 11:50:01 -04:00
|
|
|
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
2019-11-20 16:12:32 -05:00
|
|
|
rna_update_cb(C, cb_v, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CurveProfile_buttons_reverse(bContext *C, void *cb_v, void *profile_v)
|
|
|
|
|
{
|
|
|
|
|
CurveProfile *profile = profile_v;
|
|
|
|
|
|
|
|
|
|
BKE_curveprofile_reverse(profile);
|
2020-06-24 11:50:01 -04:00
|
|
|
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
2019-11-20 16:12:32 -05:00
|
|
|
rna_update_cb(C, cb_v, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CurveProfile_buttons_delete(bContext *C, void *cb_v, void *profile_v)
|
|
|
|
|
{
|
|
|
|
|
CurveProfile *profile = profile_v;
|
|
|
|
|
|
|
|
|
|
BKE_curveprofile_remove_by_flag(profile, SELECT);
|
2020-06-24 11:50:01 -04:00
|
|
|
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
2019-11-20 16:12:32 -05:00
|
|
|
|
|
|
|
|
rna_update_cb(C, cb_v, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-24 11:50:01 -04:00
|
|
|
static void CurveProfile_buttons_update(bContext *C, void *arg1_v, void *profile_v)
|
2019-11-20 16:12:32 -05:00
|
|
|
{
|
|
|
|
|
CurveProfile *profile = profile_v;
|
2020-06-24 11:50:01 -04:00
|
|
|
BKE_curveprofile_update(profile, PROF_UPDATE_REMOVE_DOUBLES | PROF_UPDATE_CLIP);
|
|
|
|
|
rna_update_cb(C, arg1_v, NULL);
|
2019-11-20 16:12:32 -05:00
|
|
|
}
|
|
|
|
|
|
2020-06-24 11:50:01 -04:00
|
|
|
static void CurveProfile_buttons_reset(bContext *C, void *arg1_v, void *profile_v)
|
2019-11-20 16:12:32 -05:00
|
|
|
{
|
|
|
|
|
CurveProfile *profile = profile_v;
|
2020-06-24 11:50:01 -04:00
|
|
|
BKE_curveprofile_reset(profile);
|
|
|
|
|
BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
|
2019-11-20 16:12:32 -05:00
|
|
|
rna_update_cb(C, arg1_v, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUpdateCb *cb)
|
|
|
|
|
{
|
|
|
|
|
CurveProfile *profile = ptr->data;
|
|
|
|
|
uiBut *bt;
|
|
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2019-11-20 16:12:32 -05:00
|
|
|
|
|
|
|
|
UI_block_emboss_set(block, UI_EMBOSS);
|
|
|
|
|
|
2020-06-24 11:50:01 -04:00
|
|
|
uiLayoutSetPropSep(layout, false);
|
2019-11-20 16:12:32 -05:00
|
|
|
|
|
|
|
|
/* Preset selector */
|
|
|
|
|
/* There is probably potential to use simpler "uiItemR" functions here, but automatic updating
|
|
|
|
|
* after a preset is selected would be more complicated. */
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *row = uiLayoutRow(layout, true);
|
2019-11-20 16:12:32 -05:00
|
|
|
bt = uiDefBlockBut(
|
|
|
|
|
block, CurveProfile_buttons_presets, profile, "Preset", 0, 0, UI_UNIT_X, UI_UNIT_X, "");
|
|
|
|
|
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
|
|
|
|
|
|
2020-06-24 11:50:01 -04:00
|
|
|
/* Show a "re-apply" preset button when it has been changed from the preset. */
|
|
|
|
|
if (profile->flag & PROF_DIRTY_PRESET) {
|
|
|
|
|
/* Only for dynamic presets. */
|
|
|
|
|
if (ELEM(profile->preset, PROF_PRESET_STEPS, PROF_PRESET_SUPPORTS)) {
|
|
|
|
|
bt = uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_NONE,
|
|
|
|
|
"Apply Preset",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
"Reapply and update the preset, removing changes");
|
|
|
|
|
UI_but_funcN_set(bt, CurveProfile_buttons_reset, MEM_dupallocN(cb), profile);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-20 16:12:32 -05:00
|
|
|
row = uiLayoutRow(layout, false);
|
|
|
|
|
|
|
|
|
|
/* (Left aligned) */
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *sub = uiLayoutRow(row, true);
|
2019-11-20 16:12:32 -05:00
|
|
|
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
|
|
|
|
|
|
|
|
|
|
/* Zoom in */
|
|
|
|
|
bt = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_ZOOM_IN,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
TIP_("Zoom in"));
|
|
|
|
|
UI_but_func_set(bt, CurveProfile_buttons_zoom_in, profile, NULL);
|
|
|
|
|
|
|
|
|
|
/* Zoom out */
|
|
|
|
|
bt = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_ZOOM_OUT,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
TIP_("Zoom out"));
|
|
|
|
|
UI_but_func_set(bt, CurveProfile_buttons_zoom_out, profile, NULL);
|
|
|
|
|
|
|
|
|
|
/* (Right aligned) */
|
|
|
|
|
sub = uiLayoutRow(row, true);
|
|
|
|
|
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
|
|
|
|
|
|
|
|
|
|
/* Reset view, reset curve */
|
|
|
|
|
bt = uiDefIconBlockBut(
|
|
|
|
|
block, CurveProfile_buttons_tools, profile, 0, 0, 0, 0, UI_UNIT_X, UI_UNIT_X, TIP_("Tools"));
|
|
|
|
|
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
|
|
|
|
|
|
|
|
|
|
/* Flip path */
|
|
|
|
|
bt = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_ARROW_LEFTRIGHT,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
TIP_("Reverse Path"));
|
|
|
|
|
UI_but_funcN_set(bt, CurveProfile_buttons_reverse, MEM_dupallocN(cb), profile);
|
|
|
|
|
|
|
|
|
|
/* Clipping toggle */
|
2021-01-04 17:02:13 +11:00
|
|
|
const int icon = (profile->flag & PROF_USE_CLIP) ? ICON_CLIPUV_HLT : ICON_CLIPUV_DEHLT;
|
2019-11-20 16:12:32 -05:00
|
|
|
bt = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
icon,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
TIP_("Toggle Profile Clipping"));
|
|
|
|
|
UI_but_funcN_set(bt, CurveProfile_clipping_toggle, MEM_dupallocN(cb), profile);
|
|
|
|
|
|
|
|
|
|
UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), NULL);
|
|
|
|
|
|
|
|
|
|
/* The path itself */
|
2020-10-04 22:44:19 -05:00
|
|
|
int path_width = max_ii(uiLayoutGetWidth(layout), UI_UNIT_X);
|
2019-11-20 16:12:32 -05:00
|
|
|
path_width = min_ii(path_width, (int)(16.0f * UI_UNIT_X));
|
2021-01-04 17:02:13 +11:00
|
|
|
const int path_height = path_width;
|
2019-11-20 16:12:32 -05:00
|
|
|
uiLayoutRow(layout, false);
|
|
|
|
|
uiDefBut(block,
|
|
|
|
|
UI_BTYPE_CURVEPROFILE,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
(short)path_width,
|
|
|
|
|
(short)path_height,
|
|
|
|
|
profile,
|
|
|
|
|
0.0f,
|
|
|
|
|
1.0f,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
|
|
|
|
|
/* Position sliders for (first) selected point */
|
2020-10-04 22:44:19 -05:00
|
|
|
int i;
|
2020-06-24 11:50:01 -04:00
|
|
|
float *selection_x, *selection_y;
|
2020-10-04 22:44:19 -05:00
|
|
|
bool point_last_or_first = false;
|
|
|
|
|
CurveProfilePoint *point = NULL;
|
2019-11-20 16:12:32 -05:00
|
|
|
for (i = 0; i < profile->path_len; i++) {
|
|
|
|
|
if (profile->path[i].flag & PROF_SELECT) {
|
|
|
|
|
point = &profile->path[i];
|
2020-06-24 11:50:01 -04:00
|
|
|
selection_x = &point->x;
|
|
|
|
|
selection_y = &point->y;
|
2019-11-20 16:12:32 -05:00
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (profile->path[i].flag & PROF_H1_SELECT) {
|
2020-06-24 11:50:01 -04:00
|
|
|
point = &profile->path[i];
|
|
|
|
|
selection_x = &point->h1_loc[0];
|
|
|
|
|
selection_y = &point->h1_loc[1];
|
|
|
|
|
}
|
|
|
|
|
else if (profile->path[i].flag & PROF_H2_SELECT) {
|
|
|
|
|
point = &profile->path[i];
|
|
|
|
|
selection_x = &point->h2_loc[0];
|
|
|
|
|
selection_y = &point->h2_loc[1];
|
|
|
|
|
}
|
2019-11-20 16:12:32 -05:00
|
|
|
}
|
2020-11-06 12:30:59 +11:00
|
|
|
if (ELEM(i, 0, profile->path_len - 1)) {
|
2019-11-20 16:12:32 -05:00
|
|
|
point_last_or_first = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Selected point data */
|
2020-10-04 22:44:19 -05:00
|
|
|
rctf bounds;
|
2019-11-20 16:12:32 -05:00
|
|
|
if (point) {
|
|
|
|
|
if (profile->flag & PROF_USE_CLIP) {
|
|
|
|
|
bounds = profile->clip_rect;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
bounds.xmin = bounds.ymin = -1000.0;
|
|
|
|
|
bounds.xmax = bounds.ymax = 1000.0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-24 11:50:01 -04:00
|
|
|
row = uiLayoutRow(layout, true);
|
2019-11-20 16:12:32 -05:00
|
|
|
|
2020-06-24 11:50:01 -04:00
|
|
|
PointerRNA point_ptr;
|
|
|
|
|
RNA_pointer_create(ptr->owner_id, &RNA_CurveProfilePoint, point, &point_ptr);
|
|
|
|
|
PropertyRNA *prop_handle_type = RNA_struct_find_property(&point_ptr, "handle_type_1");
|
|
|
|
|
uiItemFullR(row,
|
|
|
|
|
&point_ptr,
|
|
|
|
|
prop_handle_type,
|
|
|
|
|
RNA_NO_INDEX,
|
|
|
|
|
0,
|
|
|
|
|
UI_ITEM_R_EXPAND | UI_ITEM_R_ICON_ONLY,
|
|
|
|
|
"",
|
|
|
|
|
ICON_NONE);
|
2019-11-20 16:12:32 -05:00
|
|
|
|
|
|
|
|
/* Position */
|
|
|
|
|
bt = uiDefButF(block,
|
|
|
|
|
UI_BTYPE_NUM,
|
|
|
|
|
0,
|
|
|
|
|
"X:",
|
|
|
|
|
0,
|
|
|
|
|
2 * UI_UNIT_Y,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
UI_UNIT_Y,
|
2020-06-24 11:50:01 -04:00
|
|
|
selection_x,
|
2019-11-20 16:12:32 -05:00
|
|
|
bounds.xmin,
|
|
|
|
|
bounds.xmax,
|
2020-09-04 21:18:45 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
2019-11-20 16:12:32 -05:00
|
|
|
"");
|
2020-09-04 21:18:45 +02:00
|
|
|
UI_but_number_step_size_set(bt, 1);
|
|
|
|
|
UI_but_number_precision_set(bt, 5);
|
2020-06-24 11:50:01 -04:00
|
|
|
UI_but_funcN_set(bt, CurveProfile_buttons_update, MEM_dupallocN(cb), profile);
|
2019-11-20 16:12:32 -05:00
|
|
|
if (point_last_or_first) {
|
|
|
|
|
UI_but_flag_enable(bt, UI_BUT_DISABLED);
|
|
|
|
|
}
|
|
|
|
|
bt = uiDefButF(block,
|
|
|
|
|
UI_BTYPE_NUM,
|
|
|
|
|
0,
|
|
|
|
|
"Y:",
|
|
|
|
|
0,
|
|
|
|
|
1 * UI_UNIT_Y,
|
|
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
UI_UNIT_Y,
|
2020-06-24 11:50:01 -04:00
|
|
|
selection_y,
|
2019-11-20 16:12:32 -05:00
|
|
|
bounds.ymin,
|
|
|
|
|
bounds.ymax,
|
2020-09-04 21:18:45 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
2019-11-20 16:12:32 -05:00
|
|
|
"");
|
2020-09-04 21:18:45 +02:00
|
|
|
UI_but_number_step_size_set(bt, 1);
|
|
|
|
|
UI_but_number_precision_set(bt, 5);
|
2020-06-24 11:50:01 -04:00
|
|
|
UI_but_funcN_set(bt, CurveProfile_buttons_update, MEM_dupallocN(cb), profile);
|
2019-11-20 16:12:32 -05:00
|
|
|
if (point_last_or_first) {
|
|
|
|
|
UI_but_flag_enable(bt, UI_BUT_DISABLED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Delete points */
|
|
|
|
|
bt = uiDefIconBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
0,
|
|
|
|
|
ICON_X,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
TIP_("Delete points"));
|
|
|
|
|
UI_but_funcN_set(bt, CurveProfile_buttons_delete, MEM_dupallocN(cb), profile);
|
|
|
|
|
if (point_last_or_first) {
|
|
|
|
|
UI_but_flag_enable(bt, UI_BUT_DISABLED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uiItemR(layout, ptr, "use_sample_straight_edges", 0, NULL, ICON_NONE);
|
|
|
|
|
uiItemR(layout, ptr, "use_sample_even_lengths", 0, NULL, ICON_NONE);
|
|
|
|
|
|
|
|
|
|
UI_block_funcN_set(block, NULL, NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-25 01:14:39 +11:00
|
|
|
/**
|
|
|
|
|
* Template for a path creation widget intended for custom bevel profiles.
|
|
|
|
|
* This section is quite similar to #uiTemplateCurveMapping, but with reduced complexity.
|
|
|
|
|
*/
|
2019-11-20 16:12:32 -05:00
|
|
|
void uiTemplateCurveProfile(uiLayout *layout, PointerRNA *ptr, const char *propname)
|
|
|
|
|
{
|
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
2020-10-04 22:44:19 -05:00
|
|
|
|
2019-11-20 16:12:32 -05:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
|
|
|
|
|
|
|
|
|
if (!prop) {
|
|
|
|
|
RNA_warning(
|
|
|
|
|
"Curve Profile property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (RNA_property_type(prop) != PROP_POINTER) {
|
|
|
|
|
RNA_warning(
|
|
|
|
|
"Curve Profile is not a pointer: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
|
2019-11-20 16:12:32 -05:00
|
|
|
if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_CurveProfile)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Share update functionality with the CurveMapping widget template. */
|
2020-10-04 22:44:19 -05:00
|
|
|
RNAUpdateCb *cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
|
2019-11-20 16:12:32 -05:00
|
|
|
cb->ptr = *ptr;
|
|
|
|
|
cb->prop = prop;
|
|
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
ID *id = cptr.owner_id;
|
2019-11-20 16:12:32 -05:00
|
|
|
UI_block_lock_set(block, (id && ID_IS_LINKED(id)), ERROR_LIBDATA_MESSAGE);
|
|
|
|
|
|
|
|
|
|
CurveProfile_buttons_layout(layout, &cptr, cb);
|
|
|
|
|
|
|
|
|
|
UI_block_lock_clear(block);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(cb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name ColorPicker Template
|
|
|
|
|
* \{ */
|
2010-01-07 09:55:11 +00:00
|
|
|
|
2012-12-13 02:40:49 +00:00
|
|
|
#define WHEEL_SIZE (5 * U.widget_unit)
|
2010-01-07 09:55:11 +00:00
|
|
|
|
2012-11-09 10:33:42 +00:00
|
|
|
/* This template now follows User Preference for type - name is not correct anymore... */
|
2015-05-05 03:13:47 +10:00
|
|
|
void uiTemplateColorPicker(uiLayout *layout,
|
2018-07-01 15:47:09 +02:00
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
bool value_slider,
|
|
|
|
|
bool lock,
|
|
|
|
|
bool lock_luminosity,
|
|
|
|
|
bool cubic)
|
2010-01-07 09:55:11 +00:00
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
|
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2014-11-09 21:20:40 +01:00
|
|
|
ColorPicker *cpicker = ui_block_colorpicker_create(block);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-01-07 09:55:11 +00:00
|
|
|
if (!prop) {
|
2011-09-09 01:29:53 +00:00
|
|
|
RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
2010-01-07 09:55:11 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
float softmin, softmax, step, precision;
|
2010-01-27 00:22:29 +00:00
|
|
|
RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *col = uiLayoutColumn(layout, true);
|
|
|
|
|
uiLayout *row = uiLayoutRow(col, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBut *but = NULL;
|
|
|
|
|
uiButHSVCube *hsv_but;
|
2012-11-09 10:33:42 +00:00
|
|
|
switch (U.color_picker_type) {
|
|
|
|
|
case USER_CP_SQUARE_SV:
|
|
|
|
|
case USER_CP_SQUARE_HS:
|
|
|
|
|
case USER_CP_SQUARE_HV:
|
2020-08-07 17:42:13 +02:00
|
|
|
hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_HSVCUBE,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
WHEEL_SIZE,
|
|
|
|
|
WHEEL_SIZE,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
-1,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
switch (U.color_picker_type) {
|
|
|
|
|
case USER_CP_SQUARE_SV:
|
|
|
|
|
hsv_but->gradient_type = UI_GRAD_SV;
|
|
|
|
|
break;
|
|
|
|
|
case USER_CP_SQUARE_HS:
|
|
|
|
|
hsv_but->gradient_type = UI_GRAD_HS;
|
|
|
|
|
break;
|
|
|
|
|
case USER_CP_SQUARE_HV:
|
|
|
|
|
hsv_but->gradient_type = UI_GRAD_HV;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
but = &hsv_but->but;
|
2012-11-09 10:33:42 +00:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-13 06:18:25 +11:00
|
|
|
/* user default */
|
|
|
|
|
case USER_CP_CIRCLE_HSV:
|
|
|
|
|
case USER_CP_CIRCLE_HSL:
|
2014-03-12 21:06:57 +02:00
|
|
|
default:
|
2018-07-01 19:57:31 +02:00
|
|
|
but = uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_HSVCIRCLE,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
WHEEL_SIZE,
|
|
|
|
|
WHEEL_SIZE,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
-1,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
2014-03-12 21:06:57 +02:00
|
|
|
break;
|
2012-11-09 10:33:42 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-06 20:19:21 +01:00
|
|
|
but->custom_data = cpicker;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-22 14:01:11 +11:00
|
|
|
cpicker->use_color_lock = lock;
|
|
|
|
|
cpicker->use_color_cubic = cubic;
|
|
|
|
|
cpicker->use_luminosity_lock = lock_luminosity;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (lock_luminosity) {
|
2012-03-09 00:41:09 +00:00
|
|
|
float color[4]; /* in case of alpha */
|
2010-07-04 20:59:10 +00:00
|
|
|
RNA_property_float_get_array(ptr, prop, color);
|
2012-03-30 01:51:25 +00:00
|
|
|
but->a2 = len_v3(color);
|
2019-03-22 14:01:11 +11:00
|
|
|
cpicker->luminosity_lock_value = len_v3(color);
|
2010-07-04 20:59:10 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-11-09 10:33:42 +00:00
|
|
|
if (value_slider) {
|
|
|
|
|
switch (U.color_picker_type) {
|
2014-03-12 18:58:50 +02:00
|
|
|
case USER_CP_CIRCLE_HSL:
|
2018-07-03 10:15:26 +02:00
|
|
|
uiItemS(row);
|
2020-08-07 17:42:13 +02:00
|
|
|
hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_HSVCUBE,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
WHEEL_SIZE + 6,
|
|
|
|
|
0,
|
|
|
|
|
14 * UI_DPI_FAC,
|
|
|
|
|
WHEEL_SIZE,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
-1,
|
|
|
|
|
softmin,
|
|
|
|
|
softmax,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
hsv_but->gradient_type = UI_GRAD_L_ALT;
|
2014-03-12 18:58:50 +02:00
|
|
|
break;
|
2012-11-09 10:33:42 +00:00
|
|
|
case USER_CP_SQUARE_SV:
|
|
|
|
|
uiItemS(col);
|
2020-08-07 17:42:13 +02:00
|
|
|
hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_HSVCUBE,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
4,
|
|
|
|
|
WHEEL_SIZE,
|
|
|
|
|
18 * UI_DPI_FAC,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
-1,
|
|
|
|
|
softmin,
|
|
|
|
|
softmax,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
hsv_but->gradient_type = UI_GRAD_SV + 3;
|
2012-11-09 10:33:42 +00:00
|
|
|
break;
|
|
|
|
|
case USER_CP_SQUARE_HS:
|
|
|
|
|
uiItemS(col);
|
2020-08-07 17:42:13 +02:00
|
|
|
hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_HSVCUBE,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
4,
|
|
|
|
|
WHEEL_SIZE,
|
|
|
|
|
18 * UI_DPI_FAC,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
-1,
|
|
|
|
|
softmin,
|
|
|
|
|
softmax,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
hsv_but->gradient_type = UI_GRAD_HS + 3;
|
2012-11-09 10:33:42 +00:00
|
|
|
break;
|
|
|
|
|
case USER_CP_SQUARE_HV:
|
|
|
|
|
uiItemS(col);
|
2020-08-07 17:42:13 +02:00
|
|
|
hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_HSVCUBE,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
4,
|
|
|
|
|
WHEEL_SIZE,
|
|
|
|
|
18 * UI_DPI_FAC,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
-1,
|
|
|
|
|
softmin,
|
|
|
|
|
softmax,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
hsv_but->gradient_type = UI_GRAD_HV + 3;
|
2012-11-09 10:33:42 +00:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-13 06:18:25 +11:00
|
|
|
/* user default */
|
|
|
|
|
case USER_CP_CIRCLE_HSV:
|
2014-03-12 21:06:57 +02:00
|
|
|
default:
|
|
|
|
|
uiItemS(row);
|
2020-08-07 17:42:13 +02:00
|
|
|
hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
|
|
|
|
|
UI_BTYPE_HSVCUBE,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
WHEEL_SIZE + 6,
|
|
|
|
|
0,
|
|
|
|
|
14 * UI_DPI_FAC,
|
|
|
|
|
WHEEL_SIZE,
|
|
|
|
|
ptr,
|
|
|
|
|
prop,
|
|
|
|
|
-1,
|
|
|
|
|
softmin,
|
|
|
|
|
softmax,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
hsv_but->gradient_type = UI_GRAD_V_ALT;
|
2014-03-12 21:06:57 +02:00
|
|
|
break;
|
2012-11-09 10:33:42 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-07 17:42:13 +02:00
|
|
|
hsv_but->but.custom_data = cpicker;
|
2012-11-09 10:33:42 +00:00
|
|
|
}
|
2010-01-07 09:55:11 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-09 16:27:24 +01:00
|
|
|
static void ui_template_palette_menu(bContext *UNUSED(C), uiLayout *layout, void *UNUSED(but_p))
|
|
|
|
|
{
|
|
|
|
|
uiLayout *row;
|
|
|
|
|
|
2020-10-24 11:42:17 -07:00
|
|
|
uiItemL(layout, IFACE_("Sort By:"), ICON_NONE);
|
2020-03-09 16:27:24 +01:00
|
|
|
row = uiLayoutRow(layout, false);
|
|
|
|
|
uiItemEnumO_value(row, IFACE_("Hue"), ICON_NONE, "PALETTE_OT_sort", "type", 1);
|
|
|
|
|
row = uiLayoutRow(layout, false);
|
|
|
|
|
uiItemEnumO_value(row, IFACE_("Saturation"), ICON_NONE, "PALETTE_OT_sort", "type", 2);
|
|
|
|
|
row = uiLayoutRow(layout, false);
|
|
|
|
|
uiItemEnumO_value(row, IFACE_("Value"), ICON_NONE, "PALETTE_OT_sort", "type", 3);
|
|
|
|
|
row = uiLayoutRow(layout, false);
|
|
|
|
|
uiItemEnumO_value(row, IFACE_("Luminance"), ICON_NONE, "PALETTE_OT_sort", "type", 4);
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-01 15:47:09 +02:00
|
|
|
void uiTemplatePalette(uiLayout *layout,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
bool UNUSED(colors))
|
2014-07-21 12:02:05 +02:00
|
|
|
{
|
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
2020-03-09 16:27:24 +01:00
|
|
|
uiBut *but = NULL;
|
|
|
|
|
|
2020-08-26 10:11:13 +10:00
|
|
|
const int cols_per_row = MAX2(uiLayoutGetWidth(layout) / UI_UNIT_X, 1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-07-21 12:02:05 +02:00
|
|
|
if (!prop) {
|
|
|
|
|
RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-04 17:02:13 +11:00
|
|
|
const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Palette)) {
|
2014-07-21 12:02:05 +02:00
|
|
|
return;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
Palette *palette = cptr.data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *col = uiLayoutColumn(layout, true);
|
2014-07-21 12:02:05 +02:00
|
|
|
uiLayoutRow(col, true);
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefIconButO(block,
|
2018-10-01 10:45:50 +02:00
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
"PALETTE_OT_color_add",
|
|
|
|
|
WM_OP_INVOKE_DEFAULT,
|
|
|
|
|
ICON_ADD,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL);
|
|
|
|
|
uiDefIconButO(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
"PALETTE_OT_color_delete",
|
|
|
|
|
WM_OP_INVOKE_DEFAULT,
|
|
|
|
|
ICON_REMOVE,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL);
|
2020-08-18 21:46:29 -04:00
|
|
|
if (palette->colors.first != NULL) {
|
2020-03-09 16:27:24 +01:00
|
|
|
but = uiDefIconButO(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
"PALETTE_OT_color_move",
|
|
|
|
|
WM_OP_INVOKE_DEFAULT,
|
|
|
|
|
ICON_TRIA_UP,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL);
|
|
|
|
|
UI_but_operator_ptr_get(but);
|
|
|
|
|
RNA_enum_set(but->opptr, "type", -1);
|
|
|
|
|
|
|
|
|
|
but = uiDefIconButO(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
"PALETTE_OT_color_move",
|
|
|
|
|
WM_OP_INVOKE_DEFAULT,
|
|
|
|
|
ICON_TRIA_DOWN,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL);
|
|
|
|
|
UI_but_operator_ptr_get(but);
|
|
|
|
|
RNA_enum_set(but->opptr, "type", 1);
|
|
|
|
|
|
|
|
|
|
/* Menu. */
|
|
|
|
|
uiDefIconMenuBut(
|
|
|
|
|
block, ui_template_palette_menu, NULL, ICON_SORTSIZE, 0, 0, UI_UNIT_X, UI_UNIT_Y, "");
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-07-21 12:02:05 +02:00
|
|
|
col = uiLayoutColumn(layout, true);
|
|
|
|
|
uiLayoutRow(col, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
int row_cols = 0, col_id = 0;
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH (PaletteColor *, color, &palette->colors) {
|
2014-07-21 12:02:05 +02:00
|
|
|
if (row_cols >= cols_per_row) {
|
|
|
|
|
uiLayoutRow(col, true);
|
|
|
|
|
row_cols = 0;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
PointerRNA color_ptr;
|
2015-11-23 10:01:54 +11:00
|
|
|
RNA_pointer_create(&palette->id, &RNA_PaletteColor, color, &color_ptr);
|
2020-08-07 15:02:07 +02:00
|
|
|
uiButColor *color_but = (uiButColor *)uiDefButR(block,
|
|
|
|
|
UI_BTYPE_COLOR,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
&color_ptr,
|
|
|
|
|
"color",
|
|
|
|
|
-1,
|
|
|
|
|
0.0,
|
|
|
|
|
1.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
"");
|
|
|
|
|
color_but->is_pallete_color = true;
|
|
|
|
|
color_but->palette_color_index = col_id;
|
2014-07-21 12:02:05 +02:00
|
|
|
row_cols++;
|
|
|
|
|
col_id++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Compositor: Redesign Cryptomatte node for better usability
In the current implementation, cryptomatte passes are connected to the node
and elements are picked by using the eyedropper tool on a special pick channel.
This design has two disadvantages - both connecting all passes individually
and always having to switch to the picker channel are tedious.
With the new design, the user selects the RenderLayer or Image from which the
Cryptomatte layers are directly loaded (the type of pass is determined by an
enum). This allows the node to automatically detect all relevant passes.
Then, when using the eyedropper tool, the operator looks up the selected
coordinates from the picked Image, Node backdrop or Clip and reads the picked
object directly from the Renderlayer/Image, therefore allowing to pick in any
context (e.g. by clicking on the Combined pass in the Image Viewer). The
sampled color is looked up in the metadata and the actual name is stored
in the cryptomatte node. This also allows to remove a hash by just removing
the name from the matte id.
Technically there is some loss of flexibility because the Cryptomatte pass
inputs can no longer be connected to other nodes, but since any compositing
done on them is likely to break the Cryptomatte system anyways, this isn't
really a concern in practise.
In the future, this would also allow to automatically translate values to names
by looking up the value in the associated metadata of the input, or to get a
better visualization of overlapping areas in the Pick output since we could
blend colors now that the output doesn't have to contain the exact value.
Idea + Original patch: Lucas Stockner
Reviewed By: Brecht van Lommel
Differential Revision: https://developer.blender.org/D3959
2021-03-16 07:37:30 +01:00
|
|
|
void uiTemplateCryptoPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, int icon)
|
2018-07-18 13:03:09 +02:00
|
|
|
{
|
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-18 13:03:09 +02:00
|
|
|
if (!prop) {
|
|
|
|
|
RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBut *but = uiDefIconTextButO(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
"UI_OT_eyedropper_color",
|
|
|
|
|
WM_OP_INVOKE_DEFAULT,
|
Compositor: Redesign Cryptomatte node for better usability
In the current implementation, cryptomatte passes are connected to the node
and elements are picked by using the eyedropper tool on a special pick channel.
This design has two disadvantages - both connecting all passes individually
and always having to switch to the picker channel are tedious.
With the new design, the user selects the RenderLayer or Image from which the
Cryptomatte layers are directly loaded (the type of pass is determined by an
enum). This allows the node to automatically detect all relevant passes.
Then, when using the eyedropper tool, the operator looks up the selected
coordinates from the picked Image, Node backdrop or Clip and reads the picked
object directly from the Renderlayer/Image, therefore allowing to pick in any
context (e.g. by clicking on the Combined pass in the Image Viewer). The
sampled color is looked up in the metadata and the actual name is stored
in the cryptomatte node. This also allows to remove a hash by just removing
the name from the matte id.
Technically there is some loss of flexibility because the Cryptomatte pass
inputs can no longer be connected to other nodes, but since any compositing
done on them is likely to break the Cryptomatte system anyways, this isn't
really a concern in practise.
In the future, this would also allow to automatically translate values to names
by looking up the value in the associated metadata of the input, or to get a
better visualization of overlapping areas in the Pick output since we could
blend colors now that the output doesn't have to contain the exact value.
Idea + Original patch: Lucas Stockner
Reviewed By: Brecht van Lommel
Differential Revision: https://developer.blender.org/D3959
2021-03-16 07:37:30 +01:00
|
|
|
icon,
|
2021-03-22 08:58:20 -04:00
|
|
|
"",
|
2020-10-04 22:44:19 -05:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
RNA_property_ui_description(prop));
|
2018-07-18 13:03:09 +02:00
|
|
|
but->rnapoin = *ptr;
|
|
|
|
|
but->rnaprop = prop;
|
|
|
|
|
but->rnaindex = -1;
|
|
|
|
|
}
|
2014-07-21 12:02:05 +02:00
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Layer Buttons Template
|
|
|
|
|
* \{ */
|
2009-06-13 11:21:02 +00:00
|
|
|
|
2009-11-29 06:04:39 +00:00
|
|
|
static void handle_layer_buttons(bContext *C, void *arg1, void *arg2)
|
|
|
|
|
{
|
|
|
|
|
uiBut *but = arg1;
|
2020-08-26 10:11:13 +10:00
|
|
|
const int cur = POINTER_AS_INT(arg2);
|
2012-03-30 01:51:25 +00:00
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2021-01-04 17:02:13 +11:00
|
|
|
const int shift = win->eventstate->shift;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!shift) {
|
2021-01-04 17:02:13 +11:00
|
|
|
const int tot = RNA_property_array_length(&but->rnapoin, but->rnaprop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-11-29 06:04:39 +00:00
|
|
|
/* Normally clicking only selects one layer */
|
2014-01-04 17:16:19 +11:00
|
|
|
RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, cur, true);
|
2020-10-04 22:44:19 -05:00
|
|
|
for (int i = 0; i < tot; i++) {
|
2019-03-25 10:15:20 +11:00
|
|
|
if (i != cur) {
|
2014-01-04 17:16:19 +11:00
|
|
|
RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, i, false);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2009-11-29 06:04:39 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-03-19 16:30:52 +00:00
|
|
|
/* view3d layer change should update depsgraph (invisible object changed maybe) */
|
|
|
|
|
/* see view3d_header.c */
|
2009-11-29 06:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-31 14:20:03 +10:00
|
|
|
/**
|
|
|
|
|
* \todo for now, grouping of layers is determined by dividing up the length of
|
|
|
|
|
* the array of layer bitflags
|
|
|
|
|
*/
|
2015-05-05 03:13:47 +10:00
|
|
|
void uiTemplateLayers(uiLayout *layout,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
PointerRNA *used_ptr,
|
|
|
|
|
const char *used_propname,
|
|
|
|
|
int active_layer)
|
2009-06-13 11:21:02 +00:00
|
|
|
{
|
2020-08-26 10:11:13 +10:00
|
|
|
const int cols_per_group = 5;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
2009-06-13 11:21:02 +00:00
|
|
|
if (!prop) {
|
2011-09-09 01:29:53 +00:00
|
|
|
RNA_warning("layers property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
2009-06-13 11:21:02 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-23 10:47:12 +02:00
|
|
|
/* the number of layers determines the way we group them
|
2018-11-14 12:53:15 +11:00
|
|
|
* - we want 2 rows only (for now)
|
2019-04-17 08:44:38 +02:00
|
|
|
* - The number of columns (cols) is the total number of buttons per row the 'remainder'
|
|
|
|
|
* is added to this, as it will be ok to have first row slightly wider if need be.
|
|
|
|
|
* - For now, only split into groups if group will have at least 5 items.
|
2009-06-13 11:21:02 +00:00
|
|
|
*/
|
2020-10-04 22:44:19 -05:00
|
|
|
const int layers = RNA_property_array_length(ptr, prop);
|
|
|
|
|
const int cols = (layers / 2) + (layers % 2);
|
|
|
|
|
const int groups = ((cols / 2) < cols_per_group) ? (1) : (cols / cols_per_group);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
PropertyRNA *used_prop = NULL;
|
2012-03-24 06:38:07 +00:00
|
|
|
if (used_ptr && used_propname) {
|
2012-03-30 01:51:25 +00:00
|
|
|
used_prop = RNA_struct_find_property(used_ptr, used_propname);
|
2009-11-29 02:42:47 +00:00
|
|
|
if (!used_prop) {
|
2011-09-09 01:29:53 +00:00
|
|
|
RNA_warning("used layers property not found: %s.%s",
|
|
|
|
|
RNA_struct_identifier(ptr->type),
|
|
|
|
|
used_propname);
|
2009-11-29 02:42:47 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (RNA_property_array_length(used_ptr, used_prop) < layers) {
|
2009-11-29 02:42:47 +00:00
|
|
|
used_prop = NULL;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2009-06-13 11:21:02 +00:00
|
|
|
/* layers are laid out going across rows, with the columns being divided into groups */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
for (int group = 0; group < groups; group++) {
|
|
|
|
|
uiLayout *uCol = uiLayoutColumn(layout, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
for (int row = 0; row < 2; row++) {
|
|
|
|
|
uiLayout *uRow = uiLayoutRow(uCol, true);
|
|
|
|
|
uiBlock *block = uiLayoutGetBlock(uRow);
|
|
|
|
|
int layer = groups * cols_per_group * row + cols_per_group * group;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-13 11:21:02 +00:00
|
|
|
/* add layers as toggle buts */
|
2020-10-04 22:44:19 -05:00
|
|
|
for (int col = 0; (col < cols_per_group) && (layer < layers); col++, layer++) {
|
2009-11-29 02:42:47 +00:00
|
|
|
int icon = 0;
|
2020-08-26 10:11:13 +10:00
|
|
|
const int butlay = 1 << layer;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (active_layer & butlay) {
|
2009-11-29 02:42:47 +00:00
|
|
|
icon = ICON_LAYER_ACTIVE;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
else if (used_prop && RNA_property_boolean_get_index(used_ptr, used_prop, layer)) {
|
2009-11-29 02:42:47 +00:00
|
|
|
icon = ICON_LAYER_USED;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBut *but = uiDefAutoButR(
|
|
|
|
|
block, ptr, prop, layer, "", icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2);
|
2018-09-19 12:05:58 +10:00
|
|
|
UI_but_func_set(but, handle_layer_buttons, but, POINTER_FROM_INT(layer));
|
2014-11-09 21:20:40 +01:00
|
|
|
but->type = UI_BTYPE_TOGGLE;
|
2009-06-13 11:21:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-06-22 23:58:16 +00:00
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name List Template
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2015-05-31 14:20:03 +10:00
|
|
|
static void uilist_draw_item_default(struct uiList *ui_list,
|
|
|
|
|
struct bContext *UNUSED(C),
|
|
|
|
|
struct uiLayout *layout,
|
|
|
|
|
struct PointerRNA *UNUSED(dataptr),
|
|
|
|
|
struct PointerRNA *itemptr,
|
|
|
|
|
int icon,
|
|
|
|
|
struct PointerRNA *UNUSED(active_dataptr),
|
|
|
|
|
const char *UNUSED(active_propname),
|
|
|
|
|
int UNUSED(index),
|
|
|
|
|
int UNUSED(flt_flag))
|
2009-09-28 18:33:45 +00:00
|
|
|
{
|
2013-11-23 18:43:23 +01:00
|
|
|
PropertyRNA *nameprop = RNA_struct_name_property(itemptr->type);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
/* Simplest one! */
|
2012-12-28 10:32:49 +00:00
|
|
|
switch (ui_list->layout_type) {
|
2013-06-26 13:22:25 +00:00
|
|
|
case UILST_LAYOUT_GRID:
|
|
|
|
|
uiItemL(layout, "", icon);
|
|
|
|
|
break;
|
|
|
|
|
case UILST_LAYOUT_DEFAULT:
|
|
|
|
|
case UILST_LAYOUT_COMPACT:
|
|
|
|
|
default:
|
2013-11-23 18:43:23 +01:00
|
|
|
if (nameprop) {
|
|
|
|
|
uiItemFullR(layout, itemptr, nameprop, RNA_NO_INDEX, 0, UI_ITEM_R_NO_BG, "", icon);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
uiItemL(layout, "", icon);
|
|
|
|
|
}
|
2013-06-26 13:22:25 +00:00
|
|
|
break;
|
2009-10-21 20:58:10 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-09 15:48:09 +01:00
|
|
|
static void uilist_draw_filter_default(struct uiList *ui_list,
|
|
|
|
|
struct bContext *UNUSED(C),
|
|
|
|
|
struct uiLayout *layout)
|
2013-08-29 12:55:31 +00:00
|
|
|
{
|
|
|
|
|
PointerRNA listptr;
|
|
|
|
|
RNA_pointer_create(NULL, &RNA_UIList, ui_list, &listptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *row = uiLayoutRow(layout, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *subrow = uiLayoutRow(row, true);
|
2013-08-29 12:55:31 +00:00
|
|
|
uiItemR(subrow, &listptr, "filter_name", 0, "", ICON_NONE);
|
|
|
|
|
uiItemR(subrow,
|
|
|
|
|
&listptr,
|
|
|
|
|
"use_filter_invert",
|
|
|
|
|
UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY,
|
|
|
|
|
"",
|
2020-10-14 15:21:02 +02:00
|
|
|
ICON_ARROW_LEFTRIGHT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-09 15:48:09 +01:00
|
|
|
if ((ui_list->filter_sort_flag & UILST_FLT_SORT_LOCK) == 0) {
|
2018-10-11 17:47:46 +02:00
|
|
|
subrow = uiLayoutRow(row, true);
|
|
|
|
|
uiItemR(subrow,
|
|
|
|
|
&listptr,
|
|
|
|
|
"use_filter_sort_alpha",
|
|
|
|
|
UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY,
|
|
|
|
|
"",
|
|
|
|
|
ICON_NONE);
|
|
|
|
|
uiItemR(subrow,
|
|
|
|
|
&listptr,
|
|
|
|
|
"use_filter_sort_reverse",
|
|
|
|
|
UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY,
|
|
|
|
|
"",
|
2018-11-21 06:21:58 +11:00
|
|
|
(ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) ? ICON_SORT_DESC : ICON_SORT_ASC);
|
2018-10-11 17:47:46 +02:00
|
|
|
}
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
char name[MAX_IDPROP_NAME];
|
|
|
|
|
int org_idx;
|
|
|
|
|
} StringCmp;
|
|
|
|
|
|
|
|
|
|
static int cmpstringp(const void *p1, const void *p2)
|
|
|
|
|
{
|
|
|
|
|
/* Case-insensitive comparison. */
|
2013-08-29 13:50:40 +00:00
|
|
|
return BLI_strcasecmp(((StringCmp *)p1)->name, ((StringCmp *)p2)->name);
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
|
|
|
|
|
2018-07-01 19:57:31 +02:00
|
|
|
static void uilist_filter_items_default(struct uiList *ui_list,
|
|
|
|
|
struct bContext *UNUSED(C),
|
|
|
|
|
struct PointerRNA *dataptr,
|
|
|
|
|
const char *propname)
|
2013-08-29 12:55:31 +00:00
|
|
|
{
|
|
|
|
|
uiListDyn *dyn_data = ui_list->dyn_data;
|
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(dataptr, propname);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
const char *filter_raw = ui_list->filter_byname;
|
|
|
|
|
char *filter = (char *)filter_raw, filter_buff[32], *filter_dyn = NULL;
|
2014-08-20 20:41:30 +02:00
|
|
|
const bool filter_exclude = (ui_list->filter_flag & UILST_FLT_EXCLUDE) != 0;
|
2019-01-09 15:48:09 +01:00
|
|
|
const bool order_by_name = (ui_list->filter_sort_flag & UILST_FLT_SORT_MASK) ==
|
|
|
|
|
UILST_FLT_SORT_ALPHA;
|
2020-08-26 10:11:13 +10:00
|
|
|
const int len = RNA_property_collection_length(dataptr, prop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
dyn_data->items_shown = dyn_data->items_len = len;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
if (len && (order_by_name || filter_raw[0])) {
|
|
|
|
|
StringCmp *names = NULL;
|
|
|
|
|
int order_idx = 0, i = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
if (order_by_name) {
|
2013-12-19 03:08:48 +11:00
|
|
|
names = MEM_callocN(sizeof(StringCmp) * len, "StringCmp");
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
|
|
|
|
if (filter_raw[0]) {
|
2020-08-26 10:11:13 +10:00
|
|
|
const size_t slen = strlen(filter_raw);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-12-19 03:08:48 +11:00
|
|
|
dyn_data->items_filter_flags = MEM_callocN(sizeof(int) * len, "items_filter_flags");
|
2013-08-29 12:55:31 +00:00
|
|
|
dyn_data->items_shown = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
/* Implicitly add heading/trailing wildcards if needed. */
|
2013-12-03 01:48:05 +11:00
|
|
|
if (slen + 3 <= sizeof(filter_buff)) {
|
2013-08-29 12:55:31 +00:00
|
|
|
filter = filter_buff;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2013-12-19 03:08:48 +11:00
|
|
|
filter = filter_dyn = MEM_mallocN((slen + 3) * sizeof(char), "filter_dyn");
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
2015-01-03 10:13:02 +01:00
|
|
|
BLI_strncpy_ensure_pad(filter, filter_raw, '*', slen + 3);
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
RNA_PROP_BEGIN (dataptr, itemptr, prop) {
|
|
|
|
|
bool do_order = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
char *namebuf = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL);
|
|
|
|
|
const char *name = namebuf ? namebuf : "";
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
if (filter[0]) {
|
|
|
|
|
/* Case-insensitive! */
|
|
|
|
|
if (fnmatch(filter, name, FNM_CASEFOLD) == 0) {
|
|
|
|
|
dyn_data->items_filter_flags[i] = UILST_FLT_ITEM;
|
|
|
|
|
if (!filter_exclude) {
|
|
|
|
|
dyn_data->items_shown++;
|
|
|
|
|
do_order = order_by_name;
|
|
|
|
|
}
|
2019-05-01 11:09:22 +10:00
|
|
|
// printf("%s: '%s' matches '%s'\n", __func__, name, filter);
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
|
|
|
|
else if (filter_exclude) {
|
|
|
|
|
dyn_data->items_shown++;
|
|
|
|
|
do_order = order_by_name;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
do_order = order_by_name;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
if (do_order) {
|
|
|
|
|
names[order_idx].org_idx = order_idx;
|
|
|
|
|
BLI_strncpy(names[order_idx++].name, name, MAX_IDPROP_NAME);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
/* free name */
|
|
|
|
|
if (namebuf) {
|
|
|
|
|
MEM_freeN(namebuf);
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
RNA_PROP_END;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
if (order_by_name) {
|
|
|
|
|
int new_idx;
|
|
|
|
|
/* note: order_idx equals either to ui_list->items_len if no filtering done,
|
|
|
|
|
* or to ui_list->items_shown if filter is enabled,
|
|
|
|
|
* or to (ui_list->items_len - ui_list->items_shown) if filtered items are excluded.
|
|
|
|
|
* This way, we only sort items we actually intend to draw!
|
|
|
|
|
*/
|
|
|
|
|
qsort(names, order_idx, sizeof(StringCmp), cmpstringp);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-12-19 03:08:48 +11:00
|
|
|
dyn_data->items_filter_neworder = MEM_mallocN(sizeof(int) * order_idx,
|
|
|
|
|
"items_filter_neworder");
|
2013-08-29 12:55:31 +00:00
|
|
|
for (new_idx = 0; new_idx < order_idx; new_idx++) {
|
|
|
|
|
dyn_data->items_filter_neworder[names[new_idx].org_idx] = new_idx;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
if (filter_dyn) {
|
|
|
|
|
MEM_freeN(filter_dyn);
|
|
|
|
|
}
|
|
|
|
|
if (names) {
|
|
|
|
|
MEM_freeN(names);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
PointerRNA item;
|
|
|
|
|
int org_idx;
|
|
|
|
|
int flt_flag;
|
|
|
|
|
} _uilist_item;
|
|
|
|
|
|
2013-08-27 15:27:41 +00:00
|
|
|
typedef struct {
|
|
|
|
|
int visual_items; /* Visual number of items (i.e. number of items we have room to display). */
|
|
|
|
|
int start_idx; /* Index of first item to display. */
|
|
|
|
|
int end_idx; /* Index of last item to display + 1. */
|
|
|
|
|
} uiListLayoutdata;
|
|
|
|
|
|
2015-05-05 03:13:47 +10:00
|
|
|
static void uilist_prepare(uiList *ui_list,
|
|
|
|
|
int len,
|
|
|
|
|
int activei,
|
|
|
|
|
int rows,
|
|
|
|
|
int maxrows,
|
|
|
|
|
int columns,
|
|
|
|
|
uiListLayoutdata *layoutdata)
|
2013-08-27 15:27:41 +00:00
|
|
|
{
|
|
|
|
|
uiListDyn *dyn_data = ui_list->dyn_data;
|
2014-04-02 13:09:43 +02:00
|
|
|
const bool use_auto_size = (ui_list->list_grip < (rows - UI_LIST_AUTO_SIZE_THRESHOLD));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-27 15:27:41 +00:00
|
|
|
/* default rows */
|
2019-03-25 10:15:20 +11:00
|
|
|
if (rows <= 0) {
|
2013-08-27 15:27:41 +00:00
|
|
|
rows = 5;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2013-08-27 15:27:41 +00:00
|
|
|
dyn_data->visual_height_min = rows;
|
2019-03-25 10:15:20 +11:00
|
|
|
if (maxrows < rows) {
|
2014-04-02 13:09:43 +02:00
|
|
|
maxrows = max_ii(rows, 5);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
|
|
|
|
if (columns <= 0) {
|
2013-08-27 15:27:41 +00:00
|
|
|
columns = 9;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
int activei_row;
|
2013-08-27 15:27:41 +00:00
|
|
|
if (columns > 1) {
|
|
|
|
|
dyn_data->height = (int)ceil((double)len / (double)columns);
|
|
|
|
|
activei_row = (int)floor((double)activei / (double)columns);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
dyn_data->height = len;
|
|
|
|
|
activei_row = activei;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-02 13:09:43 +02:00
|
|
|
if (!use_auto_size) {
|
|
|
|
|
/* No auto-size, yet we clamp at min size! */
|
|
|
|
|
maxrows = rows = max_ii(ui_list->list_grip, rows);
|
|
|
|
|
}
|
|
|
|
|
else if ((rows != maxrows) && (dyn_data->height > rows)) {
|
|
|
|
|
/* Expand size if needed and possible. */
|
2013-08-27 15:27:41 +00:00
|
|
|
rows = min_ii(dyn_data->height, maxrows);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-15 23:24:20 +11:00
|
|
|
/* If list length changes or list is tagged to check this,
|
2021-06-24 15:56:58 +10:00
|
|
|
* and active is out of view, scroll to it. */
|
2013-08-27 15:27:41 +00:00
|
|
|
if (ui_list->list_last_len != len || ui_list->flag & UILST_SCROLL_TO_ACTIVE_ITEM) {
|
|
|
|
|
if (activei_row < ui_list->list_scroll) {
|
|
|
|
|
ui_list->list_scroll = activei_row;
|
|
|
|
|
}
|
|
|
|
|
else if (activei_row >= ui_list->list_scroll + rows) {
|
|
|
|
|
ui_list->list_scroll = activei_row - rows + 1;
|
|
|
|
|
}
|
|
|
|
|
ui_list->flag &= ~UILST_SCROLL_TO_ACTIVE_ITEM;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-04 17:02:13 +11:00
|
|
|
const int max_scroll = max_ii(0, dyn_data->height - rows);
|
2013-08-27 15:27:41 +00:00
|
|
|
CLAMP(ui_list->list_scroll, 0, max_scroll);
|
|
|
|
|
ui_list->list_last_len = len;
|
|
|
|
|
dyn_data->visual_height = rows;
|
|
|
|
|
layoutdata->visual_items = rows * columns;
|
|
|
|
|
layoutdata->start_idx = ui_list->list_scroll * columns;
|
|
|
|
|
layoutdata->end_idx = min_ii(layoutdata->start_idx + rows * columns, len);
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-08 15:51:01 +02:00
|
|
|
static void uilist_resize_update_cb(bContext *C, void *arg1, void *UNUSED(arg2))
|
2014-04-02 13:09:43 +02:00
|
|
|
{
|
|
|
|
|
uiList *ui_list = arg1;
|
|
|
|
|
uiListDyn *dyn_data = ui_list->dyn_data;
|
|
|
|
|
|
|
|
|
|
/* This way we get diff in number of additional items to show (positive) or hide (negative). */
|
2017-09-27 11:13:03 +10:00
|
|
|
const int diff = round_fl_to_int((float)(dyn_data->resize - dyn_data->resize_prev) /
|
|
|
|
|
(float)UI_UNIT_Y);
|
2014-04-02 13:09:43 +02:00
|
|
|
|
|
|
|
|
if (diff != 0) {
|
|
|
|
|
ui_list->list_grip += diff;
|
|
|
|
|
dyn_data->resize_prev += diff * UI_UNIT_Y;
|
|
|
|
|
ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
|
|
|
|
|
}
|
2016-06-08 15:51:01 +02:00
|
|
|
|
|
|
|
|
/* In case uilist is in popup, we need special refreshing */
|
|
|
|
|
ED_region_tag_refresh_ui(CTX_wm_menu(C));
|
2014-04-02 13:09:43 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-11 00:06:03 +01:00
|
|
|
static void *uilist_item_use_dynamic_tooltip(PointerRNA *itemptr, const char *propname)
|
|
|
|
|
{
|
|
|
|
|
if (propname && propname[0] && itemptr && itemptr->data) {
|
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(itemptr, propname);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-02-11 00:06:03 +01:00
|
|
|
if (prop && (RNA_property_type(prop) == PROP_STRING)) {
|
|
|
|
|
return RNA_property_string_get_alloc(itemptr, prop, NULL, 0, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const char *tip)
|
|
|
|
|
{
|
|
|
|
|
char *dyn_tooltip = argN;
|
|
|
|
|
return BLI_sprintfN("%s - %s", tip, dyn_tooltip);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-05 03:13:47 +10:00
|
|
|
void uiTemplateList(uiLayout *layout,
|
|
|
|
|
bContext *C,
|
|
|
|
|
const char *listtype_name,
|
|
|
|
|
const char *list_id,
|
|
|
|
|
PointerRNA *dataptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
PointerRNA *active_dataptr,
|
|
|
|
|
const char *active_propname,
|
2019-01-09 15:48:09 +01:00
|
|
|
const char *item_dyntip_propname,
|
|
|
|
|
int rows,
|
|
|
|
|
int maxrows,
|
|
|
|
|
int layout_type,
|
|
|
|
|
int columns,
|
|
|
|
|
bool sort_reverse,
|
|
|
|
|
bool sort_lock)
|
2009-07-21 01:26:17 +00:00
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
PropertyRNA *prop = NULL, *activeprop;
|
2013-08-29 12:55:31 +00:00
|
|
|
_uilist_item *items_ptr = NULL;
|
2013-08-27 15:27:41 +00:00
|
|
|
uiLayout *glob = NULL, *box, *row, *col, *subrow, *sub, *overlap;
|
2009-06-24 14:16:56 +00:00
|
|
|
uiBut *but;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-27 15:27:41 +00:00
|
|
|
uiListLayoutdata layoutdata;
|
2012-12-28 10:32:49 +00:00
|
|
|
char ui_list_id[UI_MAX_NAME_STR];
|
2012-01-11 09:33:44 +00:00
|
|
|
char numstr[32];
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
int rnaicon = ICON_NONE, icon = ICON_NONE;
|
|
|
|
|
int i = 0, activei = 0;
|
|
|
|
|
int len = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-24 14:16:56 +00:00
|
|
|
/* validate arguments */
|
2013-02-18 14:03:26 +00:00
|
|
|
/* Forbid default UI_UL_DEFAULT_CLASS_NAME list class without a custom list_id! */
|
2015-01-26 16:03:11 +01:00
|
|
|
if (STREQ(UI_UL_DEFAULT_CLASS_NAME, listtype_name) && !(list_id && list_id[0])) {
|
2013-02-19 15:45:56 +00:00
|
|
|
RNA_warning("template_list using default '%s' UIList class must provide a custom list_id",
|
|
|
|
|
UI_UL_DEFAULT_CLASS_NAME);
|
2013-02-18 14:03:26 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
if (!active_dataptr->data) {
|
|
|
|
|
RNA_warning("No active data");
|
2009-10-21 20:58:10 +00:00
|
|
|
return;
|
2009-07-01 22:25:49 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
if (dataptr->data) {
|
|
|
|
|
prop = RNA_struct_find_property(dataptr, propname);
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!prop) {
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
RNA_warning("Property not found: %s.%s", RNA_struct_identifier(dataptr->type), propname);
|
2009-10-21 20:58:10 +00:00
|
|
|
return;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2009-07-01 22:25:49 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
activeprop = RNA_struct_find_property(active_dataptr, active_propname);
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!activeprop) {
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
RNA_warning(
|
|
|
|
|
"Property not found: %s.%s", RNA_struct_identifier(active_dataptr->type), active_propname);
|
2009-10-21 20:58:10 +00:00
|
|
|
return;
|
2009-06-24 14:16:56 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (prop) {
|
2021-01-04 17:02:13 +11:00
|
|
|
const PropertyType type = RNA_property_type(prop);
|
2012-03-24 06:38:07 +00:00
|
|
|
if (type != PROP_COLLECTION) {
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
RNA_warning("Expected a collection data property");
|
2009-10-21 20:58:10 +00:00
|
|
|
return;
|
2009-07-01 22:25:49 +00:00
|
|
|
}
|
2009-06-24 14:16:56 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-04 17:02:13 +11:00
|
|
|
const PropertyType activetype = RNA_property_type(activeprop);
|
2012-03-24 06:38:07 +00:00
|
|
|
if (activetype != PROP_INT) {
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
RNA_warning("Expected an integer active data property");
|
2009-10-21 20:58:10 +00:00
|
|
|
return;
|
2009-06-24 14:16:56 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-07-15 19:20:59 +00:00
|
|
|
/* get icon */
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
if (dataptr->data && prop) {
|
2020-10-04 22:44:19 -05:00
|
|
|
StructRNA *ptype = RNA_property_pointer_type(dataptr, prop);
|
2012-03-30 01:51:25 +00:00
|
|
|
rnaicon = RNA_struct_ui_icon(ptype);
|
2009-07-15 19:20:59 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-24 14:16:56 +00:00
|
|
|
/* get active data */
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
activei = RNA_property_int_get(active_dataptr, activeprop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
/* Find the uiList type. */
|
2020-10-04 22:44:19 -05:00
|
|
|
uiListType *ui_list_type = WM_uilisttype_find(listtype_name, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-28 10:32:49 +00:00
|
|
|
if (ui_list_type == NULL) {
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
RNA_warning("List type %s not found", listtype_name);
|
|
|
|
|
return;
|
2013-03-26 09:59:43 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiListDrawItemFunc draw_item = ui_list_type->draw_item ? ui_list_type->draw_item :
|
|
|
|
|
uilist_draw_item_default;
|
|
|
|
|
uiListDrawFilterFunc draw_filter = ui_list_type->draw_filter ? ui_list_type->draw_filter :
|
|
|
|
|
uilist_draw_filter_default;
|
|
|
|
|
uiListFilterItemsFunc filter_items = ui_list_type->filter_items ? ui_list_type->filter_items :
|
|
|
|
|
uilist_filter_items_default;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
/* Find or add the uiList to the current Region. */
|
|
|
|
|
/* We tag the list id with the list type... */
|
2012-12-28 10:32:49 +00:00
|
|
|
BLI_snprintf(
|
|
|
|
|
ui_list_id, sizeof(ui_list_id), "%s_%s", ui_list_type->idname, list_id ? list_id : "");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-06 21:56:54 +02:00
|
|
|
/* Allows to work in popups. */
|
2020-10-04 22:44:19 -05:00
|
|
|
ARegion *region = CTX_wm_menu(C);
|
2020-03-06 16:56:42 +01:00
|
|
|
if (region == NULL) {
|
|
|
|
|
region = CTX_wm_region(C);
|
2016-05-06 21:56:54 +02:00
|
|
|
}
|
2020-10-04 22:44:19 -05:00
|
|
|
uiList *ui_list = BLI_findstring(®ion->ui_lists, ui_list_id, offsetof(uiList, list_id));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-28 10:32:49 +00:00
|
|
|
if (!ui_list) {
|
2013-12-19 03:08:48 +11:00
|
|
|
ui_list = MEM_callocN(sizeof(uiList), "uiList");
|
2012-12-28 10:32:49 +00:00
|
|
|
BLI_strncpy(ui_list->list_id, ui_list_id, sizeof(ui_list->list_id));
|
2020-03-06 16:56:42 +01:00
|
|
|
BLI_addtail(®ion->ui_lists, ui_list);
|
2014-05-23 08:55:31 +02:00
|
|
|
ui_list->list_grip = -UI_LIST_AUTO_SIZE_THRESHOLD; /* Force auto size by default. */
|
2019-01-09 15:48:09 +01:00
|
|
|
if (sort_reverse) {
|
|
|
|
|
ui_list->filter_sort_flag |= UILST_FLT_SORT_REVERSE;
|
|
|
|
|
}
|
|
|
|
|
if (sort_lock) {
|
|
|
|
|
ui_list->filter_sort_flag |= UILST_FLT_SORT_LOCK;
|
2013-03-26 09:59:43 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2013-08-27 15:27:41 +00:00
|
|
|
if (!ui_list->dyn_data) {
|
2013-12-19 03:08:48 +11:00
|
|
|
ui_list->dyn_data = MEM_callocN(sizeof(uiListDyn), "uiList.dyn_data");
|
2013-08-27 15:27:41 +00:00
|
|
|
}
|
2020-10-04 22:44:19 -05:00
|
|
|
uiListDyn *dyn_data = ui_list->dyn_data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
/* Because we can't actually pass type across save&load... */
|
2012-12-28 10:32:49 +00:00
|
|
|
ui_list->type = ui_list_type;
|
|
|
|
|
ui_list->layout_type = layout_type;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
/* Reset filtering data. */
|
2014-01-24 22:12:38 +01:00
|
|
|
MEM_SAFE_FREE(dyn_data->items_filter_flags);
|
|
|
|
|
MEM_SAFE_FREE(dyn_data->items_filter_neworder);
|
2013-08-29 12:55:31 +00:00
|
|
|
dyn_data->items_len = dyn_data->items_shown = -1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-12 15:56:47 +01:00
|
|
|
/* When active item changed since last draw, scroll to it. */
|
|
|
|
|
if (activei != ui_list->list_last_activei) {
|
|
|
|
|
ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
|
|
|
|
|
ui_list->list_last_activei = activei;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
/* Filter list items! (not for compact layout, though) */
|
|
|
|
|
if (dataptr->data && prop) {
|
2014-08-20 20:41:30 +02:00
|
|
|
const int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
|
|
|
|
|
const bool order_reverse = (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) != 0;
|
2013-08-29 12:55:31 +00:00
|
|
|
int items_shown, idx = 0;
|
|
|
|
|
#if 0
|
|
|
|
|
int prev_ii = -1, prev_i;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (layout_type == UILST_LAYOUT_COMPACT) {
|
|
|
|
|
dyn_data->items_len = dyn_data->items_shown = RNA_property_collection_length(dataptr, prop);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2019-05-01 11:09:22 +10:00
|
|
|
// printf("%s: filtering...\n", __func__);
|
2013-08-29 12:55:31 +00:00
|
|
|
filter_items(ui_list, C, dataptr, propname);
|
2019-05-01 11:09:22 +10:00
|
|
|
// printf("%s: filtering done.\n", __func__);
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
items_shown = dyn_data->items_shown;
|
|
|
|
|
if (items_shown >= 0) {
|
2013-11-09 17:05:07 +00:00
|
|
|
bool activei_mapping_pending = true;
|
2013-12-19 03:08:48 +11:00
|
|
|
items_ptr = MEM_mallocN(sizeof(_uilist_item) * items_shown, __func__);
|
2019-05-01 11:09:22 +10:00
|
|
|
// printf("%s: items shown: %d.\n", __func__, items_shown);
|
2013-08-29 12:55:31 +00:00
|
|
|
RNA_PROP_BEGIN (dataptr, itemptr, prop) {
|
|
|
|
|
if (!dyn_data->items_filter_flags ||
|
2014-01-12 22:05:24 +11:00
|
|
|
((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude)) {
|
2013-08-29 12:55:31 +00:00
|
|
|
int ii;
|
|
|
|
|
if (dyn_data->items_filter_neworder) {
|
|
|
|
|
ii = dyn_data->items_filter_neworder[idx++];
|
|
|
|
|
ii = order_reverse ? items_shown - ii - 1 : ii;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ii = order_reverse ? items_shown - ++idx : idx++;
|
|
|
|
|
}
|
2019-05-01 11:09:22 +10:00
|
|
|
// printf("%s: ii: %d\n", __func__, ii);
|
2013-08-29 12:55:31 +00:00
|
|
|
items_ptr[ii].item = itemptr;
|
|
|
|
|
items_ptr[ii].org_idx = i;
|
|
|
|
|
items_ptr[ii].flt_flag = dyn_data->items_filter_flags ? dyn_data->items_filter_flags[i] :
|
|
|
|
|
0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-11-09 17:05:07 +00:00
|
|
|
if (activei_mapping_pending && activei == i) {
|
2013-08-29 12:55:31 +00:00
|
|
|
activei = ii;
|
2013-11-09 17:05:07 +00:00
|
|
|
/* So that we do not map again activei! */
|
|
|
|
|
activei_mapping_pending = false;
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
2016-04-01 16:54:01 +02:00
|
|
|
#if 0 /* For now, do not alter active element, even if it will be hidden... */
|
2013-08-29 12:55:31 +00:00
|
|
|
else if (activei < i) {
|
|
|
|
|
/* We do not want an active but invisible item!
|
|
|
|
|
* Only exception is when all items are filtered out...
|
|
|
|
|
*/
|
|
|
|
|
if (prev_ii >= 0) {
|
|
|
|
|
activei = prev_ii;
|
|
|
|
|
RNA_property_int_set(active_dataptr, activeprop, prev_i);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
activei = ii;
|
|
|
|
|
RNA_property_int_set(active_dataptr, activeprop, i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
prev_i = i;
|
|
|
|
|
prev_ii = ii;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
RNA_PROP_END;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-04-01 16:54:01 +02:00
|
|
|
if (activei_mapping_pending) {
|
|
|
|
|
/* No active item found, set to 'invalid' -1 value... */
|
|
|
|
|
activei = -1;
|
|
|
|
|
}
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
|
|
|
|
if (dyn_data->items_shown >= 0) {
|
|
|
|
|
len = dyn_data->items_shown;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
len = dyn_data->items_len;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
switch (layout_type) {
|
2013-06-26 13:22:25 +00:00
|
|
|
case UILST_LAYOUT_DEFAULT:
|
|
|
|
|
/* layout */
|
2020-08-07 14:34:11 +02:00
|
|
|
box = uiLayoutListBox(layout, ui_list, active_dataptr, activeprop);
|
2014-01-04 17:16:19 +11:00
|
|
|
glob = uiLayoutColumn(box, true);
|
|
|
|
|
row = uiLayoutRow(glob, false);
|
|
|
|
|
col = uiLayoutColumn(row, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-06-26 13:22:25 +00:00
|
|
|
/* init numbers */
|
2014-11-09 21:20:40 +01:00
|
|
|
uilist_prepare(ui_list, len, activei, rows, maxrows, 1, &layoutdata);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-06-26 13:22:25 +00:00
|
|
|
if (dataptr->data && prop) {
|
|
|
|
|
/* create list items */
|
|
|
|
|
for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) {
|
|
|
|
|
PointerRNA *itemptr = &items_ptr[i].item;
|
|
|
|
|
void *dyntip_data;
|
2020-08-26 10:11:13 +10:00
|
|
|
const int org_i = items_ptr[i].org_idx;
|
|
|
|
|
const int flt_flag = items_ptr[i].flt_flag;
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *subblock = uiLayoutGetBlock(col);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
overlap = uiLayoutOverlap(col);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
/* list item behind label & other buttons */
|
|
|
|
|
sub = uiLayoutRow(overlap, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
but = uiDefButR_prop(subblock,
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_BTYPE_LISTROW,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
UI_UNIT_Y,
|
2013-08-29 12:55:31 +00:00
|
|
|
active_dataptr,
|
|
|
|
|
activeprop,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
2013-08-29 12:55:31 +00:00
|
|
|
org_i,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
2013-08-29 12:55:31 +00:00
|
|
|
TIP_("Double click to rename"));
|
|
|
|
|
if ((dyntip_data = uilist_item_use_dynamic_tooltip(itemptr, item_dyntip_propname))) {
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_func_tooltip_set(but, uilist_item_tooltip_func, dyntip_data);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
sub = uiLayoutRow(overlap, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-18 10:24:14 +10:00
|
|
|
icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false);
|
2015-02-11 00:06:03 +01:00
|
|
|
if (icon == ICON_DOT) {
|
|
|
|
|
icon = ICON_NONE;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2015-02-11 00:06:03 +01:00
|
|
|
draw_item(ui_list,
|
|
|
|
|
C,
|
2014-01-04 17:16:19 +11:00
|
|
|
sub,
|
2013-08-29 12:55:31 +00:00
|
|
|
dataptr,
|
|
|
|
|
itemptr,
|
|
|
|
|
icon,
|
|
|
|
|
active_dataptr,
|
|
|
|
|
active_propname,
|
|
|
|
|
org_i,
|
|
|
|
|
flt_flag);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-15 12:27:16 +11:00
|
|
|
/* Items should be able to set context pointers for the layout. But the list-row button
|
2020-12-11 22:20:31 +01:00
|
|
|
* swallows events, so it needs the context storage too for handlers to see it. */
|
|
|
|
|
but->context = uiLayoutGetContextStore(sub);
|
|
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
/* If we are "drawing" active item, set all labels as active. */
|
2013-06-26 13:22:25 +00:00
|
|
|
if (i == activei) {
|
|
|
|
|
ui_layout_list_set_labels_active(sub);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
/* add dummy buttons to fill space */
|
|
|
|
|
for (; i < layoutdata.start_idx + layoutdata.visual_items; i++) {
|
|
|
|
|
uiItemL(col, "", ICON_NONE);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
/* add scrollbar */
|
|
|
|
|
if (len > layoutdata.visual_items) {
|
|
|
|
|
col = uiLayoutColumn(row, false);
|
|
|
|
|
uiDefButI(block,
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_BTYPE_SCROLL,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2019-11-25 11:42:49 +01:00
|
|
|
V2D_SCROLL_WIDTH,
|
2013-08-29 12:55:31 +00:00
|
|
|
UI_UNIT_Y * dyn_data->visual_height,
|
|
|
|
|
&ui_list->list_scroll,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2013-08-27 15:27:41 +00:00
|
|
|
dyn_data->height - dyn_data->visual_height,
|
|
|
|
|
dyn_data->visual_height,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
"");
|
|
|
|
|
}
|
|
|
|
|
break;
|
2013-08-29 12:55:31 +00:00
|
|
|
case UILST_LAYOUT_COMPACT:
|
2014-11-09 21:20:40 +01:00
|
|
|
row = uiLayoutRow(layout, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
if ((dataptr->data && prop) && (dyn_data->items_shown > 0) && (activei >= 0) &&
|
2013-12-06 10:52:04 +11:00
|
|
|
(activei < dyn_data->items_shown)) {
|
2013-08-29 12:55:31 +00:00
|
|
|
PointerRNA *itemptr = &items_ptr[activei].item;
|
2020-08-26 10:11:13 +10:00
|
|
|
const int org_i = items_ptr[activei].org_idx;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-18 10:24:14 +10:00
|
|
|
icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false);
|
2019-03-25 10:15:20 +11:00
|
|
|
if (icon == ICON_DOT) {
|
2016-01-18 01:39:09 +01:00
|
|
|
icon = ICON_NONE;
|
2009-07-01 22:25:49 +00:00
|
|
|
}
|
2013-08-29 12:55:31 +00:00
|
|
|
draw_item(
|
2013-06-26 13:22:25 +00:00
|
|
|
ui_list, C, row, dataptr, itemptr, icon, active_dataptr, active_propname, org_i, 0);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2013-06-26 13:22:25 +00:00
|
|
|
/* if list is empty, add in dummy button */
|
2013-08-27 15:27:41 +00:00
|
|
|
else {
|
|
|
|
|
uiItemL(row, "", ICON_NONE);
|
2013-06-26 13:22:25 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-06-26 13:22:25 +00:00
|
|
|
/* next/prev button */
|
2014-11-09 21:20:40 +01:00
|
|
|
BLI_snprintf(numstr, sizeof(numstr), "%d :", dyn_data->items_shown);
|
|
|
|
|
but = uiDefIconTextButR_prop(block,
|
|
|
|
|
UI_BTYPE_NUM,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2019-04-17 06:17:24 +02:00
|
|
|
numstr,
|
2014-11-09 21:20:40 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 5,
|
2013-08-27 15:27:41 +00:00
|
|
|
UI_UNIT_Y,
|
2013-12-06 10:52:04 +11:00
|
|
|
active_dataptr,
|
|
|
|
|
activeprop,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
2013-12-06 10:52:04 +11:00
|
|
|
if (dyn_data->items_shown == 0) {
|
2013-08-29 12:55:31 +00:00
|
|
|
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
break;
|
2013-08-29 12:55:31 +00:00
|
|
|
case UILST_LAYOUT_GRID:
|
2020-08-07 14:34:11 +02:00
|
|
|
box = uiLayoutListBox(layout, ui_list, active_dataptr, activeprop);
|
2013-08-29 12:55:31 +00:00
|
|
|
glob = uiLayoutColumn(box, true);
|
|
|
|
|
row = uiLayoutRow(glob, false);
|
2013-06-26 13:22:25 +00:00
|
|
|
col = uiLayoutColumn(row, true);
|
|
|
|
|
subrow = NULL; /* Quite gcc warning! */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-01 19:57:31 +02:00
|
|
|
uilist_prepare(ui_list, len, activei, rows, maxrows, columns, &layoutdata);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (dataptr->data && prop) {
|
2013-06-26 13:22:25 +00:00
|
|
|
/* create list items */
|
2013-08-29 12:55:31 +00:00
|
|
|
for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) {
|
2019-03-25 10:15:20 +11:00
|
|
|
PointerRNA *itemptr = &items_ptr[i].item;
|
2020-08-26 10:11:13 +10:00
|
|
|
const int org_i = items_ptr[i].org_idx;
|
|
|
|
|
const int flt_flag = items_ptr[i].flt_flag;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
/* create button */
|
2013-08-27 15:27:41 +00:00
|
|
|
if (!(i % columns)) {
|
2014-11-09 21:20:40 +01:00
|
|
|
subrow = uiLayoutRow(col, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *subblock = uiLayoutGetBlock(subrow);
|
2014-01-04 17:16:19 +11:00
|
|
|
overlap = uiLayoutOverlap(subrow);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-06-26 13:22:25 +00:00
|
|
|
/* list item behind label & other buttons */
|
2014-01-04 17:16:19 +11:00
|
|
|
sub = uiLayoutRow(overlap, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
but = uiDefButR_prop(subblock,
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_BTYPE_LISTROW,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2014-11-09 21:20:40 +01:00
|
|
|
"",
|
|
|
|
|
0,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_UNIT_X * 10,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
active_dataptr,
|
|
|
|
|
activeprop,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
2014-11-09 21:20:40 +01:00
|
|
|
org_i,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
NULL);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_drawflag_enable(but, UI_BUT_NO_TOOLTIP);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
sub = uiLayoutRow(overlap, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-18 10:24:14 +10:00
|
|
|
icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false);
|
2013-08-29 12:55:31 +00:00
|
|
|
draw_item(ui_list,
|
2019-04-17 06:17:24 +02:00
|
|
|
C,
|
2013-08-27 15:27:41 +00:00
|
|
|
sub,
|
|
|
|
|
dataptr,
|
2019-04-17 06:17:24 +02:00
|
|
|
itemptr,
|
|
|
|
|
icon,
|
2013-08-27 15:27:41 +00:00
|
|
|
active_dataptr,
|
|
|
|
|
active_propname,
|
|
|
|
|
org_i,
|
|
|
|
|
flt_flag);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
/* If we are "drawing" active item, set all labels as active. */
|
2013-08-27 15:27:41 +00:00
|
|
|
if (i == activei) {
|
|
|
|
|
ui_layout_list_set_labels_active(sub);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-26 13:22:25 +00:00
|
|
|
/* add dummy buttons to fill space */
|
2014-01-04 17:16:19 +11:00
|
|
|
for (; i < layoutdata.start_idx + layoutdata.visual_items; i++) {
|
2014-11-09 21:20:40 +01:00
|
|
|
if (!(i % columns)) {
|
2014-01-04 17:16:19 +11:00
|
|
|
subrow = uiLayoutRow(col, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2013-08-29 12:55:31 +00:00
|
|
|
uiItemL(subrow, "", ICON_NONE);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2013-08-27 15:27:41 +00:00
|
|
|
/* add scrollbar */
|
2013-08-29 12:55:31 +00:00
|
|
|
if (len > layoutdata.visual_items) {
|
|
|
|
|
/* col = */ uiLayoutColumn(row, false);
|
|
|
|
|
uiDefButI(block,
|
|
|
|
|
UI_BTYPE_SCROLL,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2019-11-25 11:42:49 +01:00
|
|
|
V2D_SCROLL_WIDTH,
|
2013-08-29 12:55:31 +00:00
|
|
|
UI_UNIT_Y * dyn_data->visual_height,
|
|
|
|
|
&ui_list->list_scroll,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2013-08-29 12:55:31 +00:00
|
|
|
dyn_data->height - dyn_data->visual_height,
|
|
|
|
|
dyn_data->visual_height,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2013-08-29 12:55:31 +00:00
|
|
|
"");
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-26 13:22:25 +00:00
|
|
|
if (glob) {
|
2021-03-10 15:47:50 +11:00
|
|
|
/* About #UI_BTYPE_GRIP drag-resize:
|
2019-04-17 08:44:38 +02:00
|
|
|
* We can't directly use results from a grip button, since we have a
|
2021-03-10 15:47:50 +11:00
|
|
|
* rather complex behavior here (sizing by discrete steps and, overall, auto-size feature).
|
2019-04-17 08:44:38 +02:00
|
|
|
* Since we *never* know whether we are grip-resizing or not
|
|
|
|
|
* (because there is no callback for when a button enters/leaves its "edit mode"),
|
|
|
|
|
* we use the fact that grip-controlled value (dyn_data->resize) is completely handled
|
|
|
|
|
* by the grip during the grab resize, so settings its value here has no effect at all.
|
|
|
|
|
*
|
|
|
|
|
* It is only meaningful when we are not resizing,
|
|
|
|
|
* in which case this gives us the correct "init drag" value.
|
2021-03-10 15:47:50 +11:00
|
|
|
* Note we cannot affect `dyn_data->resize_prev here`,
|
2019-04-17 08:44:38 +02:00
|
|
|
* since this value is not controlled by the grip!
|
2019-04-17 06:17:24 +02:00
|
|
|
*/
|
2013-08-27 15:27:41 +00:00
|
|
|
dyn_data->resize = dyn_data->resize_prev +
|
|
|
|
|
(dyn_data->visual_height - ui_list->list_grip) * UI_UNIT_Y;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-27 15:27:41 +00:00
|
|
|
row = uiLayoutRow(glob, true);
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *subblock = uiLayoutGetBlock(row);
|
2013-08-27 15:27:41 +00:00
|
|
|
UI_block_emboss_set(subblock, UI_EMBOSS_NONE);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-27 15:27:41 +00:00
|
|
|
if (ui_list->filter_flag & UILST_FLT_SHOW) {
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefIconButBitI(subblock,
|
2013-08-27 15:27:41 +00:00
|
|
|
UI_BTYPE_TOGGLE,
|
2014-11-09 21:20:40 +01:00
|
|
|
UILST_FLT_SHOW,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
2013-08-27 15:27:41 +00:00
|
|
|
ICON_DISCLOSURE_TRI_DOWN,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_UNIT_X,
|
2014-04-02 13:22:12 +02:00
|
|
|
UI_UNIT_Y * 0.5f,
|
|
|
|
|
&(ui_list->filter_flag),
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2013-08-29 12:55:31 +00:00
|
|
|
TIP_("Hide filtering options"));
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefIconButI(subblock,
|
|
|
|
|
UI_BTYPE_GRIP,
|
2014-04-02 13:09:43 +02:00
|
|
|
0,
|
|
|
|
|
ICON_GRIP,
|
2019-04-17 06:17:24 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
2014-04-02 13:09:43 +02:00
|
|
|
UI_UNIT_X * 10.0f,
|
|
|
|
|
UI_UNIT_Y * 0.5f,
|
|
|
|
|
&dyn_data->resize,
|
2019-04-17 06:17:24 +02:00
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
2014-04-02 13:09:43 +02:00
|
|
|
UI_but_func_set(but, uilist_resize_update_cb, ui_list, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(subblock, UI_EMBOSS);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
col = uiLayoutColumn(glob, false);
|
|
|
|
|
subblock = uiLayoutGetBlock(col);
|
|
|
|
|
uiDefBut(subblock,
|
|
|
|
|
UI_BTYPE_SEPR,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y * 0.05f,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-09 15:48:09 +01:00
|
|
|
draw_filter(ui_list, C, col);
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefIconButBitI(subblock,
|
|
|
|
|
UI_BTYPE_TOGGLE,
|
|
|
|
|
UILST_FLT_SHOW,
|
|
|
|
|
0,
|
|
|
|
|
ICON_DISCLOSURE_TRI_RIGHT,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2014-04-02 13:22:12 +02:00
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y * 0.5f,
|
|
|
|
|
&(ui_list->filter_flag),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2013-08-29 12:55:31 +00:00
|
|
|
TIP_("Show filtering options"));
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefIconButI(subblock,
|
|
|
|
|
UI_BTYPE_GRIP,
|
|
|
|
|
0,
|
|
|
|
|
ICON_GRIP,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 10.0f,
|
|
|
|
|
UI_UNIT_Y * 0.5f,
|
2014-04-02 13:09:43 +02:00
|
|
|
&dyn_data->resize,
|
|
|
|
|
0.0,
|
|
|
|
|
0.0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_func_set(but, uilist_resize_update_cb, ui_list, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(subblock, UI_EMBOSS);
|
2013-08-29 12:55:31 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2013-08-29 12:55:31 +00:00
|
|
|
if (items_ptr) {
|
|
|
|
|
MEM_freeN(items_ptr);
|
2013-08-27 15:27:41 +00:00
|
|
|
}
|
2009-06-24 14:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Running Jobs Template
|
|
|
|
|
* \{ */
|
2009-06-30 19:20:45 +00:00
|
|
|
|
2012-03-30 01:51:25 +00:00
|
|
|
#define B_STOPRENDER 1
|
|
|
|
|
#define B_STOPCAST 2
|
|
|
|
|
#define B_STOPANIM 3
|
|
|
|
|
#define B_STOPCOMPO 4
|
|
|
|
|
#define B_STOPSEQ 5
|
|
|
|
|
#define B_STOPCLIP 6
|
Final 'FileBrowser First Stage' merge.
It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser.
From user perspective, it:
* Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender!
* Makes short/long display 'fixed' size (among four choices, like thumbnails mode).
* Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories).
* Consequently, adds datablocks types filtering.
* Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared).
* Generates thumbnails way faster.
From code perspective, it:
* Is ready for asset engine needs (on data structure level in filebrowser's listing).
* Simplifies and makes 'generic' file listing much lighter.
* Separates file listing in three different aspects:
** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct.
** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.).
** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one.
* Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items.
* Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs).
* Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too).
Revision: https://developer.blender.org/D1316
Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
|
|
|
#define B_STOPFILE 7
|
|
|
|
|
#define B_STOPOTHER 8
|
2009-06-30 19:20:45 +00:00
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static void do_running_jobs(bContext *C, void *UNUSED(arg), int event)
|
2009-06-30 19:20:45 +00:00
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
switch (event) {
|
2009-06-30 19:20:45 +00:00
|
|
|
case B_STOPRENDER:
|
2014-01-04 17:16:19 +11:00
|
|
|
G.is_break = true;
|
2009-06-30 19:20:45 +00:00
|
|
|
break;
|
|
|
|
|
case B_STOPCAST:
|
2010-07-04 19:58:52 +00:00
|
|
|
WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C), NULL);
|
2009-06-30 19:20:45 +00:00
|
|
|
break;
|
|
|
|
|
case B_STOPANIM:
|
2009-08-16 20:37:22 +00:00
|
|
|
WM_operator_name_call(C, "SCREEN_OT_animation_play", WM_OP_INVOKE_SCREEN, NULL);
|
2009-06-30 19:20:45 +00:00
|
|
|
break;
|
2010-04-13 17:15:11 +00:00
|
|
|
case B_STOPCOMPO:
|
2012-08-15 10:31:52 +00:00
|
|
|
WM_jobs_stop(CTX_wm_manager(C), CTX_data_scene(C), NULL);
|
2010-04-13 17:15:11 +00:00
|
|
|
break;
|
== Sequencer ==
This patch adds:
* support for proxy building again (missing feature from Blender 2.49)
additionally to the way, Blender 2.49 worked, you can select several
strips at once and make Blender build proxies in the background (using
the job system)
Also a new thing: movie proxies are now build into AVI files, and
the proxy system is moved into ImBuf-library, so that other parts
of blender can also benefit from it.
* Timecode support: to fix seeking issues with files, that have
a) varying frame rates
b) very large GOP lengths
c) are broken inbetween
d) use different time code tracks
the proxy builder can now also build timecode indices, which are
used (optionally) for seeking.
For the first time, it is possible, to do frame exact seeking on
all file types.
* Support for different video-streams in one video file (can be
selected in sequencer, other parts of blender can also use it,
but UI has to be added accordingly)
* IMPORTANT: this patch *requires* ffmpeg 0.7 or newer, since
older versions don't support the pkt_pts field, that is essential
for building timecode indices.
Windows and Mac libs are already updated, Linux-users have to build
their own ffmpeg verions until distros keep up.
2011-08-28 14:46:03 +00:00
|
|
|
case B_STOPSEQ:
|
2019-08-01 12:40:57 -07:00
|
|
|
WM_jobs_stop(CTX_wm_manager(C), CTX_data_scene(C), NULL);
|
== Sequencer ==
This patch adds:
* support for proxy building again (missing feature from Blender 2.49)
additionally to the way, Blender 2.49 worked, you can select several
strips at once and make Blender build proxies in the background (using
the job system)
Also a new thing: movie proxies are now build into AVI files, and
the proxy system is moved into ImBuf-library, so that other parts
of blender can also benefit from it.
* Timecode support: to fix seeking issues with files, that have
a) varying frame rates
b) very large GOP lengths
c) are broken inbetween
d) use different time code tracks
the proxy builder can now also build timecode indices, which are
used (optionally) for seeking.
For the first time, it is possible, to do frame exact seeking on
all file types.
* Support for different video-streams in one video file (can be
selected in sequencer, other parts of blender can also use it,
but UI has to be added accordingly)
* IMPORTANT: this patch *requires* ffmpeg 0.7 or newer, since
older versions don't support the pkt_pts field, that is essential
for building timecode indices.
Windows and Mac libs are already updated, Linux-users have to build
their own ffmpeg verions until distros keep up.
2011-08-28 14:46:03 +00:00
|
|
|
break;
|
2011-11-07 12:55:18 +00:00
|
|
|
case B_STOPCLIP:
|
2019-08-01 12:40:57 -07:00
|
|
|
WM_jobs_stop(CTX_wm_manager(C), CTX_data_scene(C), NULL);
|
2011-11-07 12:55:18 +00:00
|
|
|
break;
|
Final 'FileBrowser First Stage' merge.
It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser.
From user perspective, it:
* Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender!
* Makes short/long display 'fixed' size (among four choices, like thumbnails mode).
* Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories).
* Consequently, adds datablocks types filtering.
* Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared).
* Generates thumbnails way faster.
From code perspective, it:
* Is ready for asset engine needs (on data structure level in filebrowser's listing).
* Simplifies and makes 'generic' file listing much lighter.
* Separates file listing in three different aspects:
** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct.
** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.).
** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one.
* Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items.
* Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs).
* Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too).
Revision: https://developer.blender.org/D1316
Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
|
|
|
case B_STOPFILE:
|
2019-08-01 12:40:57 -07:00
|
|
|
WM_jobs_stop(CTX_wm_manager(C), CTX_data_scene(C), NULL);
|
Final 'FileBrowser First Stage' merge.
It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser.
From user perspective, it:
* Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender!
* Makes short/long display 'fixed' size (among four choices, like thumbnails mode).
* Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories).
* Consequently, adds datablocks types filtering.
* Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared).
* Generates thumbnails way faster.
From code perspective, it:
* Is ready for asset engine needs (on data structure level in filebrowser's listing).
* Simplifies and makes 'generic' file listing much lighter.
* Separates file listing in three different aspects:
** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct.
** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.).
** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one.
* Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items.
* Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs).
* Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too).
Revision: https://developer.blender.org/D1316
Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
|
|
|
break;
|
2012-09-03 16:05:37 +00:00
|
|
|
case B_STOPOTHER:
|
2014-01-04 17:16:19 +11:00
|
|
|
G.is_break = true;
|
2012-09-03 16:05:37 +00:00
|
|
|
break;
|
2009-06-30 19:20:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-18 13:53:38 +11:00
|
|
|
struct ProgressTooltip_Store {
|
|
|
|
|
wmWindowManager *wm;
|
|
|
|
|
void *owner;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static char *progress_tooltip_func(bContext *UNUSED(C), void *argN, const char *UNUSED(tip))
|
|
|
|
|
{
|
|
|
|
|
struct ProgressTooltip_Store *arg = argN;
|
|
|
|
|
wmWindowManager *wm = arg->wm;
|
|
|
|
|
void *owner = arg->owner;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-18 13:53:38 +11:00
|
|
|
const float progress = WM_jobs_progress(wm, owner);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-18 13:53:38 +11:00
|
|
|
/* create tooltip text and associate it with the job */
|
|
|
|
|
char elapsed_str[32];
|
|
|
|
|
char remaining_str[32] = "Unknown";
|
|
|
|
|
const double elapsed = PIL_check_seconds_timer() - WM_jobs_starttime(wm, owner);
|
|
|
|
|
BLI_timecode_string_from_time_simple(elapsed_str, sizeof(elapsed_str), elapsed);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-18 13:53:38 +11:00
|
|
|
if (progress) {
|
2016-02-10 13:59:57 +11:00
|
|
|
const double remaining = (elapsed / (double)progress) - elapsed;
|
2016-01-18 13:53:38 +11:00
|
|
|
BLI_timecode_string_from_time_simple(remaining_str, sizeof(remaining_str), remaining);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-18 13:53:38 +11:00
|
|
|
return BLI_sprintfN(
|
|
|
|
|
"Time Remaining: %s\n"
|
|
|
|
|
"Time Elapsed: %s",
|
|
|
|
|
remaining_str,
|
|
|
|
|
elapsed_str);
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-30 19:20:45 +00:00
|
|
|
void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
|
|
|
|
|
{
|
2020-02-19 15:06:14 +11:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2012-03-30 01:51:25 +00:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
2020-04-03 13:25:03 +02:00
|
|
|
ScrArea *area = CTX_wm_area(C);
|
2012-03-30 01:51:25 +00:00
|
|
|
void *owner = NULL;
|
2016-01-18 01:39:09 +01:00
|
|
|
int handle_event, icon = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_layout_set_current(block, layout);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_func_handle_set(block, do_running_jobs, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-01 12:40:57 -07:00
|
|
|
/* another scene can be rendering too, for example via compositor */
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
2019-08-01 12:40:57 -07:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY)) {
|
|
|
|
|
handle_event = B_STOPOTHER;
|
|
|
|
|
icon = ICON_NONE;
|
|
|
|
|
owner = scene;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-08-01 12:40:57 -07:00
|
|
|
else {
|
|
|
|
|
continue;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-08-01 12:40:57 -07:00
|
|
|
|
|
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_SEQ_BUILD_PROXY)) {
|
|
|
|
|
handle_event = B_STOPSEQ;
|
|
|
|
|
icon = ICON_SEQUENCE;
|
|
|
|
|
owner = scene;
|
|
|
|
|
break;
|
Final 'FileBrowser First Stage' merge.
It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser.
From user perspective, it:
* Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender!
* Makes short/long display 'fixed' size (among four choices, like thumbnails mode).
* Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories).
* Consequently, adds datablocks types filtering.
* Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared).
* Generates thumbnails way faster.
From code perspective, it:
* Is ready for asset engine needs (on data structure level in filebrowser's listing).
* Simplifies and makes 'generic' file listing much lighter.
* Separates file listing in three different aspects:
** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct.
** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.).
** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one.
* Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items.
* Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs).
* Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too).
Revision: https://developer.blender.org/D1316
Thanks to Campbell & Sergey for the reviews. :)
2015-08-19 22:41:39 +02:00
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_SEQ_BUILD_PREVIEW)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
handle_event = B_STOPSEQ;
|
|
|
|
|
icon = ICON_SEQUENCE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_CLIP_BUILD_PROXY)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
handle_event = B_STOPCLIP;
|
|
|
|
|
icon = ICON_TRACKER;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_CLIP_PREFETCH)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
handle_event = B_STOPCLIP;
|
|
|
|
|
icon = ICON_TRACKER;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_CLIP_TRACK_MARKERS)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
handle_event = B_STOPCLIP;
|
|
|
|
|
icon = ICON_TRACKER;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_CLIP_SOLVE_CAMERA)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
handle_event = B_STOPCLIP;
|
|
|
|
|
icon = ICON_TRACKER;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_FILESEL_READDIR)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
handle_event = B_STOPFILE;
|
|
|
|
|
icon = ICON_FILEBROWSER;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
handle_event = B_STOPRENDER;
|
|
|
|
|
icon = ICON_SCENE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_COMPOSITE)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
handle_event = B_STOPCOMPO;
|
|
|
|
|
icon = ICON_RENDERLAYERS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE) ||
|
|
|
|
|
WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_BAKE)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
/* Skip bake jobs in compositor to avoid compo header displaying
|
|
|
|
|
* progress bar which is not being updated (bake jobs only need
|
|
|
|
|
* to update NC_IMAGE context.
|
|
|
|
|
*/
|
2020-04-03 13:25:03 +02:00
|
|
|
if (area->spacetype != SPACE_NODE) {
|
2016-01-18 01:39:09 +01:00
|
|
|
handle_event = B_STOPOTHER;
|
2019-08-01 12:40:57 -07:00
|
|
|
icon = ICON_IMAGE;
|
2016-01-18 01:39:09 +01:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
continue;
|
2016-01-18 01:39:09 +01:00
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_DPAINT_BAKE)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
handle_event = B_STOPOTHER;
|
|
|
|
|
icon = ICON_MOD_DYNAMICPAINT;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_POINTCACHE)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
handle_event = B_STOPOTHER;
|
|
|
|
|
icon = ICON_PHYSICS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_SIM_FLUID)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
handle_event = B_STOPOTHER;
|
|
|
|
|
icon = ICON_MOD_FLUIDSIM;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_SIM_OCEAN)) {
|
2019-08-01 12:40:57 -07:00
|
|
|
handle_event = B_STOPOTHER;
|
|
|
|
|
icon = ICON_MOD_OCEAN;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2016-01-18 01:39:09 +01:00
|
|
|
if (owner) {
|
|
|
|
|
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
|
2020-08-26 10:11:13 +10:00
|
|
|
const bool active = !(G.is_break || WM_jobs_is_stopped(wm, owner));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-18 01:39:09 +01:00
|
|
|
uiLayout *row = uiLayoutRow(layout, false);
|
|
|
|
|
block = uiLayoutGetBlock(row);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-18 01:39:09 +01:00
|
|
|
/* get percentage done and set it as the UI text */
|
|
|
|
|
const float progress = WM_jobs_progress(wm, owner);
|
|
|
|
|
char text[8];
|
|
|
|
|
BLI_snprintf(text, 8, "%d%%", (int)(progress * 100));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-18 01:39:09 +01:00
|
|
|
const char *name = active ? WM_jobs_name(wm, owner) : "Canceling...";
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-18 01:39:09 +01:00
|
|
|
/* job name and icon */
|
|
|
|
|
const int textwidth = UI_fontstyle_string_width(fstyle, name);
|
|
|
|
|
uiDefIconTextBut(block,
|
2012-09-03 16:05:37 +00:00
|
|
|
UI_BTYPE_LABEL,
|
|
|
|
|
0,
|
2016-01-18 01:39:09 +01:00
|
|
|
icon,
|
2019-04-17 06:17:24 +02:00
|
|
|
name,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2016-01-18 01:39:09 +01:00
|
|
|
textwidth + UI_UNIT_X * 1.5f,
|
|
|
|
|
UI_UNIT_Y,
|
2019-04-17 06:17:24 +02:00
|
|
|
NULL,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
2016-01-18 13:53:38 +11:00
|
|
|
0.0f,
|
|
|
|
|
"");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-18 13:53:38 +11:00
|
|
|
/* stick progress bar and cancel button together */
|
2016-01-18 01:39:09 +01:00
|
|
|
row = uiLayoutRow(layout, true);
|
|
|
|
|
uiLayoutSetActive(row, active);
|
|
|
|
|
block = uiLayoutGetBlock(row);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
{
|
2016-01-18 01:39:09 +01:00
|
|
|
struct ProgressTooltip_Store *tip_arg = MEM_mallocN(sizeof(*tip_arg), __func__);
|
|
|
|
|
tip_arg->wm = wm;
|
|
|
|
|
tip_arg->owner = owner;
|
2020-08-07 15:16:26 +02:00
|
|
|
uiButProgressbar *but_progress = (uiButProgressbar *)uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_PROGRESS_BAR,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
text,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 6.0f,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
0,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
but_progress->progress = progress;
|
|
|
|
|
UI_but_func_tooltip_set(&but_progress->but, progress_tooltip_func, tip_arg);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2016-01-18 13:53:38 +11:00
|
|
|
if (!wm->is_interface_locked) {
|
|
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
handle_event,
|
|
|
|
|
ICON_PANEL_CLOSE,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2018-09-17 10:22:00 +02:00
|
|
|
TIP_("Stop this job"));
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-09-17 10:22:00 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-01-17 13:44:13 +01:00
|
|
|
if (ED_screen_animation_no_scrub(wm)) {
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefIconTextBut(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
B_STOPANIM,
|
|
|
|
|
ICON_CANCEL,
|
|
|
|
|
IFACE_("Anim Player"),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 5.0f,
|
|
|
|
|
UI_UNIT_Y,
|
2012-11-23 15:33:44 +00:00
|
|
|
NULL,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
TIP_("Stop animation playback"));
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2009-06-30 19:20:45 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Reports for Last Operator Template
|
|
|
|
|
* \{ */
|
Info Header: Non-blocking Info Messages
Reports (i.e. 'info' or 'errors') are now shown in the info header in place of the scene statistics if the last executed operator had some, with this info disappearing again once another operator is run (to show scene statistics again).
For example, this means that info such as the the number of verts merged, or whether a Keying Set successfully inserted keyframes, etc. is now shown again somewhere, and that this is done in a non-blocking manner.
The current implementation is still a bit crude (i.e. lacking fancy polish), but is at least barebones functional. The todos...
* When more than 1 report message is generated by the last operator, there is currently a display of the number of reports. In future, it would be nice to be able to add a button beside this or make the label clickable with appropriate text indicating this (commented out atm) to show popup menu of all the reports...
* There could probably be some kind of coloured backdrop behind the text. Currently using standard box, but that has padding problems, and lacks visual interest.
* Timer based fade out/disappear?
2010-03-02 11:48:40 +00:00
|
|
|
|
2010-06-03 07:27:55 +00:00
|
|
|
void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
|
Info Header: Non-blocking Info Messages
Reports (i.e. 'info' or 'errors') are now shown in the info header in place of the scene statistics if the last executed operator had some, with this info disappearing again once another operator is run (to show scene statistics again).
For example, this means that info such as the the number of verts merged, or whether a Keying Set successfully inserted keyframes, etc. is now shown again somewhere, and that this is done in a non-blocking manner.
The current implementation is still a bit crude (i.e. lacking fancy polish), but is at least barebones functional. The todos...
* When more than 1 report message is generated by the last operator, there is currently a display of the number of reports. In future, it would be nice to be able to add a button beside this or make the label clickable with appropriate text indicating this (commented out atm) to show popup menu of all the reports...
* There could probably be some kind of coloured backdrop behind the text. Currently using standard box, but that has padding problems, and lacks visual interest.
* Timer based fade out/disappear?
2010-03-02 11:48:40 +00:00
|
|
|
{
|
2010-06-03 07:27:55 +00:00
|
|
|
ReportList *reports = CTX_wm_reports(C);
|
2012-03-30 01:51:25 +00:00
|
|
|
Report *report = BKE_reports_last_displayable(reports);
|
2020-10-04 22:44:19 -05:00
|
|
|
const uiStyle *style = UI_style_get();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-06-03 07:27:55 +00:00
|
|
|
uiBut *but;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-06-03 07:27:55 +00:00
|
|
|
/* if the report display has timed out, don't show */
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!reports->reporttimer) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
ReportTimerInfo *rti = (ReportTimerInfo *)reports->reporttimer->customdata;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (!rti || rti->widthfac == 0.0f || !report) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *ui_abs = uiLayoutAbsolute(layout, false);
|
|
|
|
|
uiBlock *block = uiLayoutGetBlock(ui_abs);
|
2021-05-04 18:17:16 +02:00
|
|
|
eUIEmbossType previous_emboss = UI_block_emboss_get(block);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-09-22 17:18:43 +10:00
|
|
|
UI_fontstyle_set(&style->widgetlabel);
|
2020-10-04 22:44:19 -05:00
|
|
|
int width = BLF_width(style->widgetlabel.uifont_id, report->message, report->len);
|
2012-10-27 11:18:54 +00:00
|
|
|
width = min_ii((int)(rti->widthfac * width), width);
|
2018-10-19 17:14:27 +02:00
|
|
|
width = max_ii(width, 10 * UI_DPI_FAC);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_begin(block);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-08 08:19:23 -08:00
|
|
|
/* Background for icon. */
|
2018-06-25 18:57:47 +02:00
|
|
|
but = uiDefBut(block,
|
|
|
|
|
UI_BTYPE_ROUNDBOX,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
2021-02-08 08:19:23 -08:00
|
|
|
0,
|
|
|
|
|
UI_UNIT_X + (6 * UI_DPI_FAC),
|
2018-06-25 18:57:47 +02:00
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
2021-02-08 08:19:23 -08:00
|
|
|
/* UI_BTYPE_ROUNDBOX's bg color is set in but->col. */
|
|
|
|
|
UI_GetThemeColorType4ubv(UI_icon_colorid_from_report_type(report->type), SPACE_INFO, but->col);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-08 08:19:23 -08:00
|
|
|
/* Background for the rest of the message. */
|
|
|
|
|
but = uiDefBut(block,
|
|
|
|
|
UI_BTYPE_ROUNDBOX,
|
|
|
|
|
0,
|
|
|
|
|
"",
|
|
|
|
|
UI_UNIT_X + (6 * UI_DPI_FAC),
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X + width,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0f,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
"");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-08 08:19:23 -08:00
|
|
|
/* Use icon background at low opacity to highlight, but still contrasting with area TH_TEXT. */
|
|
|
|
|
UI_GetThemeColorType4ubv(UI_icon_colorid_from_report_type(report->type), SPACE_INFO, but->col);
|
|
|
|
|
but->col[3] = 64;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-08 08:19:23 -08:00
|
|
|
UI_block_align_end(block);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-08 08:19:23 -08:00
|
|
|
/* The report icon itself. */
|
|
|
|
|
but = uiDefIconButO(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
"SCREEN_OT_info_log_show",
|
|
|
|
|
WM_OP_INVOKE_REGION_WIN,
|
|
|
|
|
UI_icon_from_report_type(report->type),
|
|
|
|
|
(3 * UI_DPI_FAC),
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
TIP_("Click to see the remaining reports in text block: 'Recent Reports'"));
|
|
|
|
|
UI_GetThemeColorType4ubv(UI_text_colorid_from_report_type(report->type), SPACE_INFO, but->col);
|
|
|
|
|
but->col[3] = 255; /* This theme color is RBG only, so have to set alpha here. */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-08 08:19:23 -08:00
|
|
|
/* The report message. */
|
2019-08-16 16:24:16 +02:00
|
|
|
but = uiDefButO(block,
|
2019-08-17 01:17:11 +10:00
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
"SCREEN_OT_info_log_show",
|
|
|
|
|
WM_OP_INVOKE_REGION_WIN,
|
|
|
|
|
report->message,
|
2021-02-08 08:19:23 -08:00
|
|
|
UI_UNIT_X,
|
2019-08-17 01:17:11 +10:00
|
|
|
0,
|
2021-02-08 08:19:23 -08:00
|
|
|
width + UI_UNIT_X,
|
2019-08-17 01:17:11 +10:00
|
|
|
UI_UNIT_Y,
|
|
|
|
|
"Show in Info Log");
|
2021-05-04 18:17:16 +02:00
|
|
|
|
|
|
|
|
UI_block_emboss_set(block, previous_emboss);
|
Info Header: Non-blocking Info Messages
Reports (i.e. 'info' or 'errors') are now shown in the info header in place of the scene statistics if the last executed operator had some, with this info disappearing again once another operator is run (to show scene statistics again).
For example, this means that info such as the the number of verts merged, or whether a Keying Set successfully inserted keyframes, etc. is now shown again somewhere, and that this is done in a non-blocking manner.
The current implementation is still a bit crude (i.e. lacking fancy polish), but is at least barebones functional. The todos...
* When more than 1 report message is generated by the last operator, there is currently a display of the number of reports. In future, it would be nice to be able to add a button beside this or make the label clickable with appropriate text indicating this (commented out atm) to show popup menu of all the reports...
* There could probably be some kind of coloured backdrop behind the text. Currently using standard box, but that has padding problems, and lacks visual interest.
* Timer based fade out/disappear?
2010-03-02 11:48:40 +00:00
|
|
|
}
|
2009-07-21 12:57:55 +00:00
|
|
|
|
2018-06-26 17:19:25 +02:00
|
|
|
void uiTemplateInputStatus(uiLayout *layout, struct bContext *C)
|
2018-06-26 12:18:54 +02:00
|
|
|
{
|
|
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2018-06-26 17:19:25 +02:00
|
|
|
WorkSpace *workspace = CTX_wm_workspace(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-26 17:19:25 +02:00
|
|
|
/* Workspace status text has priority. */
|
|
|
|
|
if (workspace->status_text) {
|
|
|
|
|
uiItemL(layout, workspace->status_text, ICON_NONE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-05 12:09:17 +02:00
|
|
|
if (WM_window_modal_keymap_status_draw(C, win, layout)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-26 17:19:25 +02:00
|
|
|
/* Otherwise should cursor keymap status. */
|
2018-06-26 12:18:54 +02:00
|
|
|
for (int i = 0; i < 3; i++) {
|
2018-06-27 23:59:05 +02:00
|
|
|
uiLayout *box = uiLayoutRow(layout, false);
|
|
|
|
|
uiLayout *col = uiLayoutColumn(box, false);
|
|
|
|
|
uiLayout *row = uiLayoutRow(col, true);
|
|
|
|
|
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-27 19:48:54 +02:00
|
|
|
const char *msg = WM_window_cursor_keymap_status_get(win, i, 0);
|
|
|
|
|
const char *msg_drag = WM_window_cursor_keymap_status_get(win, i, 1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-03 10:15:26 +02:00
|
|
|
if (msg || (msg_drag == NULL)) {
|
|
|
|
|
uiItemL(row, msg ? msg : "", (ICON_MOUSE_LMB + i));
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-27 23:59:05 +02:00
|
|
|
if (msg_drag) {
|
2018-07-02 13:27:22 +02:00
|
|
|
uiItemL(row, msg_drag, (ICON_MOUSE_LMB_DRAG + i));
|
2018-06-26 12:18:54 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-27 23:59:05 +02:00
|
|
|
/* Use trick with empty string to keep icons in same position. */
|
|
|
|
|
row = uiLayoutRow(col, false);
|
2018-07-02 13:27:22 +02:00
|
|
|
uiItemL(row, " ", ICON_NONE);
|
2018-06-26 12:18:54 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Keymap Template
|
|
|
|
|
* \{ */
|
2011-10-04 13:24:48 +00:00
|
|
|
|
|
|
|
|
static void keymap_item_modified(bContext *UNUSED(C), void *kmi_p, void *UNUSED(unused))
|
|
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
wmKeyMapItem *kmi = (wmKeyMapItem *)kmi_p;
|
2011-10-04 13:24:48 +00:00
|
|
|
WM_keyconfig_update_tag(NULL, kmi);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void template_keymap_item_properties(uiLayout *layout, const char *title, PointerRNA *ptr)
|
|
|
|
|
{
|
|
|
|
|
uiItemS(layout);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 10:15:20 +11:00
|
|
|
if (title) {
|
2011-10-04 13:24:48 +00:00
|
|
|
uiItemL(layout, title, ICON_NONE);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *flow = uiLayoutColumnFlow(layout, 2, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-17 09:08:17 +10:00
|
|
|
RNA_STRUCT_BEGIN_SKIP_RNA_TYPE (ptr, prop) {
|
2014-08-20 20:41:30 +02:00
|
|
|
const bool is_set = RNA_property_is_set(ptr, prop);
|
2013-09-20 09:10:17 +00:00
|
|
|
uiBut *but;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-10-04 13:24:48 +00:00
|
|
|
/* recurse for nested properties */
|
2012-03-24 06:38:07 +00:00
|
|
|
if (RNA_property_type(prop) == PROP_POINTER) {
|
2012-03-30 01:51:25 +00:00
|
|
|
PointerRNA propptr = RNA_property_pointer_get(ptr, prop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (propptr.data && RNA_struct_is_a(propptr.type, &RNA_OperatorProperties)) {
|
2013-07-09 00:13:17 +00:00
|
|
|
const char *name = RNA_property_ui_name(prop);
|
2011-10-04 13:24:48 +00:00
|
|
|
template_keymap_item_properties(layout, name, &propptr);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *box = uiLayoutBox(flow);
|
2013-09-20 09:10:17 +00:00
|
|
|
uiLayoutSetActive(box, is_set);
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *row = uiLayoutRow(box, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-09-20 09:10:17 +00:00
|
|
|
/* property value */
|
|
|
|
|
uiItemFullR(row, ptr, prop, -1, 0, 0, NULL, ICON_NONE);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-09-20 09:10:17 +00:00
|
|
|
if (is_set) {
|
|
|
|
|
/* unset operator */
|
|
|
|
|
uiBlock *block = uiLayoutGetBlock(row);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
|
|
|
|
but = uiDefIconButO(block,
|
|
|
|
|
UI_BTYPE_BUT,
|
|
|
|
|
"UI_OT_unset_property_button",
|
|
|
|
|
WM_OP_EXEC_DEFAULT,
|
|
|
|
|
ICON_X,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
NULL);
|
2013-09-20 09:10:17 +00:00
|
|
|
but->rnapoin = *ptr;
|
|
|
|
|
but->rnaprop = prop;
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS);
|
2013-09-20 09:10:17 +00:00
|
|
|
}
|
2011-10-04 13:24:48 +00:00
|
|
|
}
|
|
|
|
|
RNA_STRUCT_END;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void uiTemplateKeymapItemProperties(uiLayout *layout, PointerRNA *ptr)
|
|
|
|
|
{
|
2012-03-30 01:51:25 +00:00
|
|
|
PointerRNA propptr = RNA_pointer_get(ptr, "properties");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (propptr.data) {
|
2012-03-30 01:51:25 +00:00
|
|
|
uiBut *but = uiLayoutGetBlock(layout)->buttons.last;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-03-29 12:52:52 +02:00
|
|
|
WM_operator_properties_sanitize(&propptr, false);
|
2011-10-04 13:24:48 +00:00
|
|
|
template_keymap_item_properties(layout, NULL, &propptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-10-04 13:24:48 +00:00
|
|
|
/* attach callbacks to compensate for missing properties update,
|
2012-03-03 16:31:46 +00:00
|
|
|
* we don't know which keymap (item) is being modified there */
|
2013-09-10 02:49:33 +00:00
|
|
|
for (; but; but = but->next) {
|
2020-09-30 20:09:02 +10:00
|
|
|
/* operator buttons may store props for use (file selector, T36492) */
|
2013-09-10 02:49:33 +00:00
|
|
|
if (but->rnaprop) {
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_func_set(but, keymap_item_modified, ptr->data, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-15 23:24:20 +11:00
|
|
|
/* Otherwise the keymap will be re-generated which we're trying to edit,
|
|
|
|
|
* see: T47685 */
|
2016-03-09 17:33:38 +11:00
|
|
|
UI_but_flag_enable(but, UI_BUT_UPDATE_DELAY);
|
2013-09-10 02:49:33 +00:00
|
|
|
}
|
|
|
|
|
}
|
2011-10-04 13:24:48 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
2019-10-28 02:51:26 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Event Icon Template
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
bool uiTemplateEventFromKeymapItem(struct uiLayout *layout,
|
|
|
|
|
const char *text,
|
|
|
|
|
const struct wmKeyMapItem *kmi,
|
|
|
|
|
bool text_fallback)
|
|
|
|
|
{
|
|
|
|
|
bool ok = false;
|
|
|
|
|
|
|
|
|
|
int icon_mod[4];
|
|
|
|
|
#ifdef WITH_HEADLESS
|
|
|
|
|
int icon = 0;
|
|
|
|
|
#else
|
2020-08-26 10:11:13 +10:00
|
|
|
const int icon = UI_icon_from_keymap_item(kmi, icon_mod);
|
2019-10-28 02:51:26 +11:00
|
|
|
#endif
|
|
|
|
|
if (icon != 0) {
|
|
|
|
|
for (int j = 0; j < ARRAY_SIZE(icon_mod) && icon_mod[j]; j++) {
|
|
|
|
|
uiItemL(layout, "", icon_mod[j]);
|
|
|
|
|
}
|
|
|
|
|
uiItemL(layout, text, icon);
|
|
|
|
|
ok = true;
|
|
|
|
|
}
|
|
|
|
|
else if (text_fallback) {
|
|
|
|
|
const char *event_text = WM_key_event_string(kmi->type, true);
|
|
|
|
|
uiItemL(layout, event_text, ICON_NONE);
|
|
|
|
|
uiItemL(layout, text, ICON_NONE);
|
|
|
|
|
ok = true;
|
|
|
|
|
}
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Color Management Template
|
|
|
|
|
* \{ */
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
|
|
|
|
|
void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, const char *propname)
|
|
|
|
|
{
|
2020-10-04 22:44:19 -05:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
|
|
|
|
|
if (!prop) {
|
|
|
|
|
printf(
|
|
|
|
|
"%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
PointerRNA colorspace_settings_ptr = RNA_property_pointer_get(ptr, prop);
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
|
2015-02-09 23:11:30 +01:00
|
|
|
uiItemR(layout, &colorspace_settings_ptr, "name", 0, IFACE_("Color Space"), ICON_NONE);
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void uiTemplateColormanagedViewSettings(uiLayout *layout,
|
|
|
|
|
bContext *UNUSED(C),
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname)
|
|
|
|
|
{
|
2020-10-04 22:44:19 -05:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
|
|
|
|
|
if (!prop) {
|
|
|
|
|
printf(
|
|
|
|
|
"%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
PointerRNA view_transform_ptr = RNA_property_pointer_get(ptr, prop);
|
|
|
|
|
ColorManagedViewSettings *view_settings = view_transform_ptr.data;
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *col = uiLayoutColumn(layout, false);
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *row = uiLayoutRow(col, false);
|
2014-08-08 01:30:22 +06:00
|
|
|
uiItemR(row, &view_transform_ptr, "view_transform", 0, IFACE_("View"), ICON_NONE);
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
col = uiLayoutColumn(layout, false);
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
uiItemR(col, &view_transform_ptr, "exposure", 0, NULL, ICON_NONE);
|
|
|
|
|
uiItemR(col, &view_transform_ptr, "gamma", 0, NULL, ICON_NONE);
|
|
|
|
|
|
2013-09-09 14:23:58 +00:00
|
|
|
uiItemR(col, &view_transform_ptr, "look", 0, IFACE_("Look"), ICON_NONE);
|
|
|
|
|
|
2014-01-04 17:16:19 +11:00
|
|
|
col = uiLayoutColumn(layout, false);
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
uiItemR(col, &view_transform_ptr, "use_curve_mapping", 0, NULL, ICON_NONE);
|
2019-03-25 10:15:20 +11:00
|
|
|
if (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) {
|
2018-08-23 10:25:54 +02:00
|
|
|
uiTemplateCurveMapping(
|
|
|
|
|
col, &view_transform_ptr, "curve_mapping", 'c', true, false, false, false);
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
}
|
2013-03-18 16:34:57 +00:00
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Component Menu
|
|
|
|
|
* \{ */
|
2013-03-18 16:34:57 +00:00
|
|
|
|
|
|
|
|
typedef struct ComponentMenuArgs {
|
|
|
|
|
PointerRNA ptr;
|
|
|
|
|
char propname[64]; /* XXX arbitrary */
|
|
|
|
|
} ComponentMenuArgs;
|
|
|
|
|
/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
|
2020-03-06 16:56:42 +01:00
|
|
|
static uiBlock *component_menu(bContext *C, ARegion *region, void *args_v)
|
2013-03-18 16:34:57 +00:00
|
|
|
{
|
2013-03-18 18:25:05 +00:00
|
|
|
ComponentMenuArgs *args = (ComponentMenuArgs *)args_v;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiLayout *layout = uiLayoutColumn(UI_block_layout(block,
|
|
|
|
|
UI_LAYOUT_VERTICAL,
|
|
|
|
|
UI_LAYOUT_PANEL,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
UI_UNIT_X * 6,
|
|
|
|
|
UI_UNIT_Y,
|
|
|
|
|
0,
|
|
|
|
|
UI_style_get()),
|
|
|
|
|
0);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
uiItemR(layout, &args->ptr, args->propname, UI_ITEM_R_EXPAND, "", ICON_NONE);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-27 12:16:16 +02:00
|
|
|
UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_direction_set(block, UI_DIR_DOWN);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
return block;
|
|
|
|
|
}
|
|
|
|
|
void uiTemplateComponentMenu(uiLayout *layout,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname,
|
|
|
|
|
const char *name)
|
|
|
|
|
{
|
|
|
|
|
ComponentMenuArgs *args = MEM_callocN(sizeof(ComponentMenuArgs), "component menu template args");
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
args->ptr = *ptr;
|
|
|
|
|
BLI_strncpy(args->propname, propname, sizeof(args->propname));
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_begin(block);
|
2013-03-18 16:34:57 +00:00
|
|
|
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBut *but = uiDefBlockButN(
|
|
|
|
|
block, component_menu, args, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, "");
|
2013-05-08 14:18:09 +00:00
|
|
|
/* set rna directly, uiDefBlockButN doesn't do this */
|
|
|
|
|
but->rnapoin = *ptr;
|
|
|
|
|
but->rnaprop = RNA_struct_find_property(ptr, propname);
|
|
|
|
|
but->rnaindex = 0;
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_end(block);
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Node Socket Icon Template
|
|
|
|
|
* \{ */
|
2013-03-18 16:34:57 +00:00
|
|
|
|
2021-04-28 13:13:43 -05:00
|
|
|
void uiTemplateNodeSocket(uiLayout *layout, bContext *UNUSED(C), float color[4])
|
2013-03-18 16:34:57 +00:00
|
|
|
{
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBlock *block = uiLayoutGetBlock(layout);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_begin(block);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
/* XXX using explicit socket colors is not quite ideal.
|
|
|
|
|
* Eventually it should be possible to use theme colors for this purpose,
|
|
|
|
|
* but this requires a better design for extendable color palettes in user prefs.
|
|
|
|
|
*/
|
2020-10-04 22:44:19 -05:00
|
|
|
uiBut *but = uiDefBut(
|
2014-11-09 21:20:40 +01:00
|
|
|
block, UI_BTYPE_NODE_SOCKET, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
2013-03-18 16:34:57 +00:00
|
|
|
rgba_float_to_uchar(but->col, color);
|
2018-05-23 10:47:12 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_end(block);
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Cache File Template
|
|
|
|
|
* \{ */
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
|
2020-06-02 14:09:01 -04:00
|
|
|
void uiTemplateCacheFile(uiLayout *layout,
|
|
|
|
|
const bContext *C,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const char *propname)
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
{
|
|
|
|
|
if (!ptr->data) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
|
|
|
|
|
|
|
|
|
if (!prop) {
|
|
|
|
|
printf(
|
|
|
|
|
"%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (RNA_property_type(prop) != PROP_POINTER) {
|
|
|
|
|
printf("%s: expected pointer property for %s.%s\n",
|
|
|
|
|
__func__,
|
|
|
|
|
RNA_struct_identifier(ptr->type),
|
|
|
|
|
propname);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PointerRNA fileptr = RNA_property_pointer_get(ptr, prop);
|
|
|
|
|
CacheFile *file = fileptr.data;
|
|
|
|
|
|
|
|
|
|
uiLayoutSetContextPointer(layout, "edit_cachefile", &fileptr);
|
|
|
|
|
|
2019-11-25 19:41:30 +01:00
|
|
|
uiTemplateID(layout,
|
|
|
|
|
C,
|
|
|
|
|
ptr,
|
|
|
|
|
propname,
|
|
|
|
|
NULL,
|
|
|
|
|
"CACHEFILE_OT_open",
|
|
|
|
|
NULL,
|
|
|
|
|
UI_TEMPLATE_ID_FILTER_ALL,
|
|
|
|
|
false,
|
|
|
|
|
NULL);
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
|
|
|
|
|
if (!file) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-16 10:44:15 +11:00
|
|
|
SpaceProperties *sbuts = CTX_wm_space_properties(C);
|
2016-10-28 17:56:09 +02:00
|
|
|
|
2020-06-29 16:36:19 -04:00
|
|
|
uiLayout *row, *sub, *subsub;
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
|
2020-06-29 16:36:19 -04:00
|
|
|
uiLayoutSetPropSep(layout, true);
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
|
2020-06-29 16:36:19 -04:00
|
|
|
row = uiLayoutRow(layout, true);
|
|
|
|
|
uiItemR(row, &fileptr, "filepath", 0, NULL, ICON_NONE);
|
|
|
|
|
sub = uiLayoutRow(row, true);
|
|
|
|
|
uiItemO(sub, "", ICON_FILE_REFRESH, "cachefile.reload");
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
|
|
|
|
|
row = uiLayoutRow(layout, false);
|
2020-06-29 16:36:19 -04:00
|
|
|
uiItemR(row, &fileptr, "is_sequence", 0, NULL, ICON_NONE);
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
|
2020-06-29 16:36:19 -04:00
|
|
|
row = uiLayoutRowWithHeading(layout, true, IFACE_("Override Frame"));
|
|
|
|
|
sub = uiLayoutRow(row, true);
|
|
|
|
|
uiLayoutSetPropDecorate(sub, false);
|
|
|
|
|
uiItemR(sub, &fileptr, "override_frame", 0, "", ICON_NONE);
|
|
|
|
|
subsub = uiLayoutRow(sub, true);
|
|
|
|
|
uiLayoutSetActive(subsub, RNA_boolean_get(&fileptr, "override_frame"));
|
|
|
|
|
uiItemR(subsub, &fileptr, "frame", 0, "", ICON_NONE);
|
|
|
|
|
uiItemDecoratorR(row, &fileptr, "frame", 0);
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
|
2017-10-29 17:23:50 +01:00
|
|
|
row = uiLayoutRow(layout, false);
|
2020-06-29 16:36:19 -04:00
|
|
|
uiItemR(row, &fileptr, "frame_offset", 0, NULL, ICON_NONE);
|
2019-04-04 15:07:37 +02:00
|
|
|
uiLayoutSetActive(row, !RNA_boolean_get(&fileptr, "is_sequence"));
|
2017-10-29 17:23:50 +01:00
|
|
|
|
2020-06-29 16:36:19 -04:00
|
|
|
if (sbuts->mainb == BCONTEXT_CONSTRAINT) {
|
|
|
|
|
row = uiLayoutRow(layout, false);
|
|
|
|
|
uiItemR(row, &fileptr, "scale", 0, IFACE_("Manual Scale"), ICON_NONE);
|
|
|
|
|
}
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
|
2020-08-03 03:28:04 +02:00
|
|
|
uiItemR(layout, &fileptr, "velocity_name", 0, NULL, ICON_NONE);
|
|
|
|
|
uiItemR(layout, &fileptr, "velocity_unit", 0, NULL, ICON_NONE);
|
|
|
|
|
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
/* TODO: unused for now, so no need to expose. */
|
|
|
|
|
#if 0
|
|
|
|
|
row = uiLayoutRow(layout, false);
|
|
|
|
|
uiItemR(row, &fileptr, "forward_axis", 0, "Forward Axis", ICON_NONE);
|
|
|
|
|
|
|
|
|
|
row = uiLayoutRow(layout, false);
|
|
|
|
|
uiItemR(row, &fileptr, "up_axis", 0, "Up Axis", ICON_NONE);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2018-09-18 17:44:14 +02:00
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Recent Files Template
|
|
|
|
|
* \{ */
|
2018-09-18 17:44:14 +02:00
|
|
|
|
|
|
|
|
int uiTemplateRecentFiles(uiLayout *layout, int rows)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
2020-08-18 21:46:29 -04:00
|
|
|
LISTBASE_FOREACH_INDEX (RecentFile *, recent, &G.recent_files, i) {
|
2020-08-19 12:26:49 +02:00
|
|
|
if (i >= rows) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-18 17:44:14 +02:00
|
|
|
const char *filename = BLI_path_basename(recent->filepath);
|
2019-05-14 14:13:02 +02:00
|
|
|
PointerRNA ptr;
|
|
|
|
|
uiItemFullO(layout,
|
|
|
|
|
"WM_OT_open_mainfile",
|
|
|
|
|
filename,
|
|
|
|
|
BLO_has_bfile_extension(filename) ? ICON_FILE_BLEND : ICON_FILE_BACKUP,
|
|
|
|
|
NULL,
|
|
|
|
|
WM_OP_INVOKE_DEFAULT,
|
|
|
|
|
0,
|
|
|
|
|
&ptr);
|
|
|
|
|
RNA_string_set(&ptr, "filepath", recent->filepath);
|
|
|
|
|
RNA_boolean_set(&ptr, "display_file_selector", false);
|
2018-09-18 17:44:14 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-09-18 17:44:14 +02:00
|
|
|
return i;
|
|
|
|
|
}
|
2019-09-06 01:22:35 +02:00
|
|
|
|
2019-09-06 16:12:47 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name FileSelectParams Path Button Template
|
|
|
|
|
* \{ */
|
2019-09-06 01:22:35 +02:00
|
|
|
|
|
|
|
|
void uiTemplateFileSelectPath(uiLayout *layout, bContext *C, FileSelectParams *params)
|
|
|
|
|
{
|
|
|
|
|
bScreen *screen = CTX_wm_screen(C);
|
|
|
|
|
SpaceFile *sfile = CTX_wm_space_file(C);
|
|
|
|
|
|
|
|
|
|
ED_file_path_button(screen, sfile, params, uiLayoutGetBlock(layout));
|
|
|
|
|
}
|
2019-09-06 16:12:47 +10:00
|
|
|
|
|
|
|
|
/** \} */
|