--:-- LUA API

ウィジェット操作

create / destroy / set / get / on / off / add_child / remove_child / リスト・タブ・名前・矩形・重なり順・フォーカスの操作

pico.create

pico.create(type_name: string) -> id: integer

指定した種別のウィジェットを1つ作り、WidgetId(整数)を返します。作った直後の位置・大きさは仮の値です。

  • type_name が知らない種別名ならエラー。
  • メモリが足りずに作れなかったときもエラー。
  • 作れる種別は ウィジェット種別一覧 を参照。

pico.destroy

pico.destroy(id: integer) -> (なし)

ウィジェットを破棄します(実際に消えるのはそのフレームの終わり)。登録した pico.on() のコールバックも外れます。コンテナを破棄すると、中の子も消えます。

  • 破棄済みの id を渡してもエラーにならず何もしません(2回呼んでも安全)。

pico.set

pico.set(id: integer, name: string, value: any) -> (なし)

プロパティを書き込みます。value は文字列・真偽値・数値のどれかです(数値は整数でも小数でもかまいません)。

  • id が無効: エラー。
  • name が未知のプロパティ名: エラー。
  • そのウィジェット種別が name に対応していない、または value の型が合わない: エラー。
  • 対応プロパティの一覧は プロパティ対応表 を参照。

pico.get

pico.get(id: integer, name: string) -> value: any | nil

プロパティを読み取ります。

  • id が無効、または name が未知のプロパティ名: エラー。
  • name 自体は有効だが、そのウィジェット種別が対応していない組み合わせ: エラーにはならず nil を返します。

pico.on

pico.on(id: integer, event_name: string, callback: function) -> (なし)

イベントコールバックを登録します。同じ id + event_name へ再度呼ぶと、古いコールバックを解除して差し替えます。

  • event_name が未知: エラー。
  • 対象ウィジェットがそのイベントに対応していない(例: Button に "checked_changed"): エラー。
  • イベント名の全一覧・引数は イベント を参照。

pico.add_child

pico.add_child(container_id: integer, child_id: integer) -> (なし)

child_id を container_id の子として追加します。container_id は LayoutContainer / GridContainer / ScrollContainer のいずれかである必要があります(それ以外はエラー)。

pico.remove_child

pico.remove_child(container_id: integer, child_id: integer) -> (なし)

add_child の逆。子を破棄せずに取り外します。

  • container_id がコンテナ種別でない: エラー。
  • child_id が実際にそのコンテナの子でない: エラー。
  • 取り外した子は、コンテナの外の普通のウィジェットに戻ります。x / y はコンテナの中での値のままです。

pico.off

pico.off(id: integer, event_name: string) -> removed: boolean

pico.on で登録したコールバックを解除します。登録されていなければ false。event_name が未知ならエラー。

pico.text_set

pico.text_set(id: integer, text: string) -> whole: boolean

TextView(16KiBまで)と MarkdownView(8KiBまで)に長い文章を渡します。pico.set(id, "text", ...) は255バイトまでなので、それより長いものはこちらを使います。上限を超えた分は切り捨てられ、false を返します。MarkdownView に渡した文書の中の相対パス(画像など)は、SDのルートが基準になります(ファイルから読むなら pico.set(id, "path", ...))。

QRCode にも使えます(255バイトまで)。こちらは超えたときに切らずに空にして false を返します(途中で切れたQRは別の中身を指してしまうため)。

pico.set_dots

pico.set_dots(id: integer, dots: table) -> (なし)

MonthGrid の日付の下に点(予定の印)を出します。dots[日] に色の番号の配列(最大3つ)か、色の番号1つを入れます。

pico.set_dots(grid, { [3] = {12, 9}, [14] = 10 })  -- 3日に赤と青、14日に緑

pico.set_name / pico.find

pico.set_name(id: integer, name: string) -> (なし)
pico.find(name: string) -> id: integer | nil

ウィジェットに名前を付けて、後から名前でidを引きます。IDを全部変数で持ち回らずに済みます。名前は1〜23文字で、アプリの中で一意です(同じ名前を付け直すと付け替わります)。最大128個。ウィジェットを pico.destroy すると名前も消えます。

pico.parent / pico.children

pico.parent(id: integer) -> parent_id: integer | nil
pico.children(id: integer) -> ids: table

親と(直接の)子のidです。親がない(一番上の)ウィジェットは nil。

pico.get_rect

pico.get_rect(id: integer) -> x, y, w, h

画面座標での矩形です(親のコンテナの位置を含んだ実際の位置)。

pico.bring_to_front / pico.send_to_back

pico.bring_to_front(id: integer) -> ok: boolean
pico.send_to_back(id: integer) -> ok: boolean

重なり順を変えます(子孫も一緒に動きます)。コンテナの子には使えず false を返します(コンテナの中の並びは add_child した順です)。

pico.focus / pico.get_focus

pico.focus(id: integer | nil [, show_ring: boolean]) -> ok: boolean
pico.get_focus() -> id: integer | nil

フォーカス(物理キーボード・コントローラーで操作する相手)を移す/外す(nil)/読みます。show_ring の既定は true(青い枠を出す)。 受けないウィジェット(focusable が false・見えない・無効・開いているダイアログの外)へは移らず false を返します。

フォーカスはOSが動かします。Tab / Shift+Tab(コントローラーは R / L)で読む順(上から、同じ高さなら左から)に、矢印 / 十字キーでその向きの一番近いものへ移り、 Enter / Space(A)で押します(真ん中をタップしたのと同じで、press_start / press_end が届きます)。Esc(B)は開いたドロップダウンを閉じ、ダイアログ(pico.show_*)ならキャンセルします。 フォーカスのある Textbox / NumberInput で文字を打つと、キーボードが開いてそのまま入ります。 枠はキー/ボタンで動かしたときだけ出て、画面をタッチすると消えます(タッチしたものがフォーカスを持ちます)。 ダイアログが開くとフォーカスは中(入力欄があれば入力欄)へ移り、その間はその中だけを動き、閉じると開く前のものへ戻ります。 pico.show_input の1行の入力欄はEnterで決定、Escでキャンセルです。

受ける種類の既定は Button Checkbox Textbox NumberInput NumberSlider(←→で値)ScrollList(↑↓で選び、決定で2回目のタップ)DropdownMenu(決定で開き、↑↓で選ぶ)TabBar(←→でタブ)MarkdownView(↑↓でスクロール)MonthGrid(←→で1日・↑↓で1週)DurationPicker(←→で桁・↑↓で増減。editable が偽なら受けない)。 ほかの種類(Canvas 等)も pico.set(id, "focusable", true) で受けるようにできます。 pico.pad_* を使ったアプリでは、コントローラーのボタンはフォーカスを動かしません(ゲームの操作とぶつからないように)。キーボードの矢印は pico.on_key で取れば(true を返せば)動きません。

pico.scroll_to

pico.scroll_to(container_id: integer, child_id: integer) -> ok: boolean

ScrollContainer を、子が見える位置(上端)までスクロールします。子でなければ false。位置の読み書きは scroll_y プロパティ、変化は scrolled イベントです。

pico.show_keyboard / pico.hide_keyboard

pico.show_keyboard(id: integer) -> (なし)
pico.hide_keyboard() -> (なし)

Textbox / NumberInput のオンスクリーンキーボードを、タップしなくても開く/閉じます。

リストとドロップダウン

ScrollList と DropdownMenu の項目の操作です。番号は0始まりで、selected_index と同じです。対応していない種別を渡すとエラーです。

pico.list_add(id: integer, text: string, opts?: table) -> (なし)

末尾に追加します。opts は ScrollList だけに効き、{icon = pico.ICON_*, color = 色の番号}(項目ごとのアイコンと文字色)。

pico.list_insert(id: integer, index: integer, text: string, opts?: table) -> (なし)

index 番目へ挿入します(ScrollList のみ。範囲外は末尾)。選択中の項目はずれた分だけ追従します。

pico.list_remove(id: integer, index: integer) -> ok: boolean

取り除きます(範囲外は false)。選択中の項目を消すと選択は外れます。

pico.list_get(id: integer, index: integer) -> text: string, color: integer | nil, icon: integer

範囲外は nil。

pico.list_select(id: integer, index: integer) -> (なし)

選択します(-1 で選択なし)。コールバックは呼ばれません。範囲外はエラー。

pico.list_scroll_to(id: integer, index: integer) -> (なし)

ScrollList を、その項目が先頭に来る位置までスクロールします。

pico.list_clear(id: integer) -> (なし)

項目を全部消します。DropdownMenu は表示も未選択の状態へ戻ります。

タブ

TabBar は最大8個のタブを持てます。番号は0始まりです。

pico.tab_add(id: integer, label: string) -> ok: boolean

タブを1つ足します。8個に達していれば false(エラーにはなりません)。TabBar 以外を渡すとエラーです。

pico.tab_label(id, index) -> label: string | nil
pico.tab_set_label(id, index, label) -> ok: boolean
pico.tab_remove(id, index) -> ok: boolean
pico.tab_clear(id) -> (なし)
pico.tab_link(tab_id: integer, index: integer, widget_id: integer) -> (なし)
pico.tab_unlink(tab_id: integer, index?: integer) -> (なし)

タブの中身の切り替えを自動化します。tab_link した widget_id は、そのタブが選ばれている間だけ表示されます(タブが切り替わるたびに自動で visible を切り替えます。tab_changed イベントとは別に動きます)。1つのタブに複数のウィジェットを連動できます(全部で32個まで)。tab_unlink は連動を外します(index を省くとそのTabBarの全部)。

local tabs = pico.create("TabBar")
for _, name in ipairs({"設定", "履歴", "情報"}) do pico.tab_add(tabs, name) end
pico.tab_link(tabs, 0, settings_panel)
pico.tab_link(tabs, 1, history_panel)
pico.tab_link(tabs, 2, about_panel)