Adding a new node in Node Editor failed for "High DPI" (Only Mac retina now).

- Py script for adding nodes was doing dpi magic, which it shouldn't. It has 
  been replaced with a (temporary) API call to set the correct cursor location.
  (Thanks to Lukas T for helping here)

- The SpaceNode->cursor[2] property now is *only* storing the coordinate
  in "adding new node space". Use of this has been removed from the code where
  possible, with as only exception the code to draw noodles while adding them.

Special coder note: Nodes should respect the DPI value, and draw larger with
larger buttons if you increase this size. The hack here is that this can only
work nice if also the node positions are scaled accordingly.

A better fix could be to check on scaling the node view itself for it. That
then would also remove this Python API call that was added in this commit.
However, that again might fight with how buttons layout code works now...
needs some careful checking.
This commit is contained in:
Ton Roosendaal 2013-09-05 13:03:03 +00:00
parent 69b68ed867
commit dc8832ac92
10 changed files with 92 additions and 77 deletions

View File

@ -66,12 +66,8 @@ class NodeAddOperator():
# convert mouse position to the View2D for later node placement
if context.region.type == 'WINDOW':
# XXX, temp fix for [#35920], still fails for (U.pixelsize != 1)
dpi_fac = context.user_preferences.system.dpi / 72.0
space.cursor_location = v2d.region_to_view(event.mouse_region_x,
event.mouse_region_y)
space.cursor_location /= dpi_fac
# convert mouse position to the View2D for later node placement
space.cursor_location_from_region(event.mouse_region_x, event.mouse_region_y)
else:
space.cursor_location = tree.view_center

View File

@ -3075,7 +3075,16 @@ int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, floa
{
float dist, vec[4][2];
float deltax, deltay;
float cursor[2] = {0.0f, 0.0f};
int toreroute, fromreroute;
/* this function can be called with snode null (via cut_links_intersect) */
/* XXX map snode->cursor back to view space */
if (snode) {
cursor[0] = snode->cursor[0] * UI_DPI_FAC;
cursor[1] = snode->cursor[1] * UI_DPI_FAC;
}
/* in v0 and v3 we put begin/end points */
if (link->fromsock) {
vec[0][0] = link->fromsock->locx;
@ -3084,7 +3093,7 @@ int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, floa
}
else {
if (snode == NULL) return 0;
copy_v2_v2(vec[0], snode->cursor);
copy_v2_v2(vec[0], cursor);
fromreroute = 0;
}
if (link->tosock) {
@ -3094,7 +3103,7 @@ int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, floa
}
else {
if (snode == NULL) return 0;
copy_v2_v2(vec[3], snode->cursor);
copy_v2_v2(vec[3], cursor);
toreroute = 0;
}

View File

@ -84,10 +84,6 @@ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx
node->locy = locy + 60.0f; /* arbitrary... so its visible, (0,0) is top of node */
nodeSetSelected(node, TRUE);
/* node location is mapped */
locx /= UI_DPI_FAC;
locy /= UI_DPI_FAC;
node->locx = locx;
node->locy = locy + 60.0f;
@ -417,9 +413,8 @@ static int node_add_mask_poll(bContext *C)
return ED_operator_node_editable(C) && snode->nodetree->type == NTREE_COMPOSIT;
}
static int node_add_mask_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int node_add_mask_exec(bContext *C, wmOperator *op)
{
ARegion *ar = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node;
ID *mask = NULL;
@ -435,9 +430,6 @@ static int node_add_mask_invoke(bContext *C, wmOperator *op, const wmEvent *even
ED_preview_kill_jobs(C);
/* convert mouse coordinates to v2d space */
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&snode->cursor[0], &snode->cursor[1]);
node = node_add_node(C, NULL, CMP_NODE_MASK, snode->cursor[0], snode->cursor[1]);
if (!node) {
@ -462,7 +454,7 @@ void NODE_OT_add_mask(wmOperatorType *ot)
ot->idname = "NODE_OT_add_mask";
/* callbacks */
ot->invoke = node_add_mask_invoke;
ot->exec = node_add_mask_exec;
ot->poll = node_add_mask_poll;
/* flags */

View File

@ -1075,31 +1075,31 @@ int node_get_resize_cursor(int directions)
return CURSOR_EDIT;
}
void node_set_cursor(wmWindow *win, SpaceNode *snode)
void node_set_cursor(wmWindow *win, SpaceNode *snode, float cursor[2])
{
bNodeTree *ntree = snode->edittree;
bNode *node;
bNodeSocket *sock;
int cursor = CURSOR_STD;
int wmcursor = CURSOR_STD;
if (ntree) {
if (node_find_indicated_socket(snode, &node, &sock, SOCK_IN | SOCK_OUT)) {
if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN | SOCK_OUT)) {
/* pass */
}
else {
/* check nodes front to back */
for (node = ntree->nodes.last; node; node = node->prev) {
if (BLI_rctf_isect_pt(&node->totr, snode->cursor[0], snode->cursor[1]))
if (BLI_rctf_isect_pt(&node->totr, cursor[0], cursor[1]))
break; /* first hit on node stops */
}
if (node) {
int dir = node->typeinfo->resize_area_func(node, snode->cursor[0], snode->cursor[1]);
cursor = node_get_resize_cursor(dir);
int dir = node->typeinfo->resize_area_func(node, cursor[0], cursor[1]);
wmcursor = node_get_resize_cursor(dir);
}
}
}
WM_cursor_set(win, cursor);
WM_cursor_set(win, wmcursor);
}
void node_draw_default(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node, bNodeInstanceKey key)
@ -1251,6 +1251,7 @@ static void draw_group_overlay(const bContext *C, ARegion *ar)
void drawnodespace(const bContext *C, ARegion *ar)
{
wmWindow *win = CTX_wm_window(C);
View2DScrollers *scrollers;
SpaceNode *snode = CTX_wm_space_node(C);
View2D *v2d = &ar->v2d;
@ -1259,7 +1260,13 @@ void drawnodespace(const bContext *C, ARegion *ar)
glClear(GL_COLOR_BUFFER_BIT);
UI_view2d_view_ortho(v2d);
/* XXX snode->cursor set in coordspace for placing new nodes, used for drawing noodles too */
UI_view2d_region_to_view(&ar->v2d, win->eventstate->x - ar->winrct.xmin, win->eventstate->y - ar->winrct.ymin,
&snode->cursor[0], &snode->cursor[1]);
snode->cursor[0] /= UI_DPI_FAC;
snode->cursor[1] /= UI_DPI_FAC;
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
/* only set once */

View File

@ -1056,7 +1056,7 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
/* checks snode->mouse position, and returns found node/socket */
/* type is SOCK_IN and/or SOCK_OUT */
int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, int in_out)
int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, float cursor[2], int in_out)
{
bNode *node;
bNodeSocket *sock;
@ -1068,10 +1068,10 @@ int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **so
/* check if we click in a socket */
for (node = snode->edittree->nodes.first; node; node = node->next) {
rect.xmin = snode->cursor[0] - (NODE_SOCKSIZE + 4);
rect.ymin = snode->cursor[1] - (NODE_SOCKSIZE + 4);
rect.xmax = snode->cursor[0] + (NODE_SOCKSIZE + 4);
rect.ymax = snode->cursor[1] + (NODE_SOCKSIZE + 4);
rect.xmin = cursor[0] - (NODE_SOCKSIZE + 4);
rect.ymin = cursor[1] - (NODE_SOCKSIZE + 4);
rect.xmax = cursor[0] + (NODE_SOCKSIZE + 4);
rect.ymax = cursor[1] + (NODE_SOCKSIZE + 4);
if (!(node->flag & NODE_HIDDEN)) {
/* extra padding inside and out - allow dragging on the text areas too */
@ -2087,17 +2087,6 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int node_clipboard_paste_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
/* convert mouse coordinates to v2d space */
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->cursor[0], &snode->cursor[1]);
return node_clipboard_paste_exec(C, op);
}
void NODE_OT_clipboard_paste(wmOperatorType *ot)
{
/* identifiers */
@ -2107,7 +2096,6 @@ void NODE_OT_clipboard_paste(wmOperatorType *ot)
/* api callbacks */
ot->exec = node_clipboard_paste_exec;
ot->invoke = node_clipboard_paste_invoke;
ot->poll = ED_operator_node_editable;
/* flags */

View File

@ -84,7 +84,7 @@ void node_draw_nodetree(const struct bContext *C, struct ARegion *ar, struct Spa
struct bNodeTree *ntree, bNodeInstanceKey parent_key);
void drawnodespace(const bContext *C, ARegion *ar);
void node_set_cursor(struct wmWindow *win, struct SpaceNode *snode);
void node_set_cursor(struct wmWindow *win, struct SpaceNode *snode, float cursor[2]);
/* DPI scaled coords */
void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry);
void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry);
@ -183,7 +183,7 @@ int composite_node_editable(struct bContext *C);
int node_has_hidden_sockets(bNode *node);
void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set);
int node_render_changed_exec(bContext *, struct wmOperator *);
int node_find_indicated_socket(struct SpaceNode *snode, struct bNode **nodep, struct bNodeSocket **sockp, int in_out);
int node_find_indicated_socket(struct SpaceNode *snode, struct bNode **nodep, struct bNodeSocket **sockp, float cursor[2], int in_out);
void NODE_OT_duplicate(struct wmOperatorType *ot);
void NODE_OT_delete(struct wmOperatorType *ot);

View File

@ -443,18 +443,19 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
bNodeSocket *tsock = NULL;
bNodeLink *link;
LinkData *linkdata;
float cursor[2];
int in_out;
in_out = nldrag->in_out;
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&snode->cursor[0], &snode->cursor[1]);
&cursor[0], &cursor[1]);
switch (event->type) {
case MOUSEMOVE:
if (in_out == SOCK_OUT) {
if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) {
if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_IN)) {
for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
link = linkdata->data;
@ -480,7 +481,7 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else {
if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) {
if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_OUT)) {
for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
link = linkdata->data;
@ -550,7 +551,7 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
/* return 1 when socket clicked */
static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach)
static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], int detach)
{
bNode *node;
bNodeSocket *sock;
@ -560,7 +561,7 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach)
int num_links;
/* output indicated? */
if (node_find_indicated_socket(snode, &node, &sock, SOCK_OUT)) {
if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_OUT)) {
nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
num_links = nodeCountSocketLinks(snode->edittree, sock);
@ -596,7 +597,7 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach)
}
}
/* or an input? */
else if (node_find_indicated_socket(snode, &node, &sock, SOCK_IN)) {
else if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN)) {
nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
num_links = nodeCountSocketLinks(snode->edittree, sock);
@ -644,14 +645,16 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
bNodeLinkDrag *nldrag;
float cursor[2];
int detach = RNA_boolean_get(op->ptr, "detach");
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&snode->cursor[0], &snode->cursor[1]);
&cursor[0], &cursor[1]);
ED_preview_kill_jobs(C);
nldrag = node_link_init(snode, detach);
nldrag = node_link_init(snode, cursor, detach);
if (nldrag) {
op->customdata = nldrag;
@ -1065,18 +1068,23 @@ void NODE_OT_join(wmOperatorType *ot)
/* ****************** Attach ******************* */
static int node_attach_exec(bContext *C, wmOperator *UNUSED(op))
static int node_attach_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
bNode *frame;
float cursor[2];
/* convert mouse coordinates to v2d space */
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &cursor[0], &cursor[1]);
/* check nodes front to back */
for (frame = ntree->nodes.last; frame; frame = frame->prev) {
/* skip selected, those are the nodes we want to attach */
if ((frame->type != NODE_FRAME) || (frame->flag & NODE_SELECT))
continue;
if (BLI_rctf_isect_pt(&frame->totr, snode->cursor[0], snode->cursor[1]))
if (BLI_rctf_isect_pt(&frame->totr, cursor[0], cursor[1]))
break;
}
if (frame) {
@ -1116,16 +1124,6 @@ static int node_attach_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
static int node_attach_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
/* convert mouse coordinates to v2d space */
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->cursor[0], &snode->cursor[1]);
return node_attach_exec(C, op);
}
void NODE_OT_attach(wmOperatorType *ot)
{
@ -1135,7 +1133,7 @@ void NODE_OT_attach(wmOperatorType *ot)
ot->idname = "NODE_OT_attach";
/* api callbacks */
ot->exec = node_attach_exec;
ot->invoke = node_attach_invoke;
ot->poll = ED_operator_node_editable;

View File

@ -306,24 +306,21 @@ static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const i
{
bNode *node, *tnode;
bNodeSocket *sock, *tsock;
float mx, my;
float cursor[2];
int selected = 0;
/* get mouse coordinates in view2d space */
UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &mx, &my);
/* node_find_indicated_socket uses snode->mx/my */
snode->cursor[0] = mx;
snode->cursor[1] = my;
UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &cursor[0], &cursor[1]);
if (extend) {
/* first do socket selection, these generally overlap with nodes.
* socket selection only in extend mode.
*/
if (node_find_indicated_socket(snode, &node, &sock, SOCK_IN)) {
if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN)) {
node_socket_toggle(node, sock, 1);
selected = 1;
}
else if (node_find_indicated_socket(snode, &node, &sock, SOCK_OUT)) {
else if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_OUT)) {
if (sock->flag & SELECT) {
node_socket_deselect(node, sock, 1);
}
@ -341,7 +338,7 @@ static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const i
}
else {
/* find the closest visible node */
node = node_under_mouse_select(snode->edittree, mx, my);
node = node_under_mouse_select(snode->edittree, cursor[0], cursor[1]);
if (node) {
if ((node->flag & SELECT) && (node->flag & NODE_ACTIVE) == 0) {
@ -362,7 +359,7 @@ static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const i
else { /* extend == 0 */
/* find the closest visible node */
node = node_under_mouse_select(snode->edittree, mx, my);
node = node_under_mouse_select(snode->edittree, cursor[0], cursor[1]);
if (node) {
for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {

View File

@ -602,8 +602,14 @@ static void node_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
/* convert mouse coordinates to v2d space */
UI_view2d_region_to_view(&ar->v2d, win->eventstate->x - ar->winrct.xmin, win->eventstate->y - ar->winrct.ymin,
&snode->cursor[0], &snode->cursor[1]);
/* here snode->cursor is used to detect the node edge for sizing */
node_set_cursor(win, snode, snode->cursor);
node_set_cursor(win, snode);
/* XXX snode->cursor is in placing new nodes space */
snode->cursor[0] /= UI_DPI_FAC;
snode->cursor[1] /= UI_DPI_FAC;
}
/* Initialize main area, setting handlers. */

View File

@ -172,6 +172,7 @@ static EnumPropertyItem buttons_texture_context_items[] = {
#include "DNA_mask_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
#include "BLI_math.h"
@ -197,6 +198,9 @@ static EnumPropertyItem buttons_texture_context_items[] = {
#include "IMB_imbuf_types.h"
#include "UI_interface.h"
#include "UI_view2d.h"
static StructRNA *rna_Space_refine(struct PointerRNA *ptr)
{
SpaceLink *space = (SpaceLink *)ptr->data;
@ -1263,6 +1267,15 @@ static void rna_SpaceNodeEditor_show_backdrop_update(Main *UNUSED(bmain), Scene
WM_main_add_notifier(NC_SCENE | ND_NODES, NULL);
}
static void rna_SpaceNodeEditor_cursor_location_from_region(SpaceNode *snode, bContext *C, int x, int y)
{
ARegion *ar = CTX_wm_region(C);
UI_view2d_region_to_view(&ar->v2d, x, y, &snode->cursor[0], &snode->cursor[1]);
snode->cursor[0] /= UI_DPI_FAC;
snode->cursor[1] /= UI_DPI_FAC;
}
static void rna_SpaceClipEditor_clip_set(PointerRNA *ptr, PointerRNA value)
{
SpaceClip *sc = (SpaceClip *)(ptr->data);
@ -3301,7 +3314,8 @@ static void rna_def_space_node_path_api(BlenderRNA *brna, PropertyRNA *cprop)
static void rna_def_space_node(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
PropertyRNA *prop, *parm;
FunctionRNA *func;
static EnumPropertyItem texture_type_items[] = {
{SNODE_TEX_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Edit texture nodes from Object"},
@ -3442,6 +3456,14 @@ static void rna_def_space_node(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "cursor");
RNA_def_property_ui_text(prop, "Cursor Location", "Location for adding new nodes");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
func = RNA_def_function(srna, "cursor_location_from_region", "rna_SpaceNodeEditor_cursor_location_from_region");
RNA_def_function_ui_description(func, "Set the cursor location using region coordinates");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_int(func, "x", 0, INT_MIN, INT_MAX, "x", "Region x coordinate", -10000, 10000);
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_int(func, "y", 0, INT_MIN, INT_MAX, "y", "Region y coordinate", -10000, 10000);
RNA_def_property_flag(parm, PROP_REQUIRED);
}
static void rna_def_space_logic(BlenderRNA *brna)