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>&#25276;&#12373;&#12394;&#12356;" & \
          "&#12391;&#12367;&#12384;&#12373;&#12356;&#12290;</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>&#12486;&#12461;&#12473;&#12488;&#12539;&#12469;" & \
              "&#12452;&#12474;&#12434;&#12479;&#12452;&#12503;&#12375;" & \ 
                "&#12390;&#12367;&#12384;&#12373;&#12356;&#12290;</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




21: サンプル・アプリから、次のステップに進む

23: 日本語(ユニコード)の実践、その他




ⓒ 小島健治 / Kenji Kojima