diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4b4b7d8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,207 @@ +# Created by https://www.toptal.com/developers/gitignore/api/python,visualstudiocode,venv +# Edit at https://www.toptal.com/developers/gitignore?templates=python,visualstudiocode,venv + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +### Python Patch ### +# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration +poetry.toml + +# ruff +.ruff_cache/ + +# LSP config files +pyrightconfig.json + +### venv ### +# Virtualenv +# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ +[Bb]in +[Ii]nclude +[Ll]ib +[Ll]ib64 +[Ll]ocal +[Ss]cripts +pyvenv.cfg +pip-selfcheck.json + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# End of https://www.toptal.com/developers/gitignore/api/python,visualstudiocode,venv \ No newline at end of file diff --git a/PyTouchBar/TouchBar.py b/PyTouchBar/TouchBar.py index 1960b8b..dc41b91 100755 --- a/PyTouchBar/TouchBar.py +++ b/PyTouchBar/TouchBar.py @@ -28,7 +28,6 @@ Action = action.Action - global DEBUG_LEVEL, buttonIds, tbdelegate, touchbar_items, customization_identifier, touchbar_items_id DEBUG_LEVEL = 0 @@ -38,204 +37,223 @@ touchbar_escape_item = None customization_identifier = None - - - -class NSWindowControllerTBModified (AppKit.NSWindowController): - ''' - A NSWindowController that handle touchbar methods. - It will be applied to windows with the "prepare_window" functions. - ''' - - def touchBar(self): - ''' Give the touchbar to the window''' - global DEBUG_LEVEL, buttonIds, touchbar_items_id, touchbar_items, tbdelegate, touchbar_items_customization, touchbar_escape_item, customization_identifier - if DEBUG_LEVEL == 1: - print ('TouchBar initializing') - - tb = AppKit.NSTouchBar.alloc().init() - - #self.tbdelegate = TouchBarDelegate.alloc().init() - - try: - if customization_identifier: - tb.setCustomizationIdentifier_(customization_identifier) - except: - traceback.print_exc() - - tb.setDelegate_(tbdelegate) - tb.setDefaultItemIdentifiers_([item.id for item in touchbar_items]) - tb.setCustomizationAllowedItemIdentifiers_([item.id for item in touchbar_items_id.values() if item.customization_mode == 1]) - tb.setCustomizationRequiredItemIdentifiers_([item.id for item in touchbar_items_id.values() if item.customization_mode == 2]) - - if touchbar_escape_item: - tb.setEscapeKeyReplacementItemIdentifier_(touchbar_escape_item.id) - - if DEBUG_LEVEL == 1: - print ('TouchBar initialized') - - - return tb - - - - + +class NSWindowControllerTBModified(AppKit.NSWindowController): + """ + A NSWindowController that handle touchbar methods. + It will be applied to windows with the "prepare_window" functions. + """ + + def touchBar(self): + """Give the touchbar to the window""" + global DEBUG_LEVEL, buttonIds, touchbar_items_id, touchbar_items, tbdelegate, touchbar_items_customization, touchbar_escape_item, customization_identifier + if DEBUG_LEVEL == 1: + print("TouchBar initializing") + + tb = AppKit.NSTouchBar.alloc().init() + + # self.tbdelegate = TouchBarDelegate.alloc().init() + + try: + if customization_identifier: + tb.setCustomizationIdentifier_(customization_identifier) + except: + traceback.print_exc() + + tb.setDelegate_(tbdelegate) + tb.setDefaultItemIdentifiers_([item.id for item in touchbar_items]) + tb.setCustomizationAllowedItemIdentifiers_( + [ + item.id + for item in touchbar_items_id.values() + if item.customization_mode == 1 + ] + ) + tb.setCustomizationRequiredItemIdentifiers_( + [ + item.id + for item in touchbar_items_id.values() + if item.customization_mode == 2 + ] + ) + + if touchbar_escape_item: + tb.setEscapeKeyReplacementItemIdentifier_(touchbar_escape_item.id) + + if DEBUG_LEVEL == 1: + print("TouchBar initialized") + + return tb + + class TouchBarDelegate(Foundation.NSObject): - ''' - A TouchBarDelegate that will create and render touchbar from its content-list items's id - ''' - def touchBar_makeItemForIdentifier_(self, bar, ident): - global touchbar_items_id, touchbar_items, DEBUG_LEVEL - - if DEBUG_LEVEL == 1: - print ('touchBar_makeItemForIdentifier_ : '+ ident) - - if ident not in touchbar_items_id.keys(): - warnings.warn("Requested ID that doesn't belong to any TouchbarItem", InternalWarning) - return - - item = touchbar_items_id[ident].makeItem() - if DEBUG_LEVEL == 1: - print ("Item: ",item) - return item - - - -def set_customization_identifier(identifier, menu = None): - ''' - Prepare the TouchBar to be customizable. - Give it an identifier (which will allow the user customization to be saved), and indicate if the app menu - should have a "Customize TouchBar" menu-item. - - Parameters: - identifier (str) : TouchBar identifier (https://developer.apple.com/documentation/appkit/nstouchbar/2544730-customizationidentifier?language=objc) - menu (Bool / None) : Set a "Customize TouchBar" menu item (None = unchanged) - ''' - global customization_identifier - customization_identifier = identifier - - if menu is not None: - AppKit.NSApplication.sharedApplication().setAutomaticCustomizeTouchBarMenuItemEnabled_(menu) - - - - - - -def set_touchbar(items, define = [], esc_key = None): - ''' - Set the content of the touchbar - - Parameters: - - items ( [TouchBarItem class instances] ) : The items that will be presented in the touchbar - ''' - - global touchbar_items_id, touchbar_items, touchbar_escape_item - - touchbar_items = items - touchbar_items_id = {} - - if esc_key: - touchbar_escape_item = esc_key - touchbar_items_id[esc_key.id] = esc_key - - for item in items: - touchbar_items_id[item.id] = item - - for item in define: - touchbar_items_id[item.id] = item - - -def customize(sender = None): - ''' - Toggle the TouchBar Customization Palette. - - Parameters: - sender (Any = None) : Sender of the action: will be passed to the ObjC method. (Not really useful, you should keep it None) - ''' - AppKit.lication.sharedApplication().toggleTouchBarCustomizationPalette_(sender) - - - + """ + A TouchBarDelegate that will create and render touchbar from its content-list items's id + """ + + def touchBar_makeItemForIdentifier_(self, bar, ident): + global touchbar_items_id, touchbar_items, DEBUG_LEVEL + + if DEBUG_LEVEL == 1: + print("touchBar_makeItemForIdentifier_ : " + ident) + + if ident not in touchbar_items_id.keys(): + warnings.warn( + "Requested ID that doesn't belong to any TouchbarItem", InternalWarning + ) + return + + item = touchbar_items_id[ident].makeItem() + if DEBUG_LEVEL == 1: + print("Item: ", item) + return item + + +def set_customization_identifier(identifier, menu=None): + """ + Prepare the TouchBar to be customizable. + Give it an identifier (which will allow the user customization to be saved), and indicate if the app menu + should have a "Customize TouchBar" menu-item. + + Parameters: + identifier (str) : TouchBar identifier (https://developer.apple.com/documentation/appkit/nstouchbar/2544730-customizationidentifier?language=objc) + menu (Bool / None) : Set a "Customize TouchBar" menu item (None = unchanged) + """ + global customization_identifier + customization_identifier = identifier + + if menu is not None: + AppKit.NSApplication.sharedApplication().setAutomaticCustomizeTouchBarMenuItemEnabled_( + menu + ) + + +def set_touchbar(items, define=[], esc_key=None): + """ + Set the content of the touchbar + + Parameters: + - items ( [TouchBarItem class instances] ) : The items that will be presented in the touchbar + """ + + global touchbar_items_id, touchbar_items, touchbar_escape_item + + touchbar_items = items + touchbar_items_id = {} + + if esc_key: + touchbar_escape_item = esc_key + touchbar_items_id[esc_key.id] = esc_key + + for item in items: + touchbar_items_id[item.id] = item + + for item in define: + touchbar_items_id[item.id] = item + + +def customize(sender=None): + """ + Toggle the TouchBar Customization Palette. + + Parameters: + sender (Any = None) : Sender of the action: will be passed to the ObjC method. (Not really useful, you should keep it None) + """ + AppKit.NSApplication.sharedApplication().toggleTouchBarCustomizationPalette_(sender) + + global delegate, window_controllers window_controllers = [] tbdelegate = TouchBarDelegate.alloc().init() + def notify(a): - ''' - A function that will be called when a Tk window is opened. This is bined to the window in the prepare_tk_windows method - ''' - global delegate, DEBUG_LEVEL - make_crash = False - - windows = AppKit.NSApplication.sharedApplication().windows() - for window in windows: - window_controllers.append(NSWindowControllerTBModified.alloc().initWithWindow_(window)) - + """ + A function that will be called when a Tk window is opened. This is bined to the window in the prepare_tk_windows method + """ + global delegate, DEBUG_LEVEL + make_crash = False + + windows = AppKit.NSApplication.sharedApplication().windows() + for window in windows: + window_controllers.append( + NSWindowControllerTBModified.alloc().initWithWindow_(window) + ) + + def reload_touchbar(): - ''' - Rebuild the touchbar, after a modification or a change in its content - ''' - global delegate, window_controllers, DEBUG_LEVEL - for controller in window_controllers: - if DEBUG_LEVEL == 1: - print ('Making new touchbar') - controller.setTouchBar_(controller.touchBar()) + """ + Rebuild the touchbar, after a modification or a change in its content + """ + global delegate, window_controllers, DEBUG_LEVEL + for controller in window_controllers: + if DEBUG_LEVEL == 1: + print("Making new touchbar") + controller.setTouchBar_(controller.touchBar()) + def prepare_tk_windows(windows): - ''' - This function is needed to prepare Tk window(s) to "host" a touchbar. - Call this function before mainlooping the window. - - Parameters: - - windows ( [Tk] or Tk) : A Tk instance OR a list of Tk instances - ''' - global delegate - if isinstance(windows, list): - for window in windows: - window.bind("", notify) - else: - prepare_tk_windows([windows]) - + """ + This function is needed to prepare Tk window(s) to "host" a touchbar. + Call this function before mainlooping the window. + + Parameters: + - windows ( [Tk] or Tk) : A Tk instance OR a list of Tk instances + """ + global delegate + if isinstance(windows, list): + for window in windows: + window.bind("", notify) + else: + prepare_tk_windows([windows]) + + def resetPreparedWindows(): - ''' - Clear touchbar from all windows - ''' - windows = AppKit.NSApplication.sharedApplication().windows() - for window in windows: - window_controllers.append(NSWindowControllerTBModified.alloc().initWithWindow_(window)) - + """ + Clear touchbar from all windows + """ + windows = AppKit.NSApplication.sharedApplication().windows() + for window in windows: + window_controllers.append( + NSWindowControllerTBModified.alloc().initWithWindow_(window) + ) + + def prepare_pygame(): - ''' - This function is needed to prepare Pygame window to "host" a touchbar. - Call this function before mainlooping the pygame. - ''' - windows = AppKit.NSApplication.sharedApplication().windows() - for window in windows: - if window.windowController() == None: - window_controllers.append(NSWindowControllerTBModified.alloc().initWithWindow_(window)) + """ + This function is needed to prepare Pygame window to "host" a touchbar. + Call this function before mainlooping the pygame. + """ + windows = AppKit.NSApplication.sharedApplication().windows() + for window in windows: + if window.windowController() == None: + window_controllers.append( + NSWindowControllerTBModified.alloc().initWithWindow_(window) + ) + def set_touchbar_pygame(): - ''' - WIP - ''' - windows = AppKit.NSApplication.sharedApplication().windows() - for window in windows: - view = window.contentView().subviews()[0] + """ + WIP + """ + windows = AppKit.NSApplication.sharedApplication().windows() + for window in windows: + view = window.contentView().subviews()[0] class TouchBarTk(Tk): - ''' - A Tk subclassed to automatically be prepared to host a touchbar - It takes same arguments as Tk - ''' - def __init__(self, *args, **kwargs): - Tk.__init__(self, *args, **kwargs) - prepare_tk_windows(self) - - -if __name__ == '__main__': - from . import tests - tests.testTk() - \ No newline at end of file + """ + A Tk subclassed to automatically be prepared to host a touchbar + It takes same arguments as Tk + """ + + def __init__(self, *args, **kwargs): + Tk.__init__(self, *args, **kwargs) + prepare_tk_windows(self) + + +if __name__ == "__main__": + from . import tests + + tests.testTk() diff --git a/PyTouchBar/items.py b/PyTouchBar/items.py index 110dbf6..12eba32 100755 --- a/PyTouchBar/items.py +++ b/PyTouchBar/items.py @@ -8,7 +8,7 @@ import warnings import objc -from Foundation import NSObject +from Foundation import NSObject, NSString import AppKit from PyObjCTools import AppHelper import Cocoa @@ -22,737 +22,765 @@ # Base Classes class TouchBarBaseItem(object): - pass - + pass + + class TouchBarItem(TouchBarBaseItem): - def __init__(self, **kwargs): - self.id = kwargs.get('id', str(uuid.uuid4())) - - def makeItem(self): - item = AppKit.NSCustomTouchBarItem.alloc().initWithIdentifier_(self.id) - return item - - - - + def __init__(self, **kwargs): + self.id = kwargs.get("id", str(uuid.uuid4())) + + def makeItem(self): + item = AppKit.NSCustomTouchBarItem.alloc().initWithIdentifier_(self.id) + return item + + # Item Definitions + class Space: - ''' - A Space item is an empty item, its only purpose is to take place - ''' - class Small(TouchBarBaseItem): - def __init__(self, customization_mode = 0): - self.id = "NSTouchBarItemIdentifierFixedSpaceSmall" - self.customization_mode = customization_mode - - class Large(TouchBarBaseItem): - def __init__(self, customization_mode = 0): - self.id = "NSTouchBarItemIdentifierFixedSpaceLarge" - self.customization_mode = customization_mode - - class Flexible(TouchBarBaseItem): - ''' - A Flexible space is a space item that take all the space it can - ''' - def __init__(self, customization_mode = 0): - self.id = "NSTouchBarItemIdentifierFlexibleSpace" - self.customization_mode = customization_mode - - + """ + A Space item is an empty item, its only purpose is to take place + """ + + class Small(TouchBarBaseItem): + def __init__(self, customization_mode=0): + self.id = "NSTouchBarItemIdentifierFixedSpaceSmall" + self.customization_mode = customization_mode + + class Large(TouchBarBaseItem): + def __init__(self, customization_mode=0): + self.id = "NSTouchBarItemIdentifierFixedSpaceLarge" + self.customization_mode = customization_mode + + class Flexible(TouchBarBaseItem): + """ + A Flexible space is a space item that take all the space it can + """ + + def __init__(self, customization_mode=0): + self.id = "NSTouchBarItemIdentifierFlexibleSpace" + self.customization_mode = customization_mode + + class Popover(TouchBarItem): - ''' - A Popover item is an item that will act just like a "subtouchbar": is looks like a button that - will present another touchbar content when pressed. - - Parameters: - - title (String) : the title of the popover button - - shows_close_button (Bool) : Optional: if true, a "x" button will be presented in the popover to close it - - holdItems ([TouchBarItem]) : The list of touchbar items contained by the popover - - Methods: - reload() : Reload the popover content - open() : Open the popover - close() : Close the popover - ''' - - - def __init__(self, items, **kwargs): - - self.id = kwargs.get('id', str(uuid.uuid4())) - - - self.title = kwargs.get('title','Popover') - self.shows_close_button = kwargs.get('shows_close_button', True) - self.holdItems = kwargs.get('hold', None) - - - #self.main.tbdelegate = TouchBarDelegate.alloc().init() - - - self.items = items - self.item = AppKit.NSPopoverTouchBarItem.alloc().init() - - self.customization_label = kwargs.get('customization_label', 'Popover') - self.customization_mode = kwargs.get('customization_mode', 0) - - - - def makeItem(self): - - #instanciedItems = list(map(lambda item: item.makeItem(), self.items)) - - self.item = AppKit.NSPopoverTouchBarItem.alloc().initWithIdentifier_(self.id) - self.item.setShowsCloseButton_(self.shows_close_button) - - self.reload() - - - self.item.setCollapsedRepresentationLabel_(self.title) - - - self.item.setCustomizationLabel_(self.customization_label) - return self.item - - - def reload(self): - - - self.secondaryTouchBar = AppKit.NSTouchBar.alloc().init() - self.holdTouchbar = AppKit.NSTouchBar.alloc().init() - self.secondaryTouchBar.setDelegate_(main.tbdelegate) - self.holdTouchbar.setDelegate_(main.tbdelegate) - - for item in self.items: - main.touchbar_items_id[item.id] = item - - self.secondaryTouchBar.setDefaultItemIdentifiers_(list(map(lambda item: item.id, self.items))) - self.item.setPopoverTouchBar_(self.secondaryTouchBar) - - if self.holdItems: - for item in self.holdItems: - main.touchbar_items_id[item.id] = item - - self.holdTouchbar.setDefaultItemIdentifiers_(list(map(lambda item: item.id, self.holdItems))) - self.item.setPressAndHoldTouchBar_(self.holdTouchbar) - - - def open(self, *dontcare): - self.item.showPopover_(None) - - def close(self, *dontcare): - self.item.dismissPopover_(None) - - + """ + A Popover item is an item that will act just like a "subtouchbar": is looks like a button that + will present another touchbar content when pressed. + + Parameters: + - title (String) : the title of the popover button + - shows_close_button (Bool) : Optional: if true, a "x" button will be presented in the popover to close it + - holdItems ([TouchBarItem]) : The list of touchbar items contained by the popover + + Methods: + reload() : Reload the popover content + open() : Open the popover + close() : Close the popover + """ + + def __init__(self, items, **kwargs): + + self.id = kwargs.get("id", str(uuid.uuid4())) + + self.title = kwargs.get("title", "Popover") + self.shows_close_button = kwargs.get("shows_close_button", True) + self.holdItems = kwargs.get("hold", None) + + # self.main.tbdelegate = TouchBarDelegate.alloc().init() + + self.items = items + self.item = AppKit.NSPopoverTouchBarItem.alloc().init() + + self.customization_label = kwargs.get("customization_label", "Popover") + self.customization_mode = kwargs.get("customization_mode", 0) + + def makeItem(self): + + # instanciedItems = list(map(lambda item: item.makeItem(), self.items)) + + self.item = AppKit.NSPopoverTouchBarItem.alloc().initWithIdentifier_(self.id) + self.item.setShowsCloseButton_(self.shows_close_button) + + self.reload() + + self.item.setCollapsedRepresentationLabel_(self.title) + + self.item.setCustomizationLabel_(self.customization_label) + return self.item + + def reload(self): + + self.secondaryTouchBar = AppKit.NSTouchBar.alloc().init() + self.holdTouchbar = AppKit.NSTouchBar.alloc().init() + self.secondaryTouchBar.setDelegate_(main.tbdelegate) + self.holdTouchbar.setDelegate_(main.tbdelegate) + + for item in self.items: + main.touchbar_items_id[item.id] = item + + self.secondaryTouchBar.setDefaultItemIdentifiers_( + list(map(lambda item: item.id, self.items)) + ) + self.item.setPopoverTouchBar_(self.secondaryTouchBar) + + if self.holdItems: + for item in self.holdItems: + main.touchbar_items_id[item.id] = item + + self.holdTouchbar.setDefaultItemIdentifiers_( + list(map(lambda item: item.id, self.holdItems)) + ) + self.item.setPressAndHoldTouchBar_(self.holdTouchbar) + + def open(self, *dontcare): + self.item.showPopover_(None) + + def close(self, *dontcare): + self.item.dismissPopover_(None) + + class Group(TouchBarItem): - def __init__(self, items, id = str(uuid.uuid4()), customization_label = "Group", customization_mode = 0): - self.id = id - - self.customization_label = customization_label - self.customization_mode = customization_mode - - self.items = items - - def makeItem(self): - instanciedItems = list(map(lambda item: item.makeItem(), self.items)) - - self.item = AppKit.NSGroupTouchBarItem.groupItemWithIdentifier_items_(self.id, instanciedItems) - self.item.setCustomizationLabel_(self.customization_label) - return self.item - - + def __init__( + self, + items, + id=str(uuid.uuid4()), + customization_label="Group", + customization_mode=0, + ): + self.id = id + + self.customization_label = customization_label + self.customization_mode = customization_mode + + self.items = items + + def makeItem(self): + instanciedItems = list(map(lambda item: item.makeItem(), self.items)) + + self.item = AppKit.NSGroupTouchBarItem.groupItemWithIdentifier_items_( + self.id, instanciedItems + ) + self.item.setCustomizationLabel_(self.customization_label) + return self.item + + class CustomNSView(TouchBarItem): - def __init__(self, view): - self.id = str(uuid.uuid4()) - - self.item = AppKit.NSCustomTouchBarItem.alloc().initWithIdentifier_(self.id) - self.item.setCustomizationLabel_("Custom View") - #self.item.view().addSubview_(view) - self.item.setView_(view) - - - def makeItem(self): - return self.item - - + def __init__(self, view): + self.id = str(uuid.uuid4()) + + self.item = AppKit.NSCustomTouchBarItem.alloc().initWithIdentifier_(self.id) + self.item.setCustomizationLabel_("Custom View") + # self.item.view().addSubview_(view) + self.item.setView_(view) + + def makeItem(self): + return self.item + + class Label(TouchBarItem): - ''' - A popover is a touchbar item that will present text. - - Parameters: - - text (String) : The string to be presented - - text_color ( (r, g, b, a) or Color constant, optional) : The foreground color of the text - - alignment (Alignment constant, optional) : Where the text needs to be presented in the item - - font_name (String, optional) : The font family name - - font_size (Int, optional) : The size of the font in pts - ''' - - def __init__(self, **kwargs): - self.id = kwargs.get('id', str(uuid.uuid4())) - self.label = None - - self.textBase = NSString(kwargs.get('text','Label')) - self.text_color_ = kwargs.get('text_color',Color.white) - self.alignment_ = kwargs.get('alignment',Alignment.center) - self.font_name_ = kwargs.get('font', "Arial") - self.font_size_ = kwargs.get('font_size', 16) - - self.customization_label = kwargs.get('customization_label', 'Label') - self.customization_mode = kwargs.get('customization_mode', 0) - - - def makeItem(self): - item = AppKit.NSCustomTouchBarItem.alloc().initWithIdentifier_(self.id) - - self.label = AppKit.NSTextField.labelWithString_(self.textBase) - self.label.setTextColor_(AppKit.NSColor.colorWithRed_green_blue_alpha_( * self.text_color_)) - self.label.setAlignment_(self.alignment_) - font = AppKit.NSFont.fontWithName_size_(self.font_name_,self.font_size_) - - item.setView_(self.label) - item.setCustomizationLabel_(self.customization_label) - - return item - - # Properties - # # Text - def textGetter(self): - return self.label.stringValue() - - def textSetter(self, newValue): - if self.label: - self.label.setStringValue_(NSString(newValue)) - - text = property(textGetter, textSetter) - - # #Text Color - def textColorGetter(self): - return self.text_color_ - - def textColorSetter(self, newValue): - self.label.setTextColor_(AppKit.NSColor.colorWithRed_green_blue_alpha_( * newValue)) - self.text_color_ = newValue - - text_color = property(textColorGetter, textColorSetter) - - # #Font - def fontGetter(self): - return self.font_name_ - - def fontSetter(self, newValue): - font = AppKit.NSFont.fontWithName_size_(newValue,newValue) - self.label.setFont_(font) - self.font_name_ = newValue - - font_name = property(fontGetter, fontSetter) - - # #Font Size - def fontSizeGetter(self): - return self.font_size_ - - def fontSizeSetter(self, newValue): - font = AppKit.NSFont.fontWithName_size_(self.font_name_,newValue) - self.label.setFont_(font) - self.font_size_ = newValue - - font_size = property(fontSizeGetter, fontSizeSetter) - - # # Alignment - def alignmentGetter(self): - return self.alignment_ - - def alignmentSetter(self, newValue): - self.label.setAlignment_(newValue) - self.alignment_ = newValue - - alignment = property(alignmentGetter, alignmentSetter) - - + """ + A popover is a touchbar item that will present text. + + Parameters: + - text (String) : The string to be presented + - text_color ( (r, g, b, a) or Color constant, optional) : The foreground color of the text + - alignment (Alignment constant, optional) : Where the text needs to be presented in the item + - font_name (String, optional) : The font family name + - font_size (Int, optional) : The size of the font in pts + """ + + def __init__(self, **kwargs): + self.id = kwargs.get("id", str(uuid.uuid4())) + self.label = None + + self.textBase = NSString(kwargs.get("text", "Label")) + self.text_color_ = kwargs.get("text_color", Color.white) + self.alignment_ = kwargs.get("alignment", Alignment.center) + self.font_name_ = kwargs.get("font", "Arial") + self.font_size_ = kwargs.get("font_size", 16) + + self.customization_label = kwargs.get("customization_label", "Label") + self.customization_mode = kwargs.get("customization_mode", 0) + + def makeItem(self): + item = AppKit.NSCustomTouchBarItem.alloc().initWithIdentifier_(self.id) + + self.label = AppKit.NSTextField.labelWithString_(self.textBase) + self.label.setTextColor_( + AppKit.NSColor.colorWithRed_green_blue_alpha_(*self.text_color_) + ) + self.label.setAlignment_(self.alignment_) + font = AppKit.NSFont.fontWithName_size_(self.font_name_, self.font_size_) + + item.setView_(self.label) + item.setCustomizationLabel_(self.customization_label) + + return item + + # Properties + # # Text + def textGetter(self): + return self.label.stringValue() + + def textSetter(self, newValue): + if self.label: + self.label.setStringValue_(NSString(newValue)) + + text = property(textGetter, textSetter) + + # #Text Color + def textColorGetter(self): + return self.text_color_ + + def textColorSetter(self, newValue): + self.label.setTextColor_( + AppKit.NSColor.colorWithRed_green_blue_alpha_(*newValue) + ) + self.text_color_ = newValue + + text_color = property(textColorGetter, textColorSetter) + + # #Font + def fontGetter(self): + return self.font_name_ + + def fontSetter(self, newValue): + font = AppKit.NSFont.fontWithName_size_(newValue, newValue) + self.label.setFont_(font) + self.font_name_ = newValue + + font_name = property(fontGetter, fontSetter) + + # #Font Size + def fontSizeGetter(self): + return self.font_size_ + + def fontSizeSetter(self, newValue): + font = AppKit.NSFont.fontWithName_size_(self.font_name_, newValue) + self.label.setFont_(font) + self.font_size_ = newValue + + font_size = property(fontSizeGetter, fontSizeSetter) + + # # Alignment + def alignmentGetter(self): + return self.alignment_ + + def alignmentSetter(self, newValue): + self.label.setAlignment_(newValue) + self.alignment_ = newValue + + alignment = property(alignmentGetter, alignmentSetter) + + class Button(TouchBarItem): - ''' - A Button is an item that will call an action when tapped - It can shows text, image or both. - - Parameters: - - title (String, optional) : The text that will be shown on the button - - color ( (r, g, b, a) or Color constant, optional) : The background color of the button - - image (String, optional) : The path of the image file that will be shown on the button - - image_position (ImagePosition constant, optional) : The position of the image compared to the text - - image_scale (ImageScale constant) : The image scaling - - action ( function(self) ) : The action that will be called when button is pressed - ''' - - def __init__(self, **kwargs): - self.id = kwargs.get('id', str(uuid.uuid4())) - - self.title_ = kwargs.get('title', None) - self.color_ = kwargs.get('color', None) - - self.image_ = kwargs.get('image',None) - - # Image - if self.image_: - defaultPosition = ImagePosition.left - else: - defaultPosition = ImagePosition.noimage - - self.image_position = kwargs.get('image_position', defaultPosition) - self.image_scale = kwargs.get('image_scale', 0) - - self.actionManager = Action.alloc().init() - self.action = kwargs.get('action', None) - - self.customization_label = kwargs.get('customization_label', 'Button') - self.customization_mode = kwargs.get('customization_mode', 0) - - - - def makeItem(self): - - item = AppKit.NSCustomTouchBarItem.alloc().initWithIdentifier_(self.id) - title = self.title_ if self.title_ else '' - self.button = AppKit.NSButton.buttonWithTitle_target_action_(title, self.actionManager ,"buttonPressed:") - - if self.image_: - image = AppKit.NSImage.alloc().initByReferencingFile_(os.path.realpath(self.image_)) - self.button.setImage_(image) - - self.button.setImagePosition_(self.image_position) - self.button.setImageScaling_(self.image_scale) - - self.button.setIdentifier_(str(id(self))) - main.buttonIds[str(id(self))] = self - - if self.color_: - self.button.setBezelColor_(AppKit.NSColor.colorWithRed_green_blue_alpha_( * self.color_)) - - item.setCustomizationLabel_(self.customization_label) - item.setView_(self.button) - - return item - - # Properties - # # Title - def titleGetter(self): - return self.title_ - - def titleSetter(self, newValue): - self.button.setTitle_(NSString(newValue)) - self.title_ = newValue - - title = property(titleGetter, titleSetter) - - # #Color - def colorGetter(self): - return self.color_ - - def colorSetter(self, newValue): - self.button.setBezelColor_(AppKit.NSColor.colorWithRed_green_blue_alpha_( * newValue)) - self.color_ = newValue - - color = property(colorGetter, colorSetter) - - # #Image - def imageGetter(self): - return self.image_ - - def imageSetter(self, newValue): - image = AppKit.NSImage.alloc().initByReferencingFile_(os.path.realpath(newValue)) - self.button.setImage_(image) - self.image_ = newValue - - image = property(imageGetter, imageSetter) - - + """ + A Button is an item that will call an action when tapped + It can shows text, image or both. + + Parameters: + - title (String, optional) : The text that will be shown on the button + - color ( (r, g, b, a) or Color constant, optional) : The background color of the button + - image (String, optional) : The path of the image file that will be shown on the button + - image_position (ImagePosition constant, optional) : The position of the image compared to the text + - image_scale (ImageScale constant) : The image scaling + - action ( function(self) ) : The action that will be called when button is pressed + """ + + def __init__(self, **kwargs): + self.id = kwargs.get("id", str(uuid.uuid4())) + + self.title_ = kwargs.get("title", None) + self.color_ = kwargs.get("color", None) + + self.image_ = kwargs.get("image", None) + + # Image + if self.image_: + defaultPosition = ImagePosition.left + else: + defaultPosition = ImagePosition.noimage + + self.image_position = kwargs.get("image_position", defaultPosition) + self.image_scale = kwargs.get("image_scale", 0) + + self.actionManager = Action.alloc().init() + self.action = kwargs.get("action", None) + + self.customization_label = kwargs.get("customization_label", "Button") + self.customization_mode = kwargs.get("customization_mode", 0) + + def makeItem(self): + + item = AppKit.NSCustomTouchBarItem.alloc().initWithIdentifier_(self.id) + title = self.title_ if self.title_ else "" + self.button = AppKit.NSButton.buttonWithTitle_target_action_( + title, self.actionManager, "buttonPressed:" + ) + + if self.image_: + image = AppKit.NSImage.alloc().initByReferencingFile_( + os.path.realpath(self.image_) + ) + self.button.setImage_(image) + + self.button.setImagePosition_(self.image_position) + self.button.setImageScaling_(self.image_scale) + + self.button.setIdentifier_(str(id(self))) + main.buttonIds[str(id(self))] = self + + if self.color_: + self.button.setBezelColor_( + AppKit.NSColor.colorWithRed_green_blue_alpha_(*self.color_) + ) + + item.setCustomizationLabel_(self.customization_label) + item.setView_(self.button) + + return item + + # Properties + # # Title + def titleGetter(self): + return self.title_ + + def titleSetter(self, newValue): + self.button.setTitle_(NSString(newValue)) + self.title_ = newValue + + title = property(titleGetter, titleSetter) + + # #Color + def colorGetter(self): + return self.color_ + + def colorSetter(self, newValue): + self.button.setBezelColor_( + AppKit.NSColor.colorWithRed_green_blue_alpha_(*newValue) + ) + self.color_ = newValue + + color = property(colorGetter, colorSetter) + + # #Image + def imageGetter(self): + return self.image_ + + def imageSetter(self, newValue): + image = AppKit.NSImage.alloc().initByReferencingFile_( + os.path.realpath(newValue) + ) + self.button.setImage_(image) + self.image_ = newValue + + image = property(imageGetter, imageSetter) + + class SegmentedControls(TouchBarItem): - ''' - A SegmentedControls item if a group of several buttons that can act one of the folowing way: - - Multiple buttons grouped - - Select one of the buttons - - Select several buttons of the group - It can be populate with strings (which will just act like buttons title), or with - SegmentedControls.Control that allows to create more complex buttons. - - Parameters: - - controls ([String and/or SegmentedControls.Control]) : Controls of the SegmentedControls - - type (SegmentedControls.Type enum constant) : How the SegControls will act (see list up there) - - action ( function(self) ) : Action that will be called when the user press/select a control - - Methods: - - sc.selectedItems() -> [SegmentedControls.Control] : When called, will return the list containing every selected controls - ''' - class Control(object): - ''' - A SegmentedControls.Control] is a SegmentedControls button more complex than just a title. - You can add image to it, change its width and more. - - Parameters: - - title (String, optional) : Text that will be shown on the control - - image (String, optional) : The image file path to show on the button - - width (Int, optional) : The width of the button in pxs - - enabled (Bool) : If False, the button will be grayed out and not clickable - - selected (Bool) : Is the button currently selected? - - image_scale (ImageScale constant) : The image scaling - ''' - - def __init__(self, **kwargs): - self.title_ = kwargs.get('title', 'Control') - imageName = kwargs.get('image', None) - - if imageName: - self.image = AppKit.NSImage.alloc().initByReferencingFile_(os.path.realpath(imageName)) - else: - self.image = None - - self.imageScaling = kwargs.get('image_scale', ImageScale.none) - self.width = kwargs.get('width', None) - self.enabled_ = kwargs.get('enabled', True) - self.selectedBase = kwargs.get('selected', False) - - self.index = -1 - self.segmentedControl = None - - - def isSelected(self): - if self.segmentedControl == None: - raise SystemError("Can't check selection until TouchBar is presented") - else: - return self.segmentedControl.NSSegmentedControl.isSelectedForSegment_(self.index) - - def setSelected(self, status): - if self.segmentedControl == None: - raise SystemError("Can't set selection until TouchBar is presented") - else: - return self.segmentedControl.NSSegmentedControl.setSelected_forSegment_(status, self.index) - - selected = property(isSelected, setSelected) - - def titleGetter(self): - return self.title_ - - def titleSetter(self, newValue): - self.title_ = newValue - if self.segmentedControl: - self.segmentedControl.NSSegmentedControl.setLabel_forSegment_(newValue, self.index) - else: - print ('i') - - title = property(titleGetter, titleSetter) - - def enabledGetter(self): - return self.enabled_ - - def enabledSetter(self, newValue): - self.enabled_ = newValue - if self.segmentedControl: - self.segmentedControl.NSSegmentedControl.setEnabled_forSegment_(newValue, self.index) - - enabled = property(enabledGetter, enabledSetter) - - def __repr__(self): - return (''.format(idx = self.index, title = self.title)) - - - class Type: - ''' How the Seg Controls will act''' - select_one = 0 - select_any = 1 - momentary = 2 - - def __init__(self, controls = ["Segmented","Controls"], **kwargs): - self.id = kwargs.get('id', str(uuid.uuid4())) - - self.controls = controls - self.initializedControls = [] - self.type = kwargs.get('type', SegmentedControls.Type.select_one) - - self.actionManager = Action.alloc().init() - self.action = kwargs.get('action', None) - - self.customization_label = kwargs.get('customization_label', 'Segmented Controls') - self.customization_mode = kwargs.get('customization_mode', 0) - - - - def makeItem(self): - - - customItem = AppKit.NSCustomTouchBarItem.alloc().initWithIdentifier_(self.id) - self.initializedControls = [] - - segmentedControl = AppKit.NSSegmentedControl.segmentedControlWithLabels_trackingMode_target_action_([], self.type, self.actionManager ,"buttonPressed:") - self.NSSegmentedControl = segmentedControl - segmentedControl.setSegmentCount_(len(self.controls)) - - - for idx, control in enumerate(self.controls): - if isinstance(control, SegmentedControls.Control): - self.initializedControls.append(control) - control.index = idx - control.segmentedControl = self - segmentedControl.setLabel_forSegment_(control.title, idx) - - if control.image: - segmentedControl.setImage_forSegment_(control.image, idx) - segmentedControl.setImageScaling_forSegment_(control.imageScaling, idx) - - if control.width: - segmentedControl.setWidth_forSegment_(control.width, idx) - segmentedControl.setEnabled_forSegment_(control.enabled, idx) - segmentedControl.setSelected_forSegment_(control.selectedBase, idx) - - else: - initializedControl = SegmentedControls.Control(title = str(control)) - initializedControl.index = idx - initializedControl.segmentedControl = self - self.initializedControls.append(initializedControl) - - segmentedControl.setLabel_forSegment_(str(control), idx) - - self.controls = self.initializedControls - - - segmentedControl.setIdentifier_(str(id(self))) - main.buttonIds[str(id(self))] = self - customItem.setCustomizationLabel_(self.customization_label) - customItem.setView_(segmentedControl) - - return customItem - - - def selectedItems(self): - for item in self.initializedControls: - if item.selected: - yield item - - - + """ + A SegmentedControls item if a group of several buttons that can act one of the folowing way: + - Multiple buttons grouped + - Select one of the buttons + - Select several buttons of the group + It can be populate with strings (which will just act like buttons title), or with + SegmentedControls.Control that allows to create more complex buttons. + + Parameters: + - controls ([String and/or SegmentedControls.Control]) : Controls of the SegmentedControls + - type (SegmentedControls.Type enum constant) : How the SegControls will act (see list up there) + - action ( function(self) ) : Action that will be called when the user press/select a control + + Methods: + - sc.selectedItems() -> [SegmentedControls.Control] : When called, will return the list containing every selected controls + """ + + class Control(object): + """ + A SegmentedControls.Control] is a SegmentedControls button more complex than just a title. + You can add image to it, change its width and more. + + Parameters: + - title (String, optional) : Text that will be shown on the control + - image (String, optional) : The image file path to show on the button + - width (Int, optional) : The width of the button in pxs + - enabled (Bool) : If False, the button will be grayed out and not clickable + - selected (Bool) : Is the button currently selected? + - image_scale (ImageScale constant) : The image scaling + """ + + def __init__(self, **kwargs): + self.title_ = kwargs.get("title", "Control") + imageName = kwargs.get("image", None) + + if imageName: + self.image = AppKit.NSImage.alloc().initByReferencingFile_( + os.path.realpath(imageName) + ) + else: + self.image = None + + self.imageScaling = kwargs.get("image_scale", ImageScale.none) + self.width = kwargs.get("width", None) + self.enabled_ = kwargs.get("enabled", True) + self.selectedBase = kwargs.get("selected", False) + + self.index = -1 + self.segmentedControl = None + + def isSelected(self): + if self.segmentedControl == None: + raise SystemError("Can't check selection until TouchBar is presented") + else: + return self.segmentedControl.NSSegmentedControl.isSelectedForSegment_( + self.index + ) + + def setSelected(self, status): + if self.segmentedControl == None: + raise SystemError("Can't set selection until TouchBar is presented") + else: + return self.segmentedControl.NSSegmentedControl.setSelected_forSegment_( + status, self.index + ) + + selected = property(isSelected, setSelected) + + def titleGetter(self): + return self.title_ + + def titleSetter(self, newValue): + self.title_ = newValue + if self.segmentedControl: + self.segmentedControl.NSSegmentedControl.setLabel_forSegment_( + newValue, self.index + ) + else: + print("i") + + title = property(titleGetter, titleSetter) + + def enabledGetter(self): + return self.enabled_ + + def enabledSetter(self, newValue): + self.enabled_ = newValue + if self.segmentedControl: + self.segmentedControl.NSSegmentedControl.setEnabled_forSegment_( + newValue, self.index + ) + + enabled = property(enabledGetter, enabledSetter) + + def __repr__(self): + return ''.format( + idx=self.index, title=self.title + ) + + class Type: + """How the Seg Controls will act""" + + select_one = 0 + select_any = 1 + momentary = 2 + + def __init__(self, controls=["Segmented", "Controls"], **kwargs): + self.id = kwargs.get("id", str(uuid.uuid4())) + + self.controls = controls + self.initializedControls = [] + self.type = kwargs.get("type", SegmentedControls.Type.select_one) + + self.actionManager = Action.alloc().init() + self.action = kwargs.get("action", None) + + self.customization_label = kwargs.get( + "customization_label", "Segmented Controls" + ) + self.customization_mode = kwargs.get("customization_mode", 0) + + def makeItem(self): + + customItem = AppKit.NSCustomTouchBarItem.alloc().initWithIdentifier_(self.id) + self.initializedControls = [] + + segmentedControl = AppKit.NSSegmentedControl.segmentedControlWithLabels_trackingMode_target_action_( + [], self.type, self.actionManager, "buttonPressed:" + ) + self.NSSegmentedControl = segmentedControl + segmentedControl.setSegmentCount_(len(self.controls)) + + for idx, control in enumerate(self.controls): + if isinstance(control, SegmentedControls.Control): + self.initializedControls.append(control) + control.index = idx + control.segmentedControl = self + segmentedControl.setLabel_forSegment_(control.title, idx) + + if control.image: + segmentedControl.setImage_forSegment_(control.image, idx) + segmentedControl.setImageScaling_forSegment_( + control.imageScaling, idx + ) + + if control.width: + segmentedControl.setWidth_forSegment_(control.width, idx) + segmentedControl.setEnabled_forSegment_(control.enabled, idx) + segmentedControl.setSelected_forSegment_(control.selectedBase, idx) + + else: + initializedControl = SegmentedControls.Control(title=str(control)) + initializedControl.index = idx + initializedControl.segmentedControl = self + self.initializedControls.append(initializedControl) + + segmentedControl.setLabel_forSegment_(str(control), idx) + + self.controls = self.initializedControls + + segmentedControl.setIdentifier_(str(id(self))) + main.buttonIds[str(id(self))] = self + customItem.setCustomizationLabel_(self.customization_label) + customItem.setView_(segmentedControl) + + return customItem + + def selectedItems(self): + for item in self.initializedControls: + if item.selected: + yield item + + class ColorPicker(TouchBarItem): - ''' - A ColorPicker item is a button that when it is pressed, will display a color selector in the touchbar. - It is used in Word or Pages to set font color for example - - Parameters: - - alpha (Bool) : If True, user can change r, g, b AND alpha value. If False, just r, g, b. - - type (ColorPicker.Type constant) : The style of the ColorPicker button - - image (string) : If type == Type.image, the button will present an image, the path of its file is this parameter. - - action ( function(self) ) : A method that will be called when user change the color value - - color ( (r, g, b, a) or Color constant) : The current color of the picker. - ''' - - class Type: - ''' The style of the ColorPicker button''' - color = 0 - text = 1 - stroke = 2 - image = 3 - - - def __init__(self, **kwargs): - self.id = kwargs.get('id', str(uuid.uuid4())) - - self.alpha = kwargs.get('alpha', False) - self.type = kwargs.get('type', ColorPicker.Type.color) - - self.image = kwargs.get('image', None) - - self.actionManager = Action.alloc().init() - self.actionManager.__dict__ - self.action = kwargs.get('action', None) - - self.customization_label = kwargs.get('customization_label', 'Color Picker') - self.customization_mode = kwargs.get('customization_mode', 0) - - - - - def makeItem(self): - - - try: - self.item - except: - if self.type == ColorPicker.Type.color: - self.item = AppKit.NSColorPickerTouchBarItem.colorPickerWithIdentifier_(self.id) - elif self.type == ColorPicker.Type.text: - self.item = AppKit.NSColorPickerTouchBarItem.textColorPickerWithIdentifier_(self.id) - elif self.type == ColorPicker.Type.stroke: - self.item = AppKit.NSColorPickerTouchBarItem.strokeColorPickerWithIdentifier_(self.id) - elif self.type == ColorPicker.Type.image: - image = AppKit.NSImage.alloc().initByReferencingFile_(os.path.realpath(self.image)) - self.item = AppKit.NSColorPickerTouchBarItem.colorPickerWithIdentifier_buttonImage_(self.id, image) - - - self.item.setShowsAlpha_(self.alpha) - - self.item.setTarget_(self.actionManager) - self.item.setAction_("buttonPressed:") - - main.buttonIds[self.id] = self - - self.item.setCustomizationLabel_(self.customization_label) - - return self.item - - def getColor(self): - color = self.item.color() - alpha = color.alphaComponent() - red = color.redComponent() - green = color.greenComponent() - blue = color.blueComponent() - return (red, green, blue, alpha) - - def setColor(self, color): - color = AppKit.NSColor.NSColor.colorWithRed_green_blue_alpha_( * color) - self.item.setColor_(color) - - color = property(getColor, setColor) - - - + """ + A ColorPicker item is a button that when it is pressed, will display a color selector in the touchbar. + It is used in Word or Pages to set font color for example + + Parameters: + - alpha (Bool) : If True, user can change r, g, b AND alpha value. If False, just r, g, b. + - type (ColorPicker.Type constant) : The style of the ColorPicker button + - image (string) : If type == Type.image, the button will present an image, the path of its file is this parameter. + - action ( function(self) ) : A method that will be called when user change the color value + - color ( (r, g, b, a) or Color constant) : The current color of the picker. + """ + + class Type: + """The style of the ColorPicker button""" + + color = 0 + text = 1 + stroke = 2 + image = 3 + + def __init__(self, **kwargs): + self.id = kwargs.get("id", str(uuid.uuid4())) + + self.alpha = kwargs.get("alpha", False) + self.type = kwargs.get("type", ColorPicker.Type.color) + + self.image = kwargs.get("image", None) + + self.actionManager = Action.alloc().init() + self.actionManager.__dict__ + self.action = kwargs.get("action", None) + + self.customization_label = kwargs.get("customization_label", "Color Picker") + self.customization_mode = kwargs.get("customization_mode", 0) + + def makeItem(self): + + try: + self.item + except: + if self.type == ColorPicker.Type.color: + self.item = AppKit.NSColorPickerTouchBarItem.colorPickerWithIdentifier_( + self.id + ) + elif self.type == ColorPicker.Type.text: + self.item = ( + AppKit.NSColorPickerTouchBarItem.textColorPickerWithIdentifier_( + self.id + ) + ) + elif self.type == ColorPicker.Type.stroke: + self.item = ( + AppKit.NSColorPickerTouchBarItem.strokeColorPickerWithIdentifier_( + self.id + ) + ) + elif self.type == ColorPicker.Type.image: + image = AppKit.NSImage.alloc().initByReferencingFile_( + os.path.realpath(self.image) + ) + self.item = AppKit.NSColorPickerTouchBarItem.colorPickerWithIdentifier_buttonImage_( + self.id, image + ) + + self.item.setShowsAlpha_(self.alpha) + + self.item.setTarget_(self.actionManager) + self.item.setAction_("buttonPressed:") + + main.buttonIds[self.id] = self + + self.item.setCustomizationLabel_(self.customization_label) + + return self.item + + def getColor(self): + color = self.item.color() + alpha = color.alphaComponent() + red = color.redComponent() + green = color.greenComponent() + blue = color.blueComponent() + return (red, green, blue, alpha) + + def setColor(self, color): + color = AppKit.NSColor.NSColor.colorWithRed_green_blue_alpha_(*color) + self.item.setColor_(color) + + color = property(getColor, setColor) + + class Slider(TouchBarItem): - ''' - A Slider is an item that will allows the user to change a number value by dragging a control over the touchbar. - - Parameters: - - title (String, optional) : A text that will be presented next to the slider - - value (Float) : The value of the slider, between 0 and 1 - - color ( (r, g, b, a) or Color constant, optional) : The tint color of the slider - - action ( function(self) ) : The function that will be called when the user change the value of the slider - ''' - def __init__(self, **kwargs): - self.id = kwargs.get('id', str(uuid.uuid4())) - self.makeNumber = 0 - - self.title = kwargs.get('title', '') - - self.actionManager = Action.alloc().init() - self.actionManager.__dict__ - self.action = kwargs.get('action', None) - self.defaultValue = kwargs.get('value',0.5) - - self.color = kwargs.get('color', None) - - self.item = AppKit.NSSliderTouchBarItem.alloc().initWithIdentifier_(self.id) - - self.customization_label = kwargs.get('customization_label', 'Slider') - self.customization_mode = kwargs.get('customization_mode', 0) - - - - def makeItem(self): - - self.makeNumber += 1 - if self.makeNumber == 1: - self.setValue(self.defaultValue) - - if self.color: - self.item.slider().setTrackFillColor_(AppKit.NSColor.colorWithRed_green_blue_alpha_( * self.color)) - - self.item.setTarget_(self.actionManager) - self.item.setAction_("buttonPressed:") - self.item.setLabel_(self.title) - - self.item.slider().setMinValue_(0) - self.item.slider().setMaxValue_(1) - - - self.item.slider().setIdentifier_(str(id(self))) - main.buttonIds[str(id(self))] = self - - self.item.setCustomizationLabel_(self.customization_label) - return self.item - - def getValue(self): - return float(self.item.slider().doubleValue()) - - def setValue(self, value): - self.item.slider().setDoubleValue_(float(value)) - - value = property(getValue, setValue) - - - + """ + A Slider is an item that will allows the user to change a number value by dragging a control over the touchbar. + + Parameters: + - title (String, optional) : A text that will be presented next to the slider + - value (Float) : The value of the slider, between 0 and 1 + - color ( (r, g, b, a) or Color constant, optional) : The tint color of the slider + - action ( function(self) ) : The function that will be called when the user change the value of the slider + """ + + def __init__(self, **kwargs): + self.id = kwargs.get("id", str(uuid.uuid4())) + self.makeNumber = 0 + + self.title = kwargs.get("title", "") + + self.actionManager = Action.alloc().init() + self.actionManager.__dict__ + self.action = kwargs.get("action", None) + self.defaultValue = kwargs.get("value", 0.5) + + self.color = kwargs.get("color", None) + + self.item = AppKit.NSSliderTouchBarItem.alloc().initWithIdentifier_(self.id) + + self.customization_label = kwargs.get("customization_label", "Slider") + self.customization_mode = kwargs.get("customization_mode", 0) + + def makeItem(self): + + self.makeNumber += 1 + if self.makeNumber == 1: + self.setValue(self.defaultValue) + + if self.color: + self.item.slider().setTrackFillColor_( + AppKit.NSColor.colorWithRed_green_blue_alpha_(*self.color) + ) + + self.item.setTarget_(self.actionManager) + self.item.setAction_("buttonPressed:") + self.item.setLabel_(self.title) + + self.item.slider().setMinValue_(0) + self.item.slider().setMaxValue_(1) + + self.item.slider().setIdentifier_(str(id(self))) + main.buttonIds[str(id(self))] = self + + self.item.setCustomizationLabel_(self.customization_label) + return self.item + + def getValue(self): + return float(self.item.slider().doubleValue()) + + def setValue(self, value): + self.item.slider().setDoubleValue_(float(value)) + + value = property(getValue, setValue) + + class Stepper(TouchBarItem): - ''' - A stepper is an item that will allow the user to select a numeric value between specified min and max. - If will contain a label showing the current value, and two buttons + and - to change the value from specified step. - - Parameters: - - value (int) : Value of the stepper - - min (int) : Minimum value - - max (int) : Maximum value - - step (int) : Increment step - - action ( function(self) ) : The function that will be called when the user change the value of the stepper - ''' - def __init__(self, **kwargs): - self.id = kwargs.get('id', str(uuid.uuid4())) - - self.actionManager = Action.alloc().init() - self.actionManager.__dict__ - self.action = kwargs.get('action', None) - - self.defaultValue = kwargs.get('value', 5) - self.defaultMin = kwargs.get('min', 0) - self.defaultMax = kwargs.get('max', 10) - self.defaultStep = kwargs.get('step', 1) - - self.item = AppKit.NSStepperTouchBarItem.alloc().initWithIdentifier_(self.id) - self.item.setValue_(float(self.defaultValue)) - self.item.setMinValue_(self.defaultMin) - self.item.setMaxValue_(self.defaultMax) - self.item.setIncrement_(self.defaultStep) - - self.customization_label = kwargs.get('customization_label', 'Stepper') - self.customization_mode = kwargs.get('customization_mode', 0) - - - - def makeItem(self): - - - self.item.setTarget_(self.actionManager) - self.item.setAction_("buttonPressed:") - - main.buttonIds[self.id] = self - - self.item.setCustomizationLabel_(self.customization_label) - return self.item - - - # Properties - # # Value - def getValue(self): - return float(self.item.value()) - - def setValue(self, value): - self.item.setValue_(float(value)) - - value = property(getValue, setValue) - - # # Max - def getMax(self): - return float(self.item.maxValue()) - - def setMax(self, value): - self.item.setMaxValue_(float(value)) - - max = property(getMax, setMax) - - # # Min - def getMin(self): - return float(self.item.minValue()) - - def setMin(self, value): - self.item.setMinValue_(float(value)) - - min = property(getMin, setMin) - - # # Step - def getStep(self): - return float(self.item.increment()) - - def setStep(self, value): - self.item.setIncrement_(float(value)) - - step = property(getStep, setStep) \ No newline at end of file + """ + A stepper is an item that will allow the user to select a numeric value between specified min and max. + If will contain a label showing the current value, and two buttons + and - to change the value from specified step. + + Parameters: + - value (int) : Value of the stepper + - min (int) : Minimum value + - max (int) : Maximum value + - step (int) : Increment step + - action ( function(self) ) : The function that will be called when the user change the value of the stepper + """ + + def __init__(self, **kwargs): + self.id = kwargs.get("id", str(uuid.uuid4())) + + self.actionManager = Action.alloc().init() + self.actionManager.__dict__ + self.action = kwargs.get("action", None) + + self.defaultValue = kwargs.get("value", 5) + self.defaultMin = kwargs.get("min", 0) + self.defaultMax = kwargs.get("max", 10) + self.defaultStep = kwargs.get("step", 1) + + self.item = AppKit.NSStepperTouchBarItem.alloc().initWithIdentifier_(self.id) + self.item.setValue_(float(self.defaultValue)) + self.item.setMinValue_(self.defaultMin) + self.item.setMaxValue_(self.defaultMax) + self.item.setIncrement_(self.defaultStep) + + self.customization_label = kwargs.get("customization_label", "Stepper") + self.customization_mode = kwargs.get("customization_mode", 0) + + def makeItem(self): + + self.item.setTarget_(self.actionManager) + self.item.setAction_("buttonPressed:") + + main.buttonIds[self.id] = self + + self.item.setCustomizationLabel_(self.customization_label) + return self.item + + # Properties + # # Value + def getValue(self): + return float(self.item.value()) + + def setValue(self, value): + self.item.setValue_(float(value)) + + value = property(getValue, setValue) + + # # Max + def getMax(self): + return float(self.item.maxValue()) + + def setMax(self, value): + self.item.setMaxValue_(float(value)) + + max = property(getMax, setMax) + + # # Min + def getMin(self): + return float(self.item.minValue()) + + def setMin(self, value): + self.item.setMinValue_(float(value)) + + min = property(getMin, setMin) + + # # Step + def getStep(self): + return float(self.item.increment()) + + def setStep(self, value): + self.item.setIncrement_(float(value)) + + step = property(getStep, setStep) diff --git a/README.md b/README.md index ec77508..2834700 100755 --- a/README.md +++ b/README.md @@ -1,34 +1,43 @@ # PyTouchBar -A NSTouchBar Wrapper for Python. It only works (for the moment) with Tkinter and PyGame.
-It mainly depends on PyObjc to wrap NSTouchBar and related classes.
-It also includes a wrapper to the haptic trackpad, allowing your Python program to trigger trackpad vibrations.
-Note: It will (of course) only works on MacBook Pro with TouchBars, or on a TouchBar Simulator (you have a good one here.) - -## What's new -#### 0.2.0: - -* Add user-customization of the TouchBar -* Best error managment -* New Stepper item (macOS 10.15 +) -* Add escape key modification + +A `NSTouchBar` wrapper for Python. It currently works with Tkinter and PyGame. + +This library depends on `PyObjC` to wrap `NSTouchBar` and related classes. It also includes a wrapper for the haptic trackpad, allowing your Python programs to trigger trackpad vibrations. + +**Note:** This will only work on MacBook Pro with TouchBars, or on a TouchBar Simulator ([you have a good one here](https://github.com/sindresorhus/touch-bar-simulator)). + +## What's New + +### 0.3.1 +* Upgraded dependencies +* Fixed some typos + +### 0.2.0 + +* Added user-customization of the TouchBar +* Better error management +* New Stepper item (macOS 10.15+) +* Added escape key modification * Improved file structure of the module ## Installation -To install PyTouchBar, just copy-paste the following command into a terminal: +To install PyTouchBar, run the following command: - pip install PyTouchBar +```bash +pip install PyTouchBar +``` ## Example -Here is a simple example displaying a window with a label, and displaying a button in the touchbar. +Here is a simple example displaying a window with a label and a button in the TouchBar. ```python from tkinter import * import PyTouchBar root = Tk() -PyTouchBar.prepare_tk_windows(root) # Tell PyTouchBar that the "root" window will have a TouchBar +PyTouchBar.prepare_tk_windows(root) # Tell PyTouchBar that the "root" window will have a TouchBar # Build Tkinter interface lbl = Label(root, text="Hello World") @@ -36,7 +45,7 @@ lbl.pack() # Build TouchBar def action(button): - print ("Button Pressed !") + print("Button Pressed!") btn = PyTouchBar.items.Button(title="Button", action=action) PyTouchBar.set_touchbar([btn]) @@ -45,22 +54,21 @@ PyTouchBar.set_touchbar([btn]) root.mainloop() ``` -## How to Use -All documentation is included in the wiki - - - * Integrate into your project - * Add items in TouchBar - - Spaces - - Labels - - Buttons - - Color Picker - - Slider - - Stepper - - Segmented Controls - - Popover - * Constants - * Change esc key - * User Customization - * Haptic Feedback - +## Documentation + +All documentation is available in the [wiki](https://github.com/Maxmad68/PyTouchBar/wiki): + +* [Integrate into your project](https://github.com/Maxmad68/PyTouchBar/wiki/Integrate-into-your-project) +* [Add items to TouchBar](https://github.com/Maxmad68/PyTouchBar/wiki/Populate-TouchBar) + - [Spaces](https://github.com/Maxmad68/PyTouchBar/wiki/Populate-TouchBar#Spaces) + - [Labels](https://github.com/Maxmad68/PyTouchBar/wiki/Populate-TouchBar#Label) + - [Buttons](https://github.com/Maxmad68/PyTouchBar/wiki/Populate-TouchBar#Button) + - [Color Picker](https://github.com/Maxmad68/PyTouchBar/wiki/Populate-TouchBar#ColorPicker) + - [Slider](https://github.com/Maxmad68/PyTouchBar/wiki/Populate-TouchBar#Slider) + - [Stepper](https://github.com/Maxmad68/PyTouchBar/wiki/Populate-TouchBar#Stepper) + - [Segmented Controls](https://github.com/Maxmad68/PyTouchBar/wiki/Populate-TouchBar#SegmentedControls) + - [Popover](https://github.com/Maxmad68/PyTouchBar/wiki/Populate-TouchBar#Popover) +* [Constants](https://github.com/Maxmad68/PyTouchBar/wiki/Constants) +* [Change Escape key](https://github.com/Maxmad68/PyTouchBar/wiki/Set-Escape-Key) +* [User Customization](https://github.com/Maxmad68/PyTouchBar/wiki/User-customization) +* [Haptic Feedback](https://github.com/Maxmad68/PyTouchBar/wiki/Haptic-Feedback) diff --git a/setup.py b/setup.py index aaa41c0..23169dc 100755 --- a/setup.py +++ b/setup.py @@ -2,9 +2,9 @@ setuptools.setup( name="PyTouchBar", - version="0.2.1", - author="Maxmad68", - author_email="maxime@madrau.fr", + version="0.3.1", + author="Maxmad68, Emilio Dalla Torre", + author_email="maxime@madrau.fr, info@emiliodallatorre.it", description="Use MacBook Pro's TouchBar in Python", long_description="Use MacBook Pro's TouchBar in Python. PyTouchBar make easy the use of the TouchBar with Python graphical modules Tkinter and Pygame (other are coming). Currently works with Buttons, Labels, Sliders, Steppers, ColorPickers, Popovers, Segmented Controls and Spaces.\nSee my Github for docs", long_description_content_type="text/markdown",