robotools / vanilla

A Pythonic wrapper around Cocoa.
MIT License
78 stars 28 forks source link

SplitView autosaveName has no effect #62

Open justvanrossum opened 6 years ago

justvanrossum commented 6 years ago

Is this the way I should use that? I was expecting the panes to be restored to their saved positions when running this, but they go back to their 50% default. I'm on 10.10 if that matters.

from vanilla import *

leftPane = List((0, 0, 0, 0), range(10))
rightPane = List((0, 0, 0, 0), range(10, 30))

paneDescriptors = [
    dict(view=leftPane, identifier="pane1"),
    dict(view=rightPane, identifier="pane2"),
]

w = Window((500, 300), "SplitViewTest")
w.splitView = SplitView((0, 0, -0, -0), paneDescriptors, autosaveName="myautosavename")

w.open()
justvanrossum commented 6 years ago

I see that the pane setting end up in the prefs file, but somehow they're being ignored when setting up the NSSplitView.

justvanrossum commented 6 years ago

I found a workaround at https://stackoverflow.com/questions/16587058/nssplitview-auto-saving-divider-positions-doesnt-work-with-auto-layout-enable

But it still doesn't work. By printing the frame info that is being fetched from the defaults I see that even though the correct frames are initially being stored, we're getting the default values anyway. Something in the way vanilla sets up the NSSplitView causes the defaults to be rewritten to their default values.

from AppKit import NSUserDefaults
from vanilla import *

def restoreAutosavedPositions(self):
    # Yes, I know my Autosave Name; but I won't necessarily restore myself automatically.
    key = "NSSplitView Subview Frames %s" % self.autosaveName()
    subviewFrames = NSUserDefaults.standardUserDefaults().valueForKey_(key)
    print(subviewFrames)
    # the last frame is skipped because I have one less divider than I have frames
    for i in range(len(subviewFrames) - 1):
        # this is the saved frame data - it's an NSString
        frameString = subviewFrames[i]
        components = frameString.split(", ")

        # only one component from the string is needed to set the position
        # if I'm vertical the third component is the frame width
        if self.isVertical():
            position = components[2]
        # if I'm horizontal the fourth component is the frame height
        else:
            position = components[3]

        self.setPosition_ofDividerAtIndex_(float(position), i)

leftPane = List((0, 0, 0, 0), range(10))
rightPane = List((0, 0, 0, 0), range(10, 30))

paneDescriptors = [
    dict(view=leftPane, identifier="pane1"),
    dict(view=rightPane, identifier="pane2"),
]

w = Window((500, 300), "SplitViewTest")
w.splitView = SplitView((0, 0, -0, -0), paneDescriptors, autosaveName="myautosavename")
restoreAutosavedPositions(w.splitView._nsObject)
w.open()