napari / napari-core

BSD 3-Clause "New" or "Revised" License
5 stars 3 forks source link

API Design & Hierarchy #15

Open kne42 opened 6 years ago

kne42 commented 6 years ago

I'd like to hear y'all's opinions on how the API is designed in terms of user accessibility (i.e. how we expose the customization of windows/toolsbars/menus/whatnot) and general hierarchy (the submodule tree).

kne42 commented 6 years ago

Since I am an Emacs user, I'm biased towards how they do things, and would like to see our API designed similarly to theirs. However, I will also note that Emacs is still one of the most popular text editors out there despite minimal changes to its infrastructure since it was released a little over 35 years ago due to how customizable and well-designed it was.

At its core, Emacs is a minimalistic, highly customizable text editor. It doesn't have all of the features, nor does it try to. It's elegant, fast, lightweight, and beautiful. It's everything that Napari strives to be.

So here I'll attempt to explain some core Emacs features and how they can translate to Napari:

buffer This is a working space which contains data. It can be displayed in a window, in a sub-pane of window, or it can be hidden/replaced with another buffer. How it is rendered depends on the major mode, which will be explained below. Example: A small file's data is loaded into a buffer. A large file's path is loaded into a buffer. A settings configuration file is loaded into a buffer.

major mode This controls how you interact with a buffer. It determines how a buffer is rendered, provides some default functions and keybindings for them, etc. You can only have one major mode per buffer. Example: A buffer containing 3D data is assigned a volume renderer major mode. A buffer containing 2D data is assigned a normal image renderer major mode. A buffer pointing to a large image file is rendered with a streaming major mode. A settings.json file is rendered using a settings major mode.

hook This is a list of callbacks that are executed at specific timings in a function. Example: A startup file is set to be read on application startup by adding the reading function for it to the startup hook. A tiff major mode is set to activate when a file is opened by matching the *.tiff pattern.

minor mode This is a collection of functions/variables/keybindings/code that is activated by enabling the minor mode. In Python terms, this is effectively a module. Minor modes can be enabled globally by adding them to the buffer creation hook. Example: A plugin to manage/move around windows and their panes is a minor mode. A plugin to enable typing unicode characters via keybindings is a minor mode. Autocomplete is a minor mode, etc.


As for hierarchy, I'd like to see the base backend/gui/whatnot go under a core second-level package and then everything to do with customizing/interfacing with said gui get sorted into their own second-level packages appropriately.