A Pythonic wrapper around Cocoa.
Documentation is at vanilla.robotools.dev.
Install for your own use with pip:
$ pip install cocoa-vanilla
A Pythonic wrapper around Cocoa.
License: MIT License
A Pythonic wrapper around Cocoa.
Documentation is at vanilla.robotools.dev.
Install for your own use with pip:
$ pip install cocoa-vanilla
(in py3)
When the value is not a string, cocoa/pyObjc tries to localise somehow, fe numbers. This is not nice and different behaviour.
import vanilla
def callback(sender):
v = sender.get()
print(v, type(v))
w = vanilla.Window((400, 400))
w.t1 = vanilla.EditText((10, 10, -10, 22), "1000", callback=callback)
w.t2 = vanilla.EditText((10, 40, -10, 22), 1000, callback=callback)
w.open()
get()
and set()
are not symmetrical as the output get()
is not getting localised.
This behaviour has changed in cocoa and maybe the best advice is to stringify before setting any data in a control, so maybe vanilla should warn if this is happening.
"control": NSAlternateKeyMask,
"option": NSAlternateKeyMask,
About having NSAlternateKeyMask
instead of NSControlKeyMask
for the "control" key? I see in the Apple Doc, that the latter is deprecated (but all of them are). So what is the best way to bind the control key?
The example for the level indicator (found here http://ts-vanilla.readthedocs.io/en/latest/objects/List.html#list-item-cells) fails in RF3 but works in RF1.8.
I assume it has to do with the import cleanups done around 1d30cfd and fc61ccb.
This is from RF3:
Traceback (most recent call last):
File "<untitled>", line 30, in <module>
File "<untitled>", line 18, in __init__
File "/Applications/RoboFontPy3.app/Contents/Resources/lib/python3.6/vanilla/vanillaLevelIndicator.py", line 272, in LevelIndicatorListCell
NameError: name 'NSLevelIndicatorCell' is not defined
Seems like there's a small bug in Slider._isVertical()
. When w
is larger than h
, Slider._isVertical()
returns True
when it should be False
(ie. wider objects shouldn't be vertical).
The dependency on the RBSplitView framework is becoming an issue when OS versions change. The framework has to be recompiled and it doesn't look like it is being actively maintained. So, something needs to be done.
I was hopeful that the changes to NSSplitView a few OS versions ago would have eliminated the issues that required the external framework in the first place. That doesn't look to be the case, or at least it's not going to be feasible replacement with a even a moderate amount of work. Now I'm thinking that the easiest course of action is going to be to rewrite RBSplitView with PyObjC. That's going to be a non trivial amount of work, but it shouldn't be terribly hard.
I noticed that most recent development is happening on a yosemite
branch.
DrawBot also seems to require that branch.
Any reasons why this is not merged into master yet?
also, why is it called like that?
Cheers
This is probably what @anthrotype meant what could possibly go wrong...
>>> import vanilla
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/just/code/git/vanilla/Lib/vanilla/__init__.py", line 3, in <module>
from vanilla.vanillaBrowser import ObjectBrowser
File "/Users/just/code/git/vanilla/Lib/vanilla/vanillaBrowser.py", line 172, in <module>
class PythonItem(AppKit.NSObject):
File "/Users/just/code/git/vanilla/Lib/vanilla/vanillaBrowser.py", line 254, in PythonItem
@objc.python_method
AttributeError: 'module' object has no attribute 'python_method'
>>> objc.__version__
'2.5.1'
It might be useful to be able to add a menu to a list item. Something like
rowMenu = [("menu name", callback1), ...]
The callback would get the sender, or just the selected items.
Right now such a menu requires a bit of subclassing.
Hi, is there a way to more precisely "target" a specific cell in a List
?
For example, in a List like this:
To get the value of the "Type size" cell in row 1, I would do something like this in my editcallback
:
selectedIndex = self.w.myList.getSelection()[0]
newSize = self.w.myList[selectedIndex]["typeSize"]
vs. something like this, if possible:
selectedCellIndex = self.w.myList.getCell()
Thanks!
( extracted from #17 )
a proposal for the auto layout https://gist.github.com/typemytype/b9c85801762c579448d7
I noticed that checkbox labels are not vertically aligned with the text. It happens because the label is a separate text field, instead of just setting the title property of the checkbox button. The Header states that it was done to fix an alignment problem but that is fixed by now (at least in 10.12). In 10.9 the default it not 100% perfect but better than the manually set version. So the workaround should be removed.
In 10.7, Apple added a really interesting new method for building interfaces. I think this could be a replacement for the posSize argument in the standard vanilla object constructor. It's definitely worth a try.
I have skimmed the conceptual documentation and a couple of blog posts and I think the two bits of data are the layout string and an identifier hat the layout engine uses in conjunction with the layout string. These are my initial thoughts for the layout string:
For the identifier:
I think using the string as posSize and the attribute name as he identifier seem the cleanest. I'll experiment with the timing and structure of all of this.
Is there interest in making vanilla a bit more thread save? For example currently it is dangerous to change the content of a TextBox from a background thread. It could be handled like this:
if NSThread.isMainThread():
if isinstance(value, NSAttributedString):
self._nsObject.setAttributedStringValue_(value)
else:
self._nsObject.setStringValue_(value)
else:
if isinstance(value, NSAttributedString):
self._nsObject.performSelectorOnMainThread_withObject_waitUntilDone_("setAttributedStringValue:", value, False)
else:
self._nsObject.performSelectorOnMainThread_withObject_waitUntilDone_("setStringValue:", value, False)
It is not pretty but works. I couldn’t find a python version.
( extracted from issue #17 )
This is going to require some research on how localization is handled at the app level. I'm not sure if localization will be able to be specified on the fly per control, which is what would be ideal for vanilla.
with the proposal I did a while ago..
https://www.dropbox.com/s/0xqmkqqeo2n0hon/locaVanillaTest.zip?dl=0
( extracted from #17 )
more documentation about and examples of drag and drop
The app compiles without errors, but on launch it fails with this error:
Detected missing constraints for <private>. It cannot be placed because there are not enough constraints to fully define the size and origin. Add the missing constraints, or set translatesAutoresizingMaskIntoConstraints=YES and constraints will be generated for you. If this view is laid out manually on macOS 10.12 and later, you may choose to not call [super layout] from your override. Set a breakpoint on DETECTED_MISSING_CONSTRAINTS to debug. This error will only be logged once.
@typemytype any clues on how to fix this? I tried to set translatesAutoresizingMaskIntoConstraints somewhere in vanilla.vanillaWindows.Window
without success.
Hi, when I do this:
self.w.textEditor = TextEditor((10, 10, 200, 200), "text")
self.w.textEditor.enable(False)
I get an:
File "/Applications/RoboFont.app/Contents/Resources/lib/python3.6/vanilla/vanillaBase.py", line 115, in enable
self._nsObject.setEnabled_(onOff)
AttributeError: 'NSScrollView' object has no attribute 'setEnabled_'
instead of divining into a pond of NS-objects a convenient method for vanilla objects switching on off the focus ring
Hey all,
Long time listener, first time caller. I think I have found a bug in SplitView but I don't know enough about it to track it down. I can see through the commits that it recently has had some work done to move it away from RBSplitView to NSSplitView, so maybe @justvanrossum might have some idea what's going on.
I noticed at first because I was trying to port over some scripts to RF3, which has a more recent version of Vanilla, I assume, than 1.8.4.
Run the below in RoboFont 1.8.4 and RoboFont 3.0:
from vanilla import Window, SplitView, Box, TextBox
class GroupDemo(object):
def __init__(self):
self.w = Window((500, 500), minSize=(10,10))
self.panel1 = Box((20, 20, -20, -20))
self.panel1.text = TextBox((0, 0, -0, -0), "This is a box")
self.panel2 = Box((20, 20, -20, -20))
self.panel2.text = TextBox((0, 0, -0, -0), "This is a box, also")
panes = [
dict(view=self.panel1, identifier="panel1"),
dict(view=self.panel2, identifier="panel2"),
]
self.w.splitView = SplitView((0, 0, -0, -0), panes)
self.w.open()
GroupDemo()
In RF 1.8.4, with a previous version of Vanilla (I can't know which, since __version__
was just added), I get what I would expect: two panels with a box inside, with a 20px "margin"
In RF 3.0, and a newer version of Vanilla, I get a boxes that fill the entire panel. No matter what posSize
I make the Box (or Group, or Button, TextBox, etc), it will stay the same size and position.
"OK", I thought, "maybe I'll just add a sacrificial group to act as the panel container". Things get better, but still act strange:
from vanilla import Window, SplitView, Box, Group, TextBox
class GroupDemo2(object):
def __init__(self):
self.w = Window((500, 500), minSize=(10,10))
self.panel1 = Group((0, 0, -0, -0))
self.panel1.box = Box((20, 20, -20, 50))
self.panel1.box.text = TextBox((0, 0, -0, -0), "This is a box with absolute height")
self.panel2 = Group((0, 0, -0, -0))
self.panel2.box = Box((20, 20, -20, -20))
self.panel2.box.text = TextBox((0, 0, -0, -0), "This is a box with relative height")
panes = [
dict(view=self.panel1, identifier="panel1"),
dict(view=self.panel2, identifier="panel2"),
]
self.w.splitView = SplitView((0, 0, -0, -0), panes)
self.w.open()
GroupDemo2()
The box with the absolute height is positioned as I would expect, yay! But the relative height box runs off the top.
It may be a misunderstanding I have about how SplitView is supposed to work now, but I feel like something is wrong here. Even the demo code included in vanillaSplitView.py
displays differently from version to version.
Thanks!
I am using parent-child connected floating windows, and
found that child-windows that move off the screen give
an error on the getPosSize because
self._window.screen()
gets None when off-screen. I solved if for now with the
following redefinition of the method.
It may not be entirely right in the returned values, but
now it works without errors when dragging the parent window.
to the side of the screen.
Petr
def getPosSize(self):
"""
A tuple of form (left, top, width, height) representing the window's
position and size.
"""
frame = self._window.frame()
if self._window.screen() is not None:
l, t, w, h = _flipFrame(self._window.screen().visibleFrame(), frame)
titlebarHeight = self._calculateTitlebarHeight()
t += titlebarHeight
h -= titlebarHeight
else:
(l, t), (w, h) = frame
return (l, t, w, h)
It would be nice to show/hide specific items in a contextual menu in List. Here's a proposal for doing that.
In List
:
def setMenu_(self, items, validator=None):
self._menuItemValidator = validator
self._callbackWrappers = []
...
In VanillaTableViewSubclass
:
def menuForEvent_(self, event):
wrapper = self.vanillaWrapper()
if wrapper._menu is not None:
if wrapper._menuItemValidator is not None:
self._validateMenu(wrapper, wrapper._menu)
return wrapper._menu
def _validateMenu(self, wrapper, menu):
# XXX this is untested pseudo-code
for item in menu.itemArray():
if item == NSMenuItem.separatorItem():
pass
elif isinstance(item, NSMenu):
self._validateMenu(wrapper, item)
else:
self._validateMenuItem(wrapper, item)
def _validateMenuItem(self, wrapper, item):
hidden = not wrapper._menuItemValidator(wrapper, item.title())
item.setHidden_(hidden)
The validator function would look like this:
def myValidator(vanillaList, itemTitle):
if title == "foo":
if blah.blah.blah:
return False
return True
If True
is returned, show the item. If False
is returned, don't show the item.
In running setup.py for both both, SimpleApp and TinyTextEditor, I have similar problem:
Checking .pth file support in /Library/Python/2.7/site-packages/
/usr/bin/python -E -c pass
TEST PASSED: /Library/Python/2.7/site-packages/ appears to support .pth files
running bdist_egg
running egg_info
creating UNKNOWN.egg-info
writing UNKNOWN.egg-info/PKG-INFO
writing top-level names to UNKNOWN.egg-info/top_level.txt
writing dependency_links to UNKNOWN.egg-info/dependency_links.txt
writing manifest file 'UNKNOWN.egg-info/SOURCES.txt'
reading manifest file 'UNKNOWN.egg-info/SOURCES.txt'
writing manifest file 'UNKNOWN.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.13-intel/egg
running install_lib
warning: install_lib: 'build/lib' does not exist -- no Python modules to install
installing package data to build/bdist.macosx-10.13-intel/egg
running install_data
creating build
creating build/bdist.macosx-10.13-intel
creating build/bdist.macosx-10.13-intel/egg
warning: install_data: setup script did not provide a directory for 'Resources/English.lproj' -- installing right in 'build/bdist.macosx-10.13-intel/egg'
error: can't copy 'Resources/English.lproj': doesn't exist or not a regular file```
AppKit Release notes: https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKit/
This is handled simply with a new Group kwarg:
self.w.group = vanilla.Group((10, 10, -10, -10), blendingMode="withinWindow")
Internally, this is handled not so simply.
These are the current init kwargs that specify window appearance.
closable = True | False
miniaturizable = True | False
initiallyVisible = True | False
fullScreenMode = None | "primary" | "auxillary"
10.10 adds new appearance options: https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKit/#10_10Window
This pushes the content view underneath the title and toolbars. Those should then be set to be transparent. (Not always, but I don't want two flags so if the transparency is not desired a coder can override this with getNSWindow().setTitlebarAppearsTransparent_(False)
.) I'm not sure when this is used but we may as well make it possible.
self.w = vanilla.Window(..., fullSizeContentView=False, ...)
try:
NSFullSizeContentViewWindowMask
except NameError:
NSFullSizeContentViewWindowMask = 1 << 15
if fullSizeContentView and osVersion >= "10.10":
mask = mask | NSFullSizeContentViewWindowMask
# ... later ...
if fullSizeContentView and osVersion >= "10.10":
self._window.setTitlebarAppearsTransparent_(True)
This will show/hide the title of the window. If it is hidden, the toolbar moves to the space formally occupied by the title.
self.w = vanilla.Window(..., titleVisible=True, ...)
try:
NSWindowTitleVisible
except NameError:
NSWindowTitleVisible = 0
NSWindowTitleHidden = 1
if osVersion >= "10.10":
if not titleVisible:
self._window.setTitleVisibility_(NSWindowTitleHidden)
else:
self._window.setTitleVisibility_(NSWindowTitleVisible)
This is an advanced thing that should be handled outside of vanilla.
How would callbacks work?
Here's a tricky one: the use of cells in NSTableView is now deprecated. Instead, we are supposed to use views. That's easy enough to switch but mixing cells and views in the same table is not permitted. So, we can't simply change things like SliderListCell to be view based instead of cell based. We do need to make the change though. (Plus, view based tables can do some really useful stuff.)
I think we could handle this change by automatically detecting the cell types during __init__
by skimming the "cell" settings in columnDescriptions. If anything there is cell based, the table view would be set to cell mode. Otherwise it would be set to view mode.
I'm still researching this so this could change.
This is going to require some research on how localization is handled at the app level. I'm not sure if localization will be able to be specified on the fly per control, which is what would be ideal for vanilla.
This is going to be tricky but it might be a very worthwhile thing to add.
This class is now deprecated. It looks like RadioGroup can be rebuilt with a Group as a parent and individual buttons set to be radio buttons. According to the documentation, those will automatically be linked as a group in 10.8+.
next to enableDelete
which directly removes an entry from a List it could be handy to have just a plain deleteCallback, that is called when ever en entry is deleted from a list. An implementation can delete the entry itself or leave the list to remove the entry and just send a delete callback.
import vanilla
import AppKit
class DeleteList(vanilla.List):
def __init__(self, *args, **kwargs):
self._deleteCallback = None
if "deleteCallback" in kwargs:
self._deleteCallback = kwargs["deleteCallback"]
del kwargs["deleteCallback"]
super(DeleteList, self).__init__(*args, **kwargs)
def _keyDown(self, event):
if self._deleteCallback is not None:
characters = event.characters()
deleteCharacters = [
AppKit.NSBackspaceCharacter,
AppKit.NSDeleteFunctionKey,
AppKit.NSDeleteCharacter,
unichr(0x007F),
]
if characters in deleteCharacters:
self._deleteCallback(self)
return True
super(DeleteList, self)._keyDown(event)
def dummyDeleteCallback(sender):
print "delete"
w = vanilla.Window((400, 400))
w.l = DeleteList((10, 10, -10, -10), ["a", "b", "c"], deleteCallback=dummyDeleteCallback)
w.open()
Therefore it doesn't work. Copy whatever Window does/needs.
When sorting a column by clicking the column's header I get a editCallback. This might be on purpose, because the order changes and somehow the list is edited, but at the same time it is not edited because the entries in the list stay the same. Would it be rude to ask for something like a "sortationCallback" in order to be able to not get an "editCallback" when the column's header is clicked by the user? Or is there somehow a way to circumvent the editCallback when the header is clicked?
I’ve written a function for one of my scripts that allows to disable specified options in a RadioGroup. @typesupply if you are interested, I will add it to the RadioGroup class and send a pull request.
from AppKit import NSCellDisabled
def setNSMatrixCellEnabled(matrix, cell_index, state):
matrix.cells()[cell_index].setCellAttribute_to_(NSCellDisabled, not state)
matrix = self.w.the_selector.getNSMatrix()
setNSMatrixCellEnabled(matrix, 1, True)
from vanilla import *
c = 1
class TestGroup(Group):
def __init__(self, name):
global c
c += 1
super(TestGroup, self).__init__((0, 0, 10, 10))
self.name = name
def _breakCycles(self):
print("breakCycles", self.name)
super(TestGroup, self)._breakCycles()
w = Window((400, 400))
w.g1 = TestGroup("at window level")
w.g2 = Group((0, 0, 100, 100))
w.g2.g1 = TestGroup("in group")
w.g2.g2 = Group((0, 0, 100, 100))
w.g2.g2.g = TestGroup("in group in group")
w.t = Tabs((0, 0, -0, -200), ["hello", "world"])
w.t[0].g = TestGroup("in first tab level")
w.t[1].g = TestGroup("in second tab level")
paneDescriptions = [
dict(view=TestGroup("in split view 1 at window level"), canCollapse=False, minSize=200, identifier="test1"),
dict(view=TestGroup("in split view 2 at window level"), canCollapse=False, minSize=100, identifier="test2")
]
w.s = SplitView((0, 200, -0, -0), paneDescriptions=paneDescriptions)
paneDescriptions = [
dict(view=TestGroup("in split view 1 inside a split view 1"), canCollapse=False, minSize=200, identifier="test1"),
dict(view=TestGroup("in split view 2 inside a split view 1"), canCollapse=False, minSize=100, identifier="test2")
]
s1 = SplitView((0, 200, -0, -0), paneDescriptions=paneDescriptions)
paneDescriptions = [
dict(view=TestGroup("in split view 1 inside a split view 2"), canCollapse=False, minSize=200, identifier="test1"),
dict(view=TestGroup("in split view 2 inside a split view 2"), canCollapse=False, minSize=100, identifier="test2")
]
s2 = SplitView((0, 200, -0, -0), paneDescriptions=paneDescriptions)
paneDescriptions = [
dict(view=s1, canCollapse=False, minSize=200, identifier="test1"),
dict(view=s2, canCollapse=False, minSize=100, identifier="test2")
]
w.s2 = SplitView((0, 200, -0, -0), paneDescriptions=paneDescriptions)
w.open()
w.close()
print(c)
Is there a version number somewhere? If not, can we add one?
now it enables everything, but it could also be based on the index of a segment
https://github.com/typesupply/vanilla/blob/master/Lib/vanilla/vanillaSegmentedButton.py#L135-L140
this could be a new api enableSegment(True, index)
or enable(True, segment=index)
where segment is optional
Hi all,
I've been trying to find a method to get callbacks while the selection changes in a NSTextView instance which a vanilla TextEditor is wrapped around, something like 'NSTextViewDidChangeSelection' notification but I can't find a method on how this could be implemented in PyObjC. Does anyone here know how this is done?
Thanks
It's a pain to build the documentation. I wonder how many people have done it. Please consider making it available in a browsable way.
I've built the documentation and committed it to my fork under a branch named gh-pages
. This allows the contents of the branch to be browsable, like so: http://miguelsousa.github.io/vanilla/
NSPopover looks very useful, so wrap it. This will need to be a special case (like Window) since the class doesn't subclass NSView.
The from __future__ import print_function
does not seem to support the flush
keyord argument to print()
. Removing it makes the demo work again on 2.7.10.
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()
I wonder how to enable a different font style in a vanilla.TextEditor
field?
In my case, I’d just like monospaced text, but I assume there must be more formatting options, such as size, color, etc.
The following code results in a wrongly placed TextEditor. The vertical scroller is not visible, and you can't get to the top of the text.
This makes it hard to impossible to create more complex groups of views. I will try to make a more concrete example of the problem I am seeing.
from vanilla import *
w = Window((500, 500), "Test", minSize=(300, 300))
group1 = Group((10, 10, -10, -10))
group2 = Group((20, 20, -20, -20))
group2.textEditor = TextEditor((0, 0, 0, 0), "abcdefgh " * 1000)
# exchange these two lines and all is fine, but it's not always possible to do that
group1.group2 = group2
w.group1 = group1
w.open()
import AppKit
def ComboListCell(items, completes=True):
"""
An object that displays a combo box in a List column.
**This object should only be used in the *columnDescriptions*
argument during the construction of a List.**
**items** The items that should appear in the combo box.
**completes** Boolean representing if the combo box auto completes entered text.
Example:
from vanilla import *
class ComboListCellDemo(object):
def __init__(self):
self.w = Window((200, 300), minSize=(100, 100))
self.w.myList = List((0, 0, -0, -0),
[{"value": "a"}],
columnDescriptions=[
{
"title": "value",
"cell": ComboListCell(["a", "b", "c", "hello", "world"]),
},
],
editCallback=self.editCallback)
self.w.open()
def editCallback(self, sender):
print(sender.get())
ComboListCellDemo()
"""
cell = AppKit.NSComboBoxCell.alloc().init()
cell.setButtonBordered_(False)
cell.setBordered_(False)
cell.setDrawsBackground_(False)
cell.setEditable_(True)
cell.setCompletes_(completes)
cell.setControlSize_(AppKit.NSMiniControlSize)
titles = []
for title in items:
if isinstance(title, (AppKit.NSString, AppKit.NSAttributedString)):
title = title.string()
titles.append(title)
cell.addItemsWithObjectValues_(titles)
return cell
from vanilla import *
class ComboListCellDemo(object):
def __init__(self):
self.w = Window((200, 300), minSize=(100, 100))
self.w.myList = List((0, 0, -0, -0),
[{"value": "a"}],
columnDescriptions=[
{
"title": "value",
"cell": ComboListCell(["a", "b", "c", "hello", "world"]),
},
],
editCallback=self.editCallback)
self.w.open()
def editCallback(self, sender):
print(sender.get())
ComboListCellDemo()
Hi!
Consider this demo:
from vanilla import *
MARGIN = 8
BOTTOM_MARGIN = MARGIN*2
class MyDemo(object):
popOptions = ('one', 'two')
def __init__(self):
self.w = FloatingWindow((0, 0, 200, 300), 'MyDemo')
self.jumpingY = 10
self.w.myPop = PopUpButton((10, self.jumpingY, -10, 20),
self.popOptions,
callback=self.myPopCallback)
self.jumpingY += MARGIN + 20
self._initCtrlsModeOne()
self.w.resize(200, self.jumpingY+BOTTOM_MARGIN)
self.w.open()
def _initCtrlsModeOne(self):
self.w.buttonOneAA = SquareButton((10, self.jumpingY, -10, 30),
'AA')
self.jumpingY += MARGIN + 30
def _delCtrlsModeOne(self):
delattr(self.w, 'buttonOneAA')
self.jumpingY -= MARGIN + 30
def _delCtrlsModeTwo(self):
delattr(self.w, 'buttonTwoBB')
delattr(self.w, 'buttonTwoCC')
self.jumpingY -= (MARGIN + 30)*2
def _initCtrlsModeTwo(self):
self.w.buttonTwoBB = SquareButton((10, self.jumpingY, -10, 30),
'BB')
self.jumpingY += MARGIN + 30
self.w.buttonTwoCC = SquareButton((10, self.jumpingY, -10, 30),
'CC')
self.jumpingY += MARGIN + 30
self.w.resize(200, self.jumpingY)
def myPopCallback(self, sender):
if self.popOptions[sender.get()] == 'one':
self._delCtrlsModeTwo()
self._initCtrlsModeOne()
else:
self._delCtrlsModeOne()
self._initCtrlsModeTwo()
self.w.resize(200, self.jumpingY+BOTTOM_MARGIN)
if __name__ == '__main__':
md = MyDemo()
It is an example for a possible scenario. I have a tool, this tool has a popUpButton() on top which defines the usage mode. Different modes (for example, “place anchors”, “build accents") need different controls below the popUpButton(). Different controls, different window size needed. Therefore I use self.w.resize() to adjust the window height. The issue is: if the tool is placed on my second screen, the method moves the tool on top of the screen.
I am on MacOS 10.13.3
Thanks!
>>> import drawBot
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "drawBot/__init__.py", line 1, in <module>
from drawBotDrawingTools import _drawBotDrawingTool
File "drawBot/drawBotDrawingTools.py", line 9, in <module>
from context import getContextForFileExt
File "drawBot/context/__init__.py", line 1, in <module>
from pdfContext import PDFContext
File "drawBot/context/pdfContext.py", line 7, in <module>
from vanilla.vanillaBase import osVersion10_11, osVersionCurrent
ImportError: cannot import name osVersion10_11
I'm trying to use drawBot as a module. Installed all the dependencies but there seem to be some problems and as far as i understand vanilla is one of them. Is this an issue with vanilla itself?
MacOSX 10.11.5
Can't compile the SimpleApp demo from here:
https://github.com/typesupply/vanilla/tree/master/Demos/SimpleApp
running install
running bdist_egg
running egg_info
writing UNKNOWN.egg-info/PKG-INFO
writing dependency_links to UNKNOWN.egg-info/dependency_links.txt
writing top-level names to UNKNOWN.egg-info/top_level.txt
reading manifest file 'UNKNOWN.egg-info/SOURCES.txt'
writing manifest file 'UNKNOWN.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.13-x86_64/egg
running install_lib
warning: install_lib: 'build/lib' does not exist -- no Python modules to install
installing package data to build/bdist.macosx-10.13-x86_64/egg
running install_data
warning: install_data: setup script did not provide a directory for 'Resources/English.lproj' -- installing right in 'build/bdist.macosx-10.13-x86_64/egg'
error: can't copy 'Resources/English.lproj': doesn't exist or not a regular file
Reading the code here, I would expect this slider to be vertical.
It isn’t! What am I doing wrong?
from vanilla import *
class Vertical_Slider(object):
def __init__(self):
self.w = Window((60, 200))
self.w.slider = Slider(
(25, 10, 10, -10))
self.w.open()
Vertical_Slider()
does not adds test
and externalFrameworks
This is undocumented. Look at NSSegmentedControl and make sure that everything is supported. For example, tool tips need to be supported by vanilla.
Can't install demos with python3.6 getting this error:
* vanilla.core
I think I found a bug when dragging/dropping onto a list ... see a demo script for RoboFont here: https://gist.github.com/fsi-jens/3ef12361015f84cbc418
Dragging the color onto the list will trigger the bug.
Traceback (most recent call last):
File "/Applications/RoboFont.app/Contents/Resources/lib/python2.7/vanilla/vanillaList.py", line 164, in tableView_validateDrop_proposedRow_proposedDropOperation_
return self._handleDrop(True, tableView, draggingInfo, row, dropOperation)
File "/Applications/RoboFont.app/Contents/Resources/lib/python2.7/vanilla/vanillaList.py", line 110, in _handleDrop
if window is not None and draggingSource is not None and window == draggingSource.window() and vanillaWrapper._selfWindowDropSettings is not None:
AttributeError: No attribute window```
Run the following, and hit the "Click" button repeatedly until it crashes. The crash occurs in a fairly deep key/value binding callback.
If in the code below you change editable=True
to editable=False
, no crash occurs.
I am not sure how to further debug this.
from vanilla import Window, Button, List
class ListTest(object):
def __init__(self):
self.w = Window((600, 400), "Test")
self.w.button = Button((10, 10, 100, 25), "Click", self.buttonClick)
self.setList()
self.w.open()
def buttonClick(self, sender):
del self.w.list
self.setList()
def setList(self):
items = [dict(a=100) for i in range(3)]
descriptions = [dict(title="a", key="a", editable=True)]
self.w.list = List((120, 0, 0, 0), items, columnDescriptions=descriptions)
ListTest()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.