2013-10-08 15:07:52 +00:00
|
|
|
/*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2009 Blender Foundation.
|
|
|
|
* All rights reserved.
|
|
|
|
*/
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup edinterface
|
2013-10-08 15:07:52 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "DNA_screen_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_space_types.h"
|
2013-10-08 15:07:52 +00:00
|
|
|
|
|
|
|
#include "BKE_context.h"
|
|
|
|
#include "BKE_screen.h"
|
|
|
|
|
|
|
|
#include "UI_interface.h"
|
|
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
2013-10-08 15:32:54 +00:00
|
|
|
#include "interface_intern.h"
|
|
|
|
|
2017-12-12 15:16:13 +11:00
|
|
|
#include "interface_eyedropper_intern.h" /* own include */
|
2016-02-29 18:46:20 +01:00
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/* Keymap
|
|
|
|
*/
|
|
|
|
/** \name Modal Keymap
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
wmKeyMap *eyedropper_modal_keymap(wmKeyConfig *keyconf)
|
|
|
|
{
|
2017-10-18 15:07:26 +11:00
|
|
|
static const EnumPropertyItem modal_items[] = {
|
2016-02-29 18:46:20 +01:00
|
|
|
{EYE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
|
|
|
|
{EYE_MODAL_SAMPLE_CONFIRM, "SAMPLE_CONFIRM", 0, "Confirm Sampling", ""},
|
|
|
|
{EYE_MODAL_SAMPLE_BEGIN, "SAMPLE_BEGIN", 0, "Start Sampling", ""},
|
|
|
|
{EYE_MODAL_SAMPLE_RESET, "SAMPLE_RESET", 0, "Reset Sampling", ""},
|
2019-02-03 14:01:45 +11:00
|
|
|
{0, NULL, 0, NULL, NULL},
|
2016-02-29 18:46:20 +01:00
|
|
|
};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-27 10:58:00 +11:00
|
|
|
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Eyedropper Modal Map");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-02-29 18:46:20 +01:00
|
|
|
/* this function is called for each spacetype, only needs to add map once */
|
2019-03-25 10:15:20 +11:00
|
|
|
if (keymap && keymap->modal_items) {
|
2016-02-29 18:46:20 +01:00
|
|
|
return NULL;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-27 10:58:00 +11:00
|
|
|
keymap = WM_modalkeymap_ensure(keyconf, "Eyedropper Modal Map", modal_items);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-02-29 18:46:20 +01:00
|
|
|
/* assign to operators */
|
2019-03-18 18:20:44 +11:00
|
|
|
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_colorramp");
|
2016-02-29 18:46:20 +01:00
|
|
|
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_color");
|
|
|
|
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_id");
|
|
|
|
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_depth");
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_driver");
|
2019-10-11 13:28:22 +02:00
|
|
|
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_gpencil_color");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-02-29 18:46:20 +01:00
|
|
|
return keymap;
|
|
|
|
}
|
|
|
|
|
2017-12-12 10:19:55 +11:00
|
|
|
wmKeyMap *eyedropper_colorband_modal_keymap(wmKeyConfig *keyconf)
|
|
|
|
{
|
|
|
|
static const EnumPropertyItem modal_items_point[] = {
|
|
|
|
{EYE_MODAL_POINT_CANCEL, "CANCEL", 0, "Cancel", ""},
|
2020-10-24 11:42:17 -07:00
|
|
|
{EYE_MODAL_POINT_SAMPLE, "SAMPLE_SAMPLE", 0, "Sample a Point", ""},
|
2017-12-12 10:19:55 +11:00
|
|
|
{EYE_MODAL_POINT_CONFIRM, "SAMPLE_CONFIRM", 0, "Confirm Sampling", ""},
|
|
|
|
{EYE_MODAL_POINT_RESET, "SAMPLE_RESET", 0, "Reset Sampling", ""},
|
2019-02-03 14:01:45 +11:00
|
|
|
{0, NULL, 0, NULL, NULL},
|
2017-12-12 10:19:55 +11:00
|
|
|
};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-27 10:58:00 +11:00
|
|
|
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Eyedropper ColorRamp PointSampling Map");
|
2019-03-25 10:15:20 +11:00
|
|
|
if (keymap && keymap->modal_items) {
|
2017-12-12 10:19:55 +11:00
|
|
|
return keymap;
|
2019-03-25 10:15:20 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-27 10:58:00 +11:00
|
|
|
keymap = WM_modalkeymap_ensure(
|
2019-03-18 18:20:44 +11:00
|
|
|
keyconf, "Eyedropper ColorRamp PointSampling Map", modal_items_point);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-12-12 10:19:55 +11:00
|
|
|
/* assign to operators */
|
2019-03-18 18:20:44 +11:00
|
|
|
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_colorramp_point");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-12-12 10:19:55 +11:00
|
|
|
return keymap;
|
|
|
|
}
|
|
|
|
|
2016-02-29 18:46:20 +01:00
|
|
|
/** \} */
|
|
|
|
|
2015-01-14 08:01:40 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/* Utility Functions
|
|
|
|
*/
|
|
|
|
/** \name Generic Shared Functions
|
|
|
|
* \{ */
|
2021-03-17 08:48:05 +01:00
|
|
|
static void eyedropper_draw_cursor_text_ex(const int x, const int y, const char *name)
|
2015-01-14 08:01:40 +11:00
|
|
|
{
|
2015-01-20 14:25:39 +11:00
|
|
|
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
|
2021-03-17 08:48:05 +01:00
|
|
|
|
2016-11-22 14:40:57 +01:00
|
|
|
const float col_fg[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
|
|
|
const float col_bg[4] = {0.0f, 0.0f, 0.0f, 0.2f};
|
2015-01-20 15:48:40 +11:00
|
|
|
|
2021-03-17 08:48:05 +01:00
|
|
|
UI_fontstyle_draw_simple_backdrop(fstyle, x, y + U.widget_unit, name, col_fg, col_bg);
|
|
|
|
}
|
|
|
|
|
|
|
|
void eyedropper_draw_cursor_text_window(const struct wmWindow *window, const char *name)
|
|
|
|
{
|
|
|
|
if (name[0] == '\0') {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
|
|
|
}
|
2015-01-14 08:01:40 +11:00
|
|
|
|
2021-03-17 08:48:05 +01:00
|
|
|
const int x = window->eventstate->x;
|
|
|
|
const int y = window->eventstate->y;
|
2015-01-14 08:01:40 +11:00
|
|
|
|
2021-03-17 08:48:05 +01:00
|
|
|
eyedropper_draw_cursor_text_ex(x, y, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void eyedropper_draw_cursor_text_region(const struct bContext *C,
|
|
|
|
const ARegion *region,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2021-05-19 13:46:55 +02:00
|
|
|
const int x = win->eventstate->x;
|
|
|
|
const int y = win->eventstate->y;
|
2021-03-17 08:48:05 +01:00
|
|
|
|
|
|
|
if ((name[0] == '\0') || (BLI_rcti_isect_pt(®ion->winrct, x, y) == false)) {
|
|
|
|
return;
|
|
|
|
}
|
2015-01-14 08:01:40 +11:00
|
|
|
|
2021-05-19 13:46:55 +02:00
|
|
|
const int mval[2] = {
|
2021-05-25 18:25:44 +10:00
|
|
|
x - region->winrct.xmin,
|
|
|
|
y - region->winrct.ymin,
|
2021-05-19 13:46:55 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
eyedropper_draw_cursor_text_ex(mval[0], mval[1], name);
|
2015-01-14 08:01:40 +11:00
|
|
|
}
|
|
|
|
|
2016-03-27 01:22:19 +13:00
|
|
|
/**
|
|
|
|
* Utility to retrieve a button representing a RNA property that is currently under the cursor.
|
|
|
|
*
|
|
|
|
* This is to be used by any eyedroppers which fetch properties (e.g. UI_OT_eyedropper_driver).
|
|
|
|
* Especially during modal operations (e.g. as with the eyedroppers), context cannot be relied
|
|
|
|
* upon to provide this information, as it is not updated until the operator finishes.
|
|
|
|
*
|
|
|
|
* \return A button under the mouse which relates to some RNA Property, or NULL
|
|
|
|
*/
|
2017-12-12 15:16:13 +11:00
|
|
|
uiBut *eyedropper_get_property_button_under_mouse(bContext *C, const wmEvent *event)
|
2016-03-27 01:22:19 +13:00
|
|
|
{
|
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
|
|
|
bScreen *screen = CTX_wm_screen(C);
|
2020-04-03 13:25:03 +02:00
|
|
|
ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->x, event->y);
|
2021-03-24 14:25:30 +01:00
|
|
|
const ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_ANY, event->x, event->y);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
uiBut *but = ui_but_find_mouse_over(region, event);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-03-27 01:22:19 +13:00
|
|
|
if (ELEM(NULL, but, but->rnapoin.data, but->rnaprop)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2020-07-03 14:20:10 +02:00
|
|
|
return but;
|
2016-03-27 01:22:19 +13:00
|
|
|
}
|
|
|
|
|
2015-01-14 08:01:40 +11:00
|
|
|
/** \} */
|