04 入出力

ユーザーが何らかの値を入力したり、計算結果を出力する方法です。

CindyJSを用いてWeb上で作品を使うときは,キーボードはありませんから(ソフトウェアキーボードも使えない)画面上に数字のボタンを配置します。(ソフトウェアキーボードのようなもの)

そこで,「ボタン」の作成もこの項目に入れています。

ボタンの作成

例として,0から9までのボタンを作って配置し,クリックするとその数が返ってくるようにしましょう。

まず,「文字を加える」ツールで,0から9までの数を全角数字で画面上に作ります。場所はどこでも構いません。図では,画面下の磁石アイコンのツールをクリックして座標軸と方眼を表示しています。

次に,表示メニューから「式による表示」を選びます。今作った文字列の識別名が表示されます。

選択モードに移り,Shitキーを押したまま,順にクリックして選択していきます。描画面上の文字でも,表の識別名でもどちらでも結構です。

いまは他に点や線をとっていないので,「すべてを選択する」ツールで選択することもできます。

全部選択できたら,Ctrl+I (⌘+I) でインスペクタを開きます。フォントの大きさを変えるとまとめて変えることができます。スライダでは最大26ですが,キーボードで打ち込むこともできます。

一度,画面の何もないところをクリックし,今度は1から一つずつ選択して次の作業をします。

インスペクタの「要素の情報」タグをクリックし,「ボタンとして使う」「クリックボタン」の両方にチェックを入れ,スクリプトの欄に Ans=0 などど書きます。0のボタンを押したら,変数 Ansに0が入るようにするのです。

これで,0の文字がボタンになります。

ボタンになると,次はクリックで選択できなくなるので,「式による表示」で選ぶか,画面上の文字列を右クリックします。

同様にして9まで設定します。

次に,スクリプトエディタを開いて,次のようなコードを書きます。

dispno(bool):=(

if(bool,pos=apply(0..9,[1.5*#,0]),pos=apply(0..9,[-40,0]));

Text0.xy=pos_1;

Text1.xy=pos_2;

Text2.xy=pos_3;

Text3.xy=pos_4;

Text4.xy=pos_5;

Text5.xy=pos_6;

Text6.xy=pos_7;

Text7.xy=pos_8;

Text8.xy=pos_9;

Text9.xy=pos_10;

);

dispno(true);

実行するとボタンが整列します。

表示する位置は適当に変えましょう。また,インスペクタをを用いて色を変えてもよいでしょう。

引数を bool にしたのは,このブール値で画面に表示したり見えなくしたりするためです。dispno(false) とすると座標 (-40,0) に配置されて画面から見えなくなります。

ボタンを押すと Ans がその値になります。動作を確かめましょう。

drawtext([0,4],Ans,size->20);

を実行すると,最初は Ans が未定義なので ___ が表示されますが,ボタンを押すとその数字に変わります。

マウスクリックの取得

今度は,ボタンを作らずに,画面上に表示した数字をクリックするとその数が変数 Ans に入るようにします。

Mouse Click スロットに書いたスクリプトは,マウスクリックのタイミングで実行されるので,これを利用します。

まず,画面上に0から1までの数字を書きますが,こんどはスクリプトで座標を決めて描きます。

たとえば,

forall(0..9,drawtext([#+0.1,0.1],#,size->28));

とします。

次に,Mouse Click スロットに,次のコードを書きます。mouse() 関数は,マウスでクリックした位置を返す関数です。

mp=mouse();

Ans=-1;

if(0<mp.x & mp.x<10 & 0<mp.y & mp.y<1,

Ans=floor(mp.x);

);

Drawスロットに戻って,drawtext([0,3],Ans); で動作を確かめましょう。数字以外の場所をクリックすると -1 が表示されます。

キーボードからの入力

キーボードからの入力を取得するには,Key Typed スロットにスクリプトを書きます。押されたキーが何であるかを返す関数は2つあります。

key() :キーボードで打たれた文字列を返します。

keydownlist() :押されたキーのリストを返します。

どう違うかは,

println(key()) または println(keydownlist()) として動作を確かめるとよいでしょう。

key() は打たれた文字列を返すのでそういう意味では使いやすいのですが,EnterやBSキーを取得できません。keydownlist() ならこれらのキーも取得できます。

ここでは,keydownlist() を使って,BSキーやEnterキーも有効になるようなスクリプトを書いてみます。

// 打ったキーの文字を数字にしてInputkeyに代入する 数字と. ,BS,Enterが有効

// BSキーを打ったときは B Enterなら E を返す

numeric="0123456789";

kk=keydownlist()_1;

if(48<=kk & kk<=57,

Inputkey=numeric_(kk-47);

);

if(96<=kk & kk<=105, // テンキー

Inputkey=numeric_(kk-95);

);

if(kk==8,Inputkey="B");

if(kk==10,Inputkey="E");

if(kk==46 % kk==110,Inputkey=".");

変数 Inputkey はInitialization スロットで Inputkey=""; として初期化しておきます。

得られた Inputkey をどう利用するかは場合によって違うでしょう。

たとえば Enter が打たれるまで Inputstr=Inputstr+Inputkey で文字列を作っていき,"E"だったとき,入力終了として次の処理に入る,といった使い方です。

ファイルの読み込み

load() 関数を使うと,テキストファイルを読み込むことができます。

しかし,改行コードを無視して,全体を1つの文字列として読み込むので,CSVファイルでは行区切りが不明となります。CSVファイルであれば,テキストファイルでファイルを開いておいて,Ctrl+C と Ctrl+V でコピーする方がよいでしょう。

setdirectory("/Users/Hoge/Desktop");

str=load("text.txt");

とすると,ユーザー Hoge のデスクトップにあるテキストファイル text.txt の内容が,文字列 strとなります。

ディレクトリ指定は,Windowsでしたら

setdirectory("C:¥Users¥Hoge¥Desktop");

のようになります。

ファイルへの書き込み

テキストファイルへの書き出しができます。

手順は

(1) setdirectory(パス)で書き出すディレクトリ(フォルダ)を指定する。

(2) f=openfile(ファイル名) でファイルを開く。fは適当な名前の変数。ファイル名は文字列。

(3) println(f,文字列) で書き出す。改行しないなら print(f,文字列)

(4) closefile(f) でファイルを閉じる

とします。

たとえば,Rireki という文字列のリストを,ユーザー Hoge のデスクトップに書き出します。

output():=(

setdirectory("/Users/Hoge/Desktop");

f=openfile("Record4");

repeat(length(Rireki),

println(f,Rireki_#);

);

closefile(f);

);

CSVファイルであればコンマ区切りですので,データの状況に応じて

println(f,a+","+b+","+c);

のようにすればよいでしょう。

表計算ソフトからのコピー

表計算のワークシートから,範囲指定をして Ctrl+C と Ctrl+V でスクリプトエディタにコピーすることができます。

このとき,行の各セルはTABコード 09 で区切られます。

コピーしたあとは tokenize() でリストに切り分けて利用します。

詳しくは「C データ処理」「01 データのリスト化」で解説しています。

描画面上での文字列入力

モードメニューの「特別」「文字列入力」によって入力ボックスができます。

画面上をクリックすると,設定ウィンドウが出ます。

そのまま OK ボタンを押すと,文字幅300ピクセルの入力ボックスができます。

動かすモードでクリック,または右クリックで選択しインスペクタを開いて,作図ツールの「文字を追加する」で描いたものと同様,文字サイズや塗り色を適当に設定します。

次の図はその左に,作図ツールの「文字を追加する」で「数式を書く」を描いたものです。

Cindyscriptエディタを開いて,ここに書いた文字列を処理するスクリプトを書きます。

はじめに描いたボックスは,Text0 という識別子になっていますので(2つめに描けば Text1)

drawtext([0,3],parse(Text0.val),size->20);

とします。Text0の値を解釈して,数式であれば計算し,文字列であれば未定義値 __ を表示します。

関数式を書いてグラフを描くこともできます。

f(x):=parse(Text0.val);

plot(f(x));

とすると,テキストの式で関数f(x)を定義し,plot() でグラフを描きます。