Skip to content
This repository was archived by the owner on Mar 30, 2023. It is now read-only.

Commit ef6beef

Browse files
committed
flesh out view docs in getting started tutorial
1 parent 73a8db2 commit ef6beef

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

README.md

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
Taktil
2-
==========================
1+
# Taktil
32

43
[![Build Status](https://travis-ci.org/taktiljs/taktil.svg?branch=master)](https://travis-ci.org/taktiljs/taktil) [![npm version](https://badge.fury.io/js/taktil.svg)](https://badge.fury.io/js/taktil)
54

@@ -24,8 +23,7 @@ $ npm install -g taktil
2423

2524
> **Note:** Don't miss the `-g` flag here as this installs the package globally, adding the the `taktil` command to your path.
2625
27-
28-
If you'd rather use Taktil without the CLI, you can install it locally into an existing project like so:
26+
If you'd rather use Taktil without the CLI, you can manually install it locally into an existing project like so:
2927

3028
```bash
3129
$ npm install taktil
@@ -49,7 +47,7 @@ Display Name: Getting Started
4947
Vendor/Category: Custom
5048
Version (1.0.0):
5149
Author: Joseph Larson
52-
API Version (2): 4
50+
API Version (4):
5351
[taktil] project initialization complete.
5452
```
5553

@@ -179,7 +177,7 @@ With that, we've defined our controls.
179177

180178
## Creating Components
181179

182-
Now that we've defined our controls, we'll move on to building some reusable components. Components, in Taktil, are the state and business logic containers for non-hardware-specific functionality. They receive and react to standardized `ControlInput` messages (through the `onControlInput` method) as well as Bitwig API events. They also decide when a connected `Control` should be updated by calling its `setState` method, usually in reaction to on of the above mentioned messages or events.
180+
Now that we've defined our controls, we'll move on to building some components. Components, in Taktil, are the state and business logic containers for non-hardware-specific functionality. They receive and react to standardized `ControlInput` messages (through the `onControlInput` method) as well as Bitwig API events. They also decide when a connected `Control` should be updated by calling its `setState` method, usually in reaction to on of the above mentioned messages or events.
183181

184182
Controls convert Midi input messages into standardized `ControlInput` messages. These messages are sent on to a connected component through the component's `onControlInput` method. In this way, each component definition is able to uniquely define how this input will be handled and when and how a control's state will be modified.
185183

@@ -320,9 +318,17 @@ export const daw = new Daw();
320318
```
321319

322320

323-
## Constructing Views
321+
## Assembling the Views
322+
323+
Now that we've defined our controls and and components, it's time to assemble them into views. I their simplest form, views are just a mapping of components to controls. When a view is active, the view's components will receive control input and generate control output. An inactive view's components, on the other hand, will not be sent control input messages, and will not generate any control output, but they will continue to maintain their internal state in preparation for being activated.
324+
325+
View components are also registered to a specific view "mode" and will only be considered active if both the view and the mode are active. Taktil maintains the array of active mode strings globally. These modes are kept in the order they were activated such that a component registered to the same control but a different mode can override the another, with the most recently activated mode taking precedence. This allows a view to configure itself differently based on the global mode list. This is useful, for instance, when implementing a shift button, where having all views know our script is in "shift mode" will allow us to define secondary actions across multiple disconnected views.
326+
327+
Views are defined by extending Taktil's View class or by stacking previously defined views using the ViewStack function. The ViewStack function accepts a list of view classes and returns a new View class definition where, in order, each of the provided views' component/control mappings override any subsequent view's mapping involving the same control (it's just simple inheritance where the the control portion of each mapping is the thing being overridden). This pattern makes it possible to define reusable chunks of view logic which can be combined together in different ways to create more complex views.
324328

325-
Components are instantiated as members of a `View` definition providing a corresponding control and a params object.
329+
In a simple project, a single view making use of view modes may be enough handle your needs. The value of view stacks will become apparent when developing more complex projects.
330+
331+
As shown below, the component/control mappings are defined as instance properties. Valid instance property types consist of a component instance, an array of component instances, or a function that returns either of the previous. Component constructors take a control instance and a params object. The params object consists of an optional mode property—for defining which mode the component should be registered to—as well as whatever else the individual component needs to operate. This is generally where we will pass in objects retrieved or created through Bitwig's API as the view instance code will not be run until after the init phase.
326332

327333
```js
328334
// src/views.js
@@ -333,33 +339,49 @@ import { PlayToggle, ModeGate, MetronomeToggle, VolumeRange } from './components
333339
import { controls } from './controls';
334340
import { daw } from './daw';
335341

342+
// in this view when you press the SHIFT button the PLAY button will toggle the metronome on/off
343+
// but when the SHIFT button is released, the PLAY button will toggle the transport's play state
336344
class BaseView extends View {
345+
// map PlayToggle component to the PLAY control, registering it to the default base mode
337346
playToggle = new PlayToggle(controls.PLAY, { transport: daw.transport });
347+
// map ModeGate component to the SHIFT control, registering it to the default base mode
338348
shiftModeGate = new ModeGate(controls.SHIFT, { target: 'SHIFT' });
349+
// map MetronomeToggle component to the PLAY control, registering it to our custom 'SHIFT' mode
339350
metroToggle = new MetronomeToggle(controls.PLAY, { mode: 'SHIFT', transport: daw.transport });
340351
}
341352

342353
class MixerView extends View {
354+
// map VolumeRange component to the KNOB control, registering it the default base mode
343355
masterVolume = new VolumeRange(controls.KNOB, { track: daw.masterTrack });
344356
}
345357

358+
// export the view name to view class mapping so that we can register these views to
359+
// the session to be activated by name
346360
export const views = {
347361
BASE: BaseView,
362+
// by stacking these views, all components in MixerView that are connected to an active mode
363+
// will be active and any components in BaseView that are connected to an active mode will
364+
// be active as long as their connected controls do not conflict with any active component
365+
// in the MixerView.
348366
MIXER: ViewStack(MixerView, BaseView),
349367
};
350368
```
351369

352370

353-
## Assembling the Session
371+
## Initializing the Session
372+
373+
At this point we've defined our control layer, created some components, and assembled those controls and components into views. Now all that's left is to create our controller script's entry point where we will initialize our session.
354374

355375
```js
376+
// src/index.js
377+
356378
import taktil from 'taktil';
357379

358380
import { controls } from './controls';
359381
import { views } from './views';
360382

361383
// 1. set bitwig api version
362-
host.loadAPI(3);
384+
host.loadAPI(4);
363385

364386
// 2. define controller script
365387
host.defineController(
@@ -385,5 +407,4 @@ taktil.registerViews(views);
385407

386408
// 6. on init, activate view to trigger initial render
387409
taktil.on('init', () => taktil.activateView('BASE'));
388-
389410
```

0 commit comments

Comments
 (0)