3
$\begingroup$

It seems it's possible to use screen.area_move because it is accomplished in the Pie Menu Editor addon and there's a thread on blenderartists.org where the author demonstrates using an operator from his addon to run screen.area_move. I'm wondering, how did he accomplish this?

#Just quickly converting the example code from the thread
C = bpy.context
a = C.area
x = a.x + (a.width >> 1)
y = a.y + a.height
C.window.cursor_warp(x, y)

#Replace Pie Menu Editor timeout operator (which I don't have access to) with timer app handler.
#bpy.ops.pme.timeout(delay=0.0001, cmd="bpy.ops.screen.area_move(x=%d, y=%d, delta=-100)" % (x, y))

def move_area():
    bpy.ops.screen.area_move(x=x, y=y, delta=-100)

bpy.app.timers.register(move_area, first_interval=1)

I've tried emulating the code posted on the thread and substituted his timeout operator with a timer apphandler. The apphandler works, but the context is still not correct. Also no combination (that I've tried) of override context passed seems to work.

Examining Blender source screen_ops.c the only poll for the operator SCREEN_OT_area_move seems to be for the position of the cursor:

ot->poll = ED_operator_screen_mainwinactive; /* when mouse is over area-edge */

Which I've managed to provide but still doesn't seem to be enough. Anyone ever get this particular operator working, or in any way figure out how to programmatically change the x, y, width or height of an editor?

$\endgroup$
1

1 Answer 1

3
$\begingroup$

Timer threads have little sense of context.

As outlined here

Context is incorrect when calling from a timer

need to pass some context to the timer. In this case I've passed a copy of the text editor context when hitting the button. Pretty sure just the screen is required context, or at most the window and screen.

enter image description here

Note found that calling the resize operator with no delta and moving the mouse worked from within a timer, however it is STICKY and a mouse click (or other events) are needed to unstick the mouse from moving the area. Not sure how to release. It is actually quite a handy way to resize the panels.. but still not quite right

import time, bpy, functools
from bpy import context

def snooper(c, w, a, x, y, delta, poll_retries=500):
    #bpy.ops.wm.redraw_timer(c, time_limit=0, iterations=10)

    while not bpy.ops.screen.area_move.poll(c, 'INVOKE_REGION_WIN'):
        poll_retries -= 1
        if not poll_retries:
            return None # out of retries

    # should poll now
    bpy.ops.screen.area_move(c,'INVOKE_REGION_WIN', x=x, y=y)

    y += delta
    w.cursor_warp(x, y)
    return None


if __name__ == '__main__':

    context = bpy.context
    a = context.area
    w = context.window
    x = a.x + (a.width >> 1)
    y = a.y + a.height     

    w.cursor_warp(x, y)
    bpy.app.timers.register(functools.partial(snooper, context.copy(), w, a, x, y, delta=100), first_interval=0.2)

Scissor sets

enter image description here

Looked into the screen areas a while back re overriding context. Recommend matching areas by the midpoints of edges and if both edge lengths also match they can be "pseudo joined" into a new area until we have one full window area with instructions on how to split back. Not unlike a binary tree.

Doing something similar here would be the go, giving the option of 1 to 4 possible resizes.. by looking for any "pseudo joined" areas in tree that have context.area and another area from the screen areas collection.

$\endgroup$
3
  • $\begingroup$ Voting more? Not sure what you mean. I'll definitely mark this as the answer as soon as I get a chance to test the code in a few days. A bit busy at the moment. I haven't up-voted your comment either because I haven't yet had the time to investigate everything properly. Very excited about what you've posted here though. I greatly appreciate the help you offer everyone. Thank you. $\endgroup$
    – Sicut Unum
    Commented Dec 24, 2019 at 16:08
  • $\begingroup$ What do you mean below, when you say "pseudo joined"? Assuming you mean not with bpy.ops.screen.area_join() (which I can't get to work in Blender 2.8 even with these context tricks). Are you able to use that operator to join areas? Is the "Scissor Sets" thing you posted from another post I can look at somewhere? $\endgroup$
    – Sicut Unum
    Commented Jan 1, 2020 at 19:31
  • $\begingroup$ @SicutUnum Did you ever get this to work for joining? $\endgroup$ Commented Mar 27, 2020 at 22:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .