Karya, built on 2018-05-31T02:46:59 (patch 0a1a35479c514820d77330ae8a978975ba22a47a)

Safe HaskellNone




Cmds to create and destroy blocks, views, tracks, and rulers.

IDs are automatically created from the state_namespace and the other IDs in existence. In general I think it's a bad idea to try to hard to give IDs descriptive names because there's nothing keeping them that way. The description should be in the track title. Even the given numbers will get out of date with their position in the block.

However, I do allow some naming beyond simple numbers for things which are unlikely to change, like tempo tracks and rulers, which don't have any other title. And block IDs are used by the sub-derive mechanism, so those should be nameable.


global modifications

rename_project :: Ui.M m => Id.Namespace -> m () Source #

Set the project to the given value and renamespace the old project to the new one. Cmd.state_save_file is not modified, so it will keep saving to the old save file.

renamespace :: Ui.M m => Id.Namespace -> Id.Namespace -> m () Source #

Rename all IDs in namespace from to to.

rename_rulers :: Ui.M m => [(Id.RulerId, Id.Id)] -> m () Source #

Rename multiple RulerIds at once. This can swap two IDs without colliding.

copy_block :: Ui.M m => Id.BlockId -> Id.Id -> m () Source #

orphan_tracks :: Ui.M m => m (Set Id.TrackId) Source #

Find tracks which are not found in any block. Probably used to pass them to Ui.destroy_track for "gc".

orphan_track :: Ui.M m => Id.TrackId -> m Bool Source #

Like orphan_tracks but more efficiently check if a single track is an orphan.

orphan_rulers :: Ui.M m => m [Id.RulerId] Source #

Find rulers which are not found in any block.

orphan_blocks :: Ui.M m => m [Id.BlockId] Source #

Find blocks with no associated views.

map_track_titles :: Ui.M m => (Text -> Text) -> m () Source #

Modify track titles with a function.

TODO this is inadequate. I need a function to get parsed inst and control track titles separately. Use TrackTree.track_tree_of to figure inst vs. control.


named_block_from_template Source #


:: Ui.M m 
=> Bool

copy the events

-> Id.BlockId 
-> Id.Id 
-> m Id.BlockId 

Create a block which is a copy of another.

block :: Ui.M m => Id.RulerId -> m Id.BlockId Source #

BlockIds look like ns/b1, ns/b2, etc.

sub_block :: Ui.M m => Maybe Id.BlockId -> Id.RulerId -> m Id.BlockId Source #

Create a block whose BlockId is prefixed by another: ns/parent.b1. The relative block call mechanism supported by the default block call means you can call it from the parent by just writing .b1.

named_block :: Ui.M m => Id.Id -> Id.RulerId -> m Id.BlockId Source #

Create a block with the given ID name. Useful for blocks meant to be sub-derived. If the name doesn't contain a /, it gets the current namespace.

destroy_block :: Ui.M m => Id.BlockId -> m () Source #

Delete a block and any views it appears in. Also delete any tracks that only appeared in that block.



unfitted_view :: Ui.M m => Id.BlockId -> m Id.ViewId Source #

Create a view with the default dimensions.

view :: Cmd.M m => Id.BlockId -> m Id.ViewId Source #

This is like unfitted_view, but tries to fit the view size to its contents.

It's in Cmd.M since it needs the screen dimensions.

Views created during setup are likely to not have the correct height. That's because I haven't received the screen resolution from fltk yet so I make a guess in Cmd.get_screen.

view_or_focus Source #


:: Cmd.M m 
=> Id.BlockId 
-> m (Maybe Id.ViewId)

Just ViewId if a new one was created.

Create a view, or focus on it if it already exists.

generate_view_id :: Id.BlockId -> Map Id.ViewId _a -> Maybe Id.Id Source #

ViewIds look like "nsb0.v0", "nsb0.v1", etc.

destroy_view :: Ui.M m => Id.ViewId -> m () Source #

Destroy a view, along with the underlying block if there were no other views.


splice_below :: Cmd.M m => m Id.TrackId Source #

Create a track and splice it below the current one. The track will be inserted to the right of the selected track.

splice_above_ancestors :: Cmd.M m => m Id.TrackId Source #

Get the ancestors (topmost parents) of the selected tracks and create a parent track to them. It will be inserted to the left of the leftmost ancestor.

insert_branch_from :: Cmd.M m => Id.BlockId -> Types.TrackNum -> m () Source #

Insert tracks using the given one and its children as a template. The effect is to copy the branch below the selection.

assign_tracknums :: Types.TrackNum -> TrackTree.TrackTree -> [Tree.Tree (Types.TrackNum, Text)] Source #

Assign ascending tracknums to the given tree in depth-first order. Return (tracknum, title) pairs.

insert_track_right :: Cmd.M m => m Id.TrackId Source #

Insert a track after the selection, or just append one if there isn't one. This is useful for empty blocks which of course have no selection.

focused_track :: Cmd.M m => Types.TrackNum -> m Id.TrackId Source #

Add a new track, and widen the view to make sure it's visible. Give keyboard focus to the title.

widen :: Ui.M m => Id.ViewId -> m () Source #

Expand the view horizontally to to fit all tracks.

track :: Ui.M m => Id.BlockId -> Types.TrackNum -> Text -> Events.Events -> m Id.TrackId Source #

Like track_events, but copy the ruler from the track to the left.

track_events :: Ui.M m => Id.BlockId -> Id.RulerId -> Types.TrackNum -> Types.Width -> Track.Track -> m Id.TrackId Source #

Lowest level track creator. The new TrackId will be in the same namespace as the given BlockId.

named_track :: Ui.M m => Id.BlockId -> Id.RulerId -> Types.TrackNum -> Text -> Track.Track -> m Id.TrackId Source #

Create a track with the given name, in the same namespace as the BlockId.

destroy_track :: Ui.M m => Id.BlockId -> Types.TrackNum -> m () Source #

Remove a track from a block. If that was the only block it appeared in, delete the underlying track. Rulers are never deleted automatically.

swap_tracks :: Ui.M m => Id.BlockId -> Types.TrackNum -> Types.TrackNum -> m () Source #

Swap the tracks at the given tracknums. If one of the tracknums is out of range, the track at the other tracknum will be moved to the beginning or end, i.e. swapped with empty space.


clip_tracknum :: Ui.M m => Id.BlockId -> Types.TrackNum -> m Types.TrackNum Source #

Clip the tracknum to within the valid range.

track_after :: Block.Block -> Types.TrackNum -> Types.TrackNum Source #

Get the track to the right of the given tracknum. This isn't just (+1) because it skips collapsed tracks.


ruler :: Ui.M m => Text -> Ruler.Ruler -> m Id.RulerId Source #

Create a ruler with the given name.

new_ruler :: Ui.M m => Id.BlockId -> Text -> Ruler.Ruler -> m Id.RulerId Source #

Set a block to a new ruler.

general util

generate_id :: Ord a => Id.Namespace -> Id.Id -> Text -> (Id.Id -> a) -> Map a _b -> Maybe Id.Id Source #

ids_for :: Id.Namespace -> Text -> Text -> [Id.Id] Source #

IDs are numbered, and they start at 1 instead of 0.

This is because usually tracknum 0 is the ruler, so counting with tracknums, event tracks start at 1. The actual TrackId should be irrelevant (and would be out of date as soon as a track is swapped), but for testing it's very convenient if they line up with the tracknums. So even though it's purely for testing and only for TrackIds, I start everything at 1 just for consistency.

require_id :: Ui.M m => Text -> Maybe a -> m a Source #

find_rect :: Maybe Rect.Rect -> (Int, Int) -> [Rect.Rect] -> (Int, Int) Source #

Find a place to fit the given rect. This is like a tiny window manager.