LiveCode7 注:
LiveCode7 での開発は日本語も英文と同じ扱いができます。以下は参考としてください。日本語の保存はLiveCode 6が参考になります。その他特殊な状況の場合、バージョン6の日本語の扱いが活かせることもあります。
22: ボタン、メニューの日本語
この章の概略
- 日本語レイベルのラジオ・ボタンで、フィールドにそれぞれメッセージを書き出します。
- アラート・ウインドウを出して日本語のメッセージを表示します。
- 選ばれた日本語のタブ・メニューから、スイッチでステートメントを引き出します。
- 日本語のメニューを作成して、バージョン6.1の「menuPick」ハンドラーのバグを修正するスクリプトで、テキスト・フィールドのフォントをメニューから設定します。
日本語のラジオ・ボタン
ラジオ・ボタンを3つ作って名前(name)は「Radio1」「Radio2」「Radio3」、レイベル(label)は「ラジオ1」「ラジオ2」「ラジオ3」、とします。その下にフィールド「field 1」を作ってください。
3つのラジオ・ボタンはグループにして、切り替えでハイライトになるようにします。グループ名は「radioBtn」としました。
ラジオ・ボタンはそれぞれのボタン・オブジェクトにスクリプトを書き込むのではなく、グループのスクリプト・エディターで、どのラジオ・ボタンがハイライトかを判別して指示を出します。ここでは押されたボタンの日本語レイベルをフィールドに書き込みます。どのラジオ・ボタンがハイライトになったかを知る方法には2種類あって、12章で使った「hilitedButton」は、グループ内のボタン・オブジェクトのレイヤーの数字を返します。3つのラジオ・ボタンでは「1」か「2」か「3」を返します。もう一つの「hilitedButtonName」は、ハイライトされたボタン名を返します。ボタン名は英文で付けられているので、それからそのレイベルの日本語を得て、ユニコードの表示がされるようにフィールドに入れます。このスクリプトは、グループ「radioBtn」のスクリプト・エディターに書き込みます。
on mouseUp
put the hilitedButtonName of me into tBtnName
put unicode the unicodeLabel of btn tBtnName into fld 1
end mouseUp
「the hilitedButtonName of me」の「me」は、スクリプトを書いているラジオ・ボタンのグループの事です。これでボタン名を「tBtnName」に入れて、次の行でボタン「tBtnName」のユニコード・レイベル(日本語)を、前章のユニコードの扱いをしてフィールドに入れます。
実際のプロジェクトでは、あまりボタン名を直接書き出すと言う事も少ないでしょうから、何か違う日本文と組み合わせてフィールドに書き出す事にします。しかし直接日本語をスクリプトで扱う事はできないので、テキスト・フィールドに入っている日本語をカスタム・プロパティにしておいて、必要に応じて引き出すと言う処置で対処します。
例えばボタン1をハイライトにした時、「ボタン1を押しました」と言うメッセージがフィールドに入るようにします。「ボタン1」は上のスクリプトで取れるので、「を押しました。」と言う日本語をフィールドに入れて、それをグループ「radioBtn」のカスタム・プロパティにします。カスタム・プロパティの名前は「cRadio」としました。
set the cRadio of grp "radioBtn" to the unicodeText of fld 1
カスタム・プロパティ「cRadio」には、上の図のようなコンテンツが入ります(これはMacOSの図です)。もし開発中のスタックがクロスプラット・フォーム用ではなく、MacかWinだけのものでしたら、このアルファベットと記号の羅列のコンテンツを、スクリプト中にクオートで囲ったストリングとして使う事もできますが、何かの事情でクラスプラット・フォームにするかもしれないので、日本語ストリングスを扱う場合は、カスタム・プロパティにしておく事を勧めます。
ボタンが押された時点で、このカスタム・プロパティを引き出して、ボタン・レイベルの日本語名と組み合わせます。赤文字にしている部分が新たに加えたスクリプトです。
on mouseUp
put the hilitedButtonName of me into tBtnName
put unicode the unicodelabel of btn tBtnName & \
the cRadio of me into fld 1
end mouseUp
日本語でアラート・ウインドウを出す
answer "You clicked button Radio1"
英語ではこのスクリプトで、ダイアログ・ウインドウを出してメッセージが表示できます。ストリングの部分を日本語にすると「???????」となってしまって、何かわからなくなります。上で作ったカスタム・プロパティを試しに使ってみます。
answer the cRadio of grp "radioBtn"
やはりこれでは日本語として読む事ができません。ダイアログに日本語を表示するのは、「htmlText」と言うのをを使います。「htmlText」はウェブ・ページを表示するプロパティで、ユニコードを「htmlText」に変換すると、キャラクター1文字づつを前章の「BOM」で説明した、UTF16に割り振った10進数のナンバーになります。グループ「radioBtn」に新しくラジオ・ボタンを追加して、名前は「radio4」、レイベルを「押さないでください。」とします。フィールド1に「押さないでください。」と日本語をタイプしてメッセージ・ボックスから
put the htmlText of fld 1
を送ると、下図のように「p」のタグで囲われた、数字が「;」で繋がれて返されます。ユニコードのそれぞれのキャラクターが、数字で返されたものです。
漢字「押」は「25276」「す」は「12373」です。始めにこれを使ってアラート・ダイアログを出してみます。アイコンがアラートになるように「warning」を「answer」の後に付けます。
answer warning "<p>押さない" & \
"でください。</p>"
これで一通りの行程が理解できたと思いますから、ラジオ・ボタン「押さないでください」が押されたら、カスタク・プロパティから、このアラートを引き出すようにします。フィールドにある「押さないでください。」を「htmlText」にして、グループ「radioBtn」のカスタム・プロパティ「cRadio4」にします。
set the cRadio4 of grp "radioBtn" to the htmlText of fld 1
グループ「radioBtn」のスクリプトは以下のように書き換えます。ラジオ・ボタン「押さないでください(radio4)」が押されたら、ビープ音を出しアラート・ウインドウに日本語で警告して、ラジオ・ボタンのハイライトを「radio1」にします。
on mouseUp
put the hilitedButtonName of me into tBtnName
if tBtnName is "Radio4" then
beep
answer warning the cRadio4 of me
set the hilitedButton of me to 1
put "" into fld 1
else
put unicode the unicodeLabel of btn tBtnName & \
the cRadio of me into fld 1
end if
end mouseUp
日本語のタブ・メニュー
タブ・メニューはプロパティ・インスペクターに、直接日本語を打ち込んで日本語タブにできますが、一旦インスペクターが閉じられると、日本語タブはそのままでも、インスペクター側に打ち込んだ日本語は「?????」に変わってしまいます。しかしこのまま続けても問題ありません。もし何かの修正が必要でしたら、テキスト・フィールドに打ち込んだ日本語のタブ・リストを、メッセージ・ボックスから送ってタブにする事もできます。
set the unicodeText of btn "tabMenu" to the unicodeText of fld 1
タブ・クリックと同時に日本語タブ名を受け取って、フィールドに日本語で表示するのは、タブ・メニューに予め用意されている「menuPick」ハンドラーのパラメータ「pItemName」を使えば普通のユニコードの扱いでできます。
on menuPick pItemName
put unicode pItemName into fld 1
end menuPick pItemName
しかし問題は、通常タブ・メニューは「switch」で選ばれたタブを「case」を使って振り分けますが、クロス・プラットフォームで統一のスクリプトにした場合、パラメータで得られるユニコードに違いが出て来るので、プラットフォーム毎に分けた「switch」コントロール・ストラクチャーを、2通り作らなくてはいけなくなります。ですから「switch」コントロール・ストラクチャーを一つだけにするには「menuHistory」を使います。「menuHistory」は、クリックされたタブ・リストの上から順に数字を返します。サンプルで言えば「タブ1」が「1」、「タブ2」が「2」、「タブ3」が「3」です。
on menuPick pItemName
switch the menuHistory of me
case "1"
-- ここは必要に応じて、ステートメントがきます
put unicode pItemName into fld 1
break
case "2"
-- ここは必要に応じて、ステートメントがきます
put unicode pItemName into fld 1
break
case "3"
-- ここは必要に応じて、ステートメントがきます
put unicode pItemName into fld 1
break
end switch
end menuPick pItemName
日本語のメニュー
メニュー・ビルダーで作るような形の日本語のメニューです。メニュー・ビルダーのメニューは、プルダウン・メニュー・ボタンがグループ化して作られています。個々のプルダウン・ボタンのプロパティ「showBoarder」をfalseに設定すると、プルダウンされるテキストのフォントのサイズも変わって、いわゆるメニューの形体になります。現在バージョン6.1で、Windowsメニューのメニュー・ハンドラー「menuPick」が、ユニコードのメニュー・アイテムを受け取れないバグがあります。ここで書くのはそのバグを避けて選んだユニコードのメニュー・アイテムを得る、MacOSとWindows共通のスクリプトにしています。ユニコード関連のバグはなかなか修正されない事も多いので、このバグが何時修正されるか不明です。修正された以降も使えると思いますが、あるいは周辺の仕様が変わって使えなくなる可能性もあります。そうなったらその時にまた、何かの形でお知らせできると思います。
バグを解消する為に、ダブル・バイトのユニコード・キャラクターをシングル・バイト毎に取り扱う、少し特殊なファンクションを使っています。2つのファンクション「UnicodeLineOffset」と「getUnicodeMenuItem」は、スタック・エディターにそっくりコピペしてください。これに関しては、ライン毎の説明は省かせてもらいます。
function unicodeLineOffset @tdata,pWhichline
put number of characters of tdata into tlength
set useunicode to true
put 1 into tlinecount
put 1 into tlineoffset
repeat with i = 1 to tlength step 2
if tlinecount is pWhichline then exit repeat
if chartonum(char i to i+1 of tdata) is 10 then
add 1 to tlinecount
put i+2 into tlineoffset
end if
end repeat
if pWhichline > tlinecount then put tlength + 1 into tlineoffset
return tlineoffset
end unicodeLineOffset
function getUnicodeMenuItem pBtnName, pLineNum
put the unicodetext of btn pBtnName into tdata
put UnicodeLineOffset(tdata,pLineNum) into startchar
put UnicodeLineOffset(tdata,pLineNum+1) - 1 into endchar
put (char startchar to endchar of tdata) into tLineData
put (the num of chars of tLineData + 2)/2 into tEndChar
set the useUnicode to true
repeat with i = 1 to (tEndChar-1)*2 step 2
put char i to i+1 of tLineData after tString
end repeat
if charToNum(char -2 to -1 of tString) is 10 then
delete char -2 to -1 of tString --// delete return character //--
end if
return tString
end getUnicodeMenuItem
基本形は英語のメニュー・ビルダーで作るのが良いと思います。メニュー・ビルダーで新しいメニューを作ったら「New Menu」をクリックして、左側の「Edit」メニューの下に「jpMenu」と「enMenu」と言うメニューを、2つ追加してください。この2つを「日本語フォント」と「英語フォント」と言うメニューにします。「Set as stack Menu bar」のチェックを外して、MacOSのスタック上にメニューがグループ・オブジェクトになって表れるようにします。
始めにボタンのレイベルを日本語にします。LiveCodeのアイコン・メニューにある「Select Grouped」をクリックすると、グループ内のボタンがセレクトできますから、「File」をセレクトして、インスペクターのレイベルを「ファイル」にしてください。ボタンの横巾が小さいので文字が全部見えるくらいの左右にして、その他のボタンもそれに揃えて右に動かします。マウスを使ってサイズ、ポジションの修正もできますし、インスペクターの「Size & Position」からでもできます。
set the unicodeText of btn "file" to the unicodeText of fld 1
プルダウンしたときに見えるメニュー・アイテムを補助のフィールドを作って「新規、開く、閉じる、-、終了」と5行をタイプして、メッセージ・ボックスからスクリプトを送ります。4行目の「-」は英文字のハイフン(hyphen)で、区切りのラインになります。
set the unicodeText of btn "edit" to the unicodeText of fld 1
同じように「edit」ボタンもレイベルを「編集」に変えて、「カット、コピー、ペースト、削除、-、Preferences」をメニュー・アイテムにします。最後の行「Preferences」は、MacOSでは自動的にメニューのアプリケーション名の下に「環境設定」となって表れます。Windows用に「環境設定」としても良いですが、MacOSの通常の「環境設定」とは異なる「編集メニュー」の下に「環境設定」が表れます。これを避けるには、どこか(例えばボタン「edit」)にカスタム・プロパティのMac用メニュー・アイテムと、Windows用メニュー・アイテムを作って、「preOpenStack」でプラット・フォームで振り分けたメニュー・アイテムを書き込むと言う方法をとります。今は「Preferences」のまま進めます。
「日本語フォント」「英語フォント」以外は、下記のスクリプトが入ります。
on menuPick
put the menuHistory of me into tLineNum -- 選ばれたアイテムの番号
put the short name of me into tMenu -- メニュー・ボタンの名前
put unicode getUnicodeMenuItem(tMenu,tLineNum) into fld 1
end menuPick
「the menuHistory of me」で、ユーザーが選んだメニュー・アイテムの番号を得ます。「the short name of me 」でメニューにしているボタンの名前を得て、この2つをファンクション「getUnicodeMenuItem」のパラメータにして選ばれたユニコードのメニュー・アイテムを、フィールド1に入れます。
実際のメニューでは、「getUnicodeMenuItem」が必要な事はフォント・メニュー以外ではあまりないかもしれません。下に書いたスクリプトのように「switch」を使って、メニュー・ヒストリーで得た番号を「case」で割り振る事になるでしょう。
switch tLineNum
case "1"
-- それぞれのステートメントが入ります。
break
case "2"
-- それぞれのステートメントが入ります。
break
case "3"
-- それぞれのステートメントが入ります。
break
case "5"
-- それぞれのステートメントが入ります。
break
end switch
メニュー「日本語フォント」は、ユーザーによってインストールしているフォントが違うので、メニューがマウスダウンされた時に、日本語フォントのリストをメニュー・アイテムにします。21章で日本語のフォント名だけのリストを作ったのと同じに、ファンクション「fontNames」でインストールしてあるフォント名のすべてをラインで分けたリストで返しますから、リピートで「fontLanguage」が「japanese」だけを選り分けます。
サンプルで作った日本語フォント・メニューを、メッセージ・ボックスからダウンロードしてください。
go to \
url "http://kenjikojima.com/livecode/download/jpFontMenu03.livecode"
メニュー「日本語フォント」に入れる「mouseDown」と「menuPick」のスクリプトです。
local lFontNames
on mouseDown
get the fontNames
repeat for each line tLine in it
if the fontLanguage of tLine is "japanese" then
put tLine & cr after tFontNames
end if
end repeat
if the platform is "MacOS" then
sort tFontNames
else
put "----------------------" &cr before tFontNames
end if
delete char -1 of tFontNames
put tFontNames into lFontNames
set the text of me to uniencode(tFontNames,japanese)
end mouseDown
on menuPick
put the menuHistory of me into tLineNum
put the short name of me into tMenu
put getUnicodeMenuItem(tMenu,tLineNum) into tFontName
put unicode tFontName & the cSelected of owner of me into fld "tempo"
set the textFont of fld "sampleText" to line tLineNum of lFontNames
end menuPick
かなりの部分は21章で使ったスクリプトと同じですが、プラットフォーム(platform)の違いでWindowsではリストの始めに「"----------------------" &cr 」を入れています。実はユニコードにしたフォント名をメニュー・ボタンにセットすると、始めの行に不明なキャラクター4文字が付いてしまいます。「menuPick」のバグが修正された時点で、再度確認しなくてはいけません。そのため始めの行を無効にする臨時的な処置を採っています。「local lFontNames」にしているのは、メニューピック「menuPick」されたフォント名を、「menuHistory」で得た番号からラインを特定するためのものです。
日本語サブメニュー
もう少し実際のメニューに即した、サブメニューを使うテキスト・メニュー改良形を作ってみました。メッセージ・ボックスから下のスクリプトを送ってスタックを見てください。
go to \
url "http://kenjikojima.com/livecode/download/jpFontMenu04.livecode"
上で作ったメニューに「テキスト」メニューを追加しています。「テキスト」メニューをクリックすると、メニューにそれぞれサブのメニューが付いています。英語のサブメニューを思い出してください。サブ・メニューの始めにすべてタブ(tab)を入れました。
サンプル・スタックの右側に、「日本語フォント」「英語フォント」「サイズ」と行替えをしてメニュー・アイテムの基本形を書いたフィールドがあります。「サイズ」から下の数字の部分はサブメニューで、数字の始めにタブ(tab)を入れています。その下の「文章揃え」はメニューで、やはり下にはタブを始めに入れたサブメニューを3つ置いています。「日本語フォント」「英語フォント」のサブメニューは、ユーザーによってインストールしてあるフォントが違うので、ここには書きません。この基本形のメニュー・リストを予めメニュー(ボタン名「text」)に「cMenuItems」と言う名前のカスタム・プロパティにして、メニューがマウスダウン(mouseDown)された瞬間にフォントのサブメニューを加えて、メニューに表示されるようにします。メニューの項目が入っているフィールド名を「textMenuItems」として、ユニコードのカスタム・プロパティ「the cMenuItems of btn "text"」にします。
set the cMenuItems of btn "text" to the unicodeText of fld "textMenuItems"
普通の英語メニューで使うメッセージ・ハンドラー「menuPick」のパラメータ「pWhich」は、現在のバージョンではユニコードを受け取ることができません。しかしユニコードのメニュー・アイテムの後にスラッシュ「/」を入れておく事で、スラッシュより後のキャラクターはメニュー・アイテムとして表示されませんが、英数字のキャラクターはパラメータ「pWhich」で受け取る事ができます。ボタン「text」(メニュー「テキスト」)に入れるスクリプト全文です。
local lMenuItems,lFontArray, lFontNum
on mouseDown
-- メニュー・アイテムの基本形のカスタム・プロパティ
put the cMenuItems of me into tMenuItems
get the fontNames
-- フォントのリストから日本語フォントだけを抜き出す
repeat for each line tLine in it
if the fontLanguage of tLine is "japanese" then
put cr& tab & tLine after jpFontNames
end if
end repeat
if the platform is "MacOS" then
sort jpFontNames
end if
get the fontNames
-- フォントのリストから英語フォント(ansi)だけを抜き出す
repeat for each line tLine in it
if the fontLanguage of tLine is "ansi" then
put cr& tab & tLine after enFontNames
end if
end repeat
if the platform is "MacOS" then
sort enFontNames
else
filter enFontNames without "@*"
sort enFontNames
put cr before enFontNames
end if
-- 日本語英語フォント名のすべて
put jpFontNames & cr & enFontNames into allFontNames
-- フォント名が引き出せるアレイ「lFontArray」を作る
put 1 into tNUm
repeat for each line tLine in allFontNames
put tLine into lFontArray[tNum]
add 1 to tNum
end repeat
put tNum into lFontNum -- アレイ「lFontArray」で使ったの最大の数字
-- ハンドラー・メニューピック(memuPick)でも使えるように
-- 「lFontArray」「lFontNum」をローカルに設定しています
-- 始めにメニューの基本形のライン2の後に英語フォント(サブメニュー)を入れる
put uniEncode(enFontNames,Japanese) after line 2 of tMenuItems
-- 次ににメニューの基本形のライン1の後に日本語フォント(サブメニュー)を入れる
put uniEncode(jpFontNames,Japanese) after line 1 of tMenuItems
-- メニューとサブメニューのすべてに「/|」と数字を振ります
repeat with i=1 to the num of lines of tMenuItems
put uniEncode("/|") & uniEncode(i) after line i of tMenuItems
end repeat
-- メニューとサブメニューのすべてにをローカルに設定
put tMenuItems into lMenuItems
-- メニューにセットする
set the unicodetext of me to tMenuItems
end mouseDown
on menuPick pWhich
-- マウスダウンでタテ棒「|」の後に振った数字を「pWhich」にする
if pWhich contains "|" then \
delete char 1 to offset("|",pWhich) of pWhich
put the short name of me into tMenu --ボタン名をtMenuに入れる
-- スタック・エディターに書いたファンクション「getUnicodeMenuItem」で
-- 「pWhich」が何なのか、ユニコードで「tItem」に入れる
-- フィールド「tempo」に入れるためだけなので、必ずしも必要ではない
put getUnicodeMenuItem(tMenu,pWhich) into tItem
if pWhich <= lFontNum then
-- 「pWhich」がフォントに振った数字より小さければ、フォントが選ばれているので
-- 「lFontArray」からフォント名を得て「tFontName」に入れる
put lFontArray[pWhich] into tFontName
replace tab with "" in tFontName -- 「tFontName」のタブを取り除く
-- 選ばれたフォントにフィールドをセットする
set the textFont of fld "sampleText" to tFontName
-- フィールド「tempo」にフォント名が書き込めるようにユニコードにする
-- フィールド「tempo」に入れるためだけなので、必ずしも必要ではない
put uniEncode(lFontArray[pWhich],japanese) into tItem
if tItem contains uniencode(tab) then
replace uniencode(tab) with "" in tItem
end if
else
-- フォント名以外のメニュー・アイテムが選ばれた
-- 「pWhich」の数字からフォントの総数を引いた残りを「case」で振り分ける
put pWhich - lFontNum into caseNum
switch caseNum
case 1
case 2
case 3
case 4
-- 1〜4までの「case」ならばサイズに当てはまるので
-- アレイ「sizeArray」を作り1〜4までの「caseNum」でサイズを特定する
put "9,10,12,14" into sizeArray
split sizeArray by comma
set the textSize of fld "sampleText" to sizeArray[caseNum]
break
case 5
-- ask "Please Type Font Size."
-- 日本語のダイアログ「テキスト・サイズをタイプしてください。」を出す
ask <p>テキスト・サ" & \
"イズをタイプし" & \
"てください。</p>"
if it <> empty then
if isNumber(it) then
-- フィールドのテキスト・サイズを設定
set the textSize of fld "sampleText" to it
else
beep
end if
end if
break
case 7
case 8
case 9
-- 「caseNum」7〜9は文字揃え。
-- アレイ「alignArray」を作って「caseNum」から6を引いた数で得る
put "left,center,right" into alignArray
split alignArray by comma
set the textAlign of fld "sampleText" to alignArray[caseNum - 6]
end switch
if tItem contains uniencode(tab) then \
replace uniencode(tab) with "" in tItem
end if
-- put tItem &cr& caseNum
put unicode tItem into fld "tempo"
end menuPick
この章で新しく出て来た言葉
htmlText プロパティ(property) フィールドの文章をHTMLタグで表示させる
put the htmlText of fld 1