A tabstrip contraption
I have a card that calculates some data, and displays it in various ways. Rather than have multiple cards that do the same calculation, I figured I’d have all of the views on the same card, and add a tabstrip to switch which ones were visible.
Attributes:
x.labels
String. The text of the labels in the tabstrip, separated by\n
. r/w.x.current
String. The text of the currently selected label. r/w.
Events:
on change label active
Called when a tab is activated or deactivated.label
(string) is the label of the tab that changed,active
(bool) is true if the tab became active, or false if the tab became inactive.
The thing I’m proud of is the event model. Previously, I had separate Decker buttons for each tab, so when I added a new widget to a “tab” I had to add newwidget.show:"solid"
on one button and newwidget.show:"none"
on all the others, and I kept forgetting which buttons I’d updated, copy/pasting the line and forgetting to change "show"
to "none"
or vice-versa, it was a pain.
The new tabstrip contraption sends an event for the old tab deactivating, and an event for the new tab activating, so I can have one single event handler like this:
on change label active do
if label = "Words"
field1.show:if active "solid" else "none" end
elseif label = "Picture"
canvas1.show:if active "solid" else "none" end
end
end
…and when I add a new widget, I can add just one line to one event handler, and be sure it will never be out of sync with anything else.
One awkward thing is that you wind up with different widgets overlapping, so you can’t easily click on one to select it. As a work around, you can use Widgets → Order… to bring up a list of widgets on the screen, select the widget you want to work with, and click the “Properties” button (if that’s what you want to do) or just click OK and drag the resize handles around.
%%WGT0{"w":[{"name":"tabstrip","type":"contraption","size":[192,16],"pos":[128,64],"script":"on change label active do\n if label = \"Words\"\n field1.show:if active \"solid\" else \"none\" end\n elseif label = \"Picture\"\n canvas1.show:if active \"solid\" else \"none\" end\n end\nend","def":"tabstrip","widgets":{"canvas":{"size":[192,16],"font":"menu","pattern":47},"current":{"pos":[0,32],"value":"Words"},"labels":{"pos":[0,64],"value":"Words\nPicture"}}},{"name":"field1","type":"field","size":[192,80],"pos":[128,80],"scrollbar":1,"value":"Here are some words in a regular field!"},{"name":"canvas1","type":"canvas","size":[192,80],"pos":[128,80],"show":"none","image":"%%IMG2AMAAUAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AAoBAwDAAQYAwAEGAMABBADAAQQAKgEBAJUBBAAmAQEAmQEEAAUBCgATAQEAnQEFAAoBBQANAQEAnwEGAA0BBAAJAQEAnQECAAYBBAANAQMABQEBAJ0BAQAMAQMADQEFAJ0BAQAQAQIArAEBABMBAwCoAQEAFwECAKUBAQAaAQIAogEBAB0BAQChAQEAHgECAJ4BAQAhAQEAnQEBACIBAQCbAQEAIwEBAJsBAQAkAQEAmQEBACUBAQCZAQEAJgEBAJkBAQAlAQEAmQEBACYBAQCZAQEAJQEBAJkBAQAlAQEAmgEBACQBAQCbAQEAJAEBAJsBAQAjAQEAmwEBACMBAQCcAQEAIQEBAJ4BAQAgAQEAnwEBAB8BAQCgAQIAHAEBAKMBAgAaAQEApQEBABkBAQCmAQIAFgEBAKkBAQAVAQEAqgECABIBAQCtAQIADwEBALABAgALAQIAswEEAAQBAwC5AQQA/wD/AJ0=","scale":1}],"d":{"tabstrip":{"name":"tabstrip","size":[192,32],"resizable":1,"margin":[0,0,0,0],"description":"A strip of mutually-exclusive options that can be clicked.","script":"on get_labels do\n labels.text\nend\n\non set_labels x do\n labels.text:x\n new_labels:\"\\n\" split x\n if !(current.text in new_labels)\n set_current[first new_labels]\n end\nend\n\non get_current do\n current.text\nend\n\non set_current x do\n valid_labels:\"\\n\" split labels.text\n if !(x in valid_labels)\n x:first valid_labels\n end\n card.event[\"change\" current.text 0]\n current.text:x\n card.event[\"change\" current.text 1]\n view[]\nend\n\non view do\n canvas.pattern:colors.white\n canvas.rect[(0,0) canvas.lsize]\n valid_labels:\"\\n\" split labels.text\n width:canvas.lsize[0] / count valid_labels\n height:canvas.lsize[1]\n \n canvas.font:\"menu\"\n\n each val key in valid_labels\n left:key * width\n canvas.pattern:colors.black\n if val = current.text\n canvas.rect[(left,0) width,height]\n canvas.pattern:colors.white\n end\n canvas.text[\n val\n (left,0) + (width,height)/2\n \"center\"\n ]\n end\nend","template":"on change label active do\n \nend","attributes":{"name":["labels","current"],"label":["Labels (one per line)","Current Label"],"type":["code","string"]},"widgets":{"canvas":{"type":"canvas","size":[192,32],"pos":[0,0],"volatile":1,"script":"on activate pos do\n valid_labels:\"\\n\" split labels.text\n index:floor (pos[0]/canvas.lsize[0])*(count valid_labels)\n set_current[valid_labels[index]]\nend\n\non click pos do\n activate[pos]\nend\n\non drag pos do\n activate[pos]\nend\n\non release pos do\n activate[pos]\nend","border":0,"scale":1},"current":{"type":"field","size":[96,16],"pos":[0,48],"style":"plain"},"labels":{"type":"field","size":[96,80],"pos":[0,80],"style":"plain"}}}}}