NS BasicでClieのジョグダイヤル対応アプリを作ろう!


HPのTOPに戻る
Basic BASIC別館のTOPに戻る

NS BasicはPalmデバイス上で動作するアプリの開発が出来ます。
また、現在最新版のNS Basicならば標準でClieのジョグダイヤルのイベントに対応しています。
その為、非常に簡単にジョグダイヤル対応のアプリの開発が可能です。

そこで、順を追ってジョグダイヤル対応アプリの開発する為のノウハウなんかを書いて行きたいと思います。

<JogDialイベントの認識>

まず初めにJogDialのイベントを認識しなければなりません。
その為には、GetEventTypeを使用します

GetEventType
戻り値
イベントタイプ
1NsbKeyOrButtonハードキー又は、シルクボタン等が押された
2NsbPenDownペンダウンイベント
3NsbPenUpペンアップイベント
4NsbJogDialJogダイヤルイベント

上の表の通りJogDialのイベントはGetEventTypeの戻り値がNsbJodDialまたは4である事が判ります。

つまり、以下のような感じでJogDialのイベントを識別出来ます(もちろんIFでも構いません)
サンプルプログラム

    Select Case GetEventType()
    Case 1
        '---- ハードキー又は、シルクボタン等が押された
    Case 2
        '---- スクリーンをスタイラスで押された
    Case 3
        '---- スクリーンからスタイラスが離された
    Case 4
        '---- ジョグダイヤルで何らかの処理が行われた
    End Select

<JogDialイベントの振り分け>

GetEventTypeでJogDialのイベントだと認識した後は、JogDialのイベントの種類を見分ける必要があります。
その為には、GetKeyを使用します。

GetKey
戻り値
ジョグダイヤルの操作
0ジョグダイヤルを時計周りに回した
1ジョグダイヤルを反時計回りに回した
2ジョグダイヤルを長押ししている
3ジョグダイヤルを押しながら時計周りに回した
4ジョグダイヤルを押しながら反時計周りに回した
5ジョグダイヤルを押した
6ジョグダイヤルを放した

※実際にはGetKeyの戻り値は文字型の為、Ascでキャラクタコードに直す必要があります

以下のような感じでJogDialのイベントの種類を見分ける事が出来ます

サンプルプログラム

    Dim theKey as Integer
    
    If GetEventType()=NsbJogDial Then
        theKey=Asc(GetKey())
        Select Case thekey
        Case 0
            '---- "JogUp"
        Case 1
            '---- "JogDown"
        Case 2
            '---- "JogPressRepeat"
        Case 3
            '---- "JogPageUp"
        Case 4
            '---- "JogPageDown"
        Case 5
            '---- "JogPress"
        Case 6
            '---- "JogRelease"
        End Select
    End If
JogDialのイベント内容
JogUpイベントJogDialを時計回りに回す
JogDownイベントJogDialを反時計回りに回す
JogPressRepeatイベントJogDialを押しっぱなしにする
JogPageUpイベントJogDialを押したまま、時計回りに回す
JogPageDownイベントJogDialを押したまま、反時計回りに回す
JogPressイベントJogDialを押す
JogReleaseイベント押されていたJogDialを離す

<JogDialイベントの流れ>



上のフローを見てもらえれば判りますがJogPress、JogUp、JogDownイベント以外は全て、JogPressイベントの次に発生するイベントです。

つまり、JogPressにイベントを配置してしまうと、JogPressRepeat、JogPageUp、JogPageDown、JogReleaseが発生する前に
必ず、発生JogPressイベントが発生してしまいます。

その為、ユーザーがJogDialを押し続けてもJogPressイベントが発生し、ユーザーが意図していないイベントが発生してしまいます。

解決する為には、JogPressイベントは「JogDialを押した判定には使わない」という方法があります。
それでは、どこでJogDialを押したという判定をするかというと、JogReleaseイベントを使用します。
JogDialを押せば必ず離す動作が必要な訳で、ユーザーには違和感無く感じると思います。

JogPressイベントに処理を入れた時は、JogDialが押された瞬間
 JogReleaseイベントに処理を入れた時には、JogDialが離された瞬間にイベントが発生します。

JogReleaseイベントにJogDialを押した判定を入れる事で、JogPressRepeat、JogPageUp、JogPageDownイベント判定時に
JogDialが押されただけなのか、それともそれ以外のイベントなのかを気にしなくて良くなります。

JogPressRepeatについて、上のフローを見てもらうと判りますが、必ずJogPressRepeatイベントの後に、
ジョグダイヤルを離す時がある為、JogReleaseが絶対に発生してしまいます。
その為、JogPressRepeatイベントを使う時には、直後に発生してしまう、JogReleaseに気を付ける必要があります。

対応方法の1つとしては、JogPressRepeatが発生した時には、フラグのセットだけを行って
その後で発生するハズのJogReleaseのイベントでフラグを判定して処理を振り分ける事で解決する事が可能です。


次にJogPageUp、JogPageDownですが、コレは、ユーザーにとっても作者にとっても難しいイベントでは無いでしょうか?
ユーザーはもたもた、押しまわしの操作を行うと、JogPressRepeatイベントが発生してしまいますし...
恐らくJogPressイベントからJogPressRepeatイベントまで1秒ないと思います。
そこで、JogPageUp、JogPageDownイベントの後にすぐにJogPressRepeatイベントが発生した場合に備えて
直前のイベントを覚えておいて、直前のイベントがJogPageUp、JogPageDownならば、JogPressRepeatイベントをキャンセルすればどうでしょう?
上手く行くのかも知れません。

おいらはユーザーに優しいアプリを作成するには押し回しで行う処理を作らないと考えています。
だって、おいらは押し回しが出来ないから...きっと他にもいるよね?

<JogDial機能拡張アプリを使用している場合>
PowerJOG、JogLauncher、JogCAT等が該当します。

PowerJOGの場合
ほとんど、プログラム的に気にする必要はありません。
ただ、JogPressイベント発生タイミングが押した時では無く、JogReleaseが発生する直前になっています。
対策としては、JogDialを押した時の処理をJogPressで行わず、JogReleaseで行う事で解決します。

また、JogPressRepeatが発生するとPowerJOGメニューが開く為、
極力JogPressRepeatイベントをNS Basicで使わないようにしておく事が望ましいようです。
JogLauncherの場合
JogLauncherが有効になっているとJogUpJogDownイベントはハードボタンの上下に置き換わります。
その為、JogDialのイベントはJogUpJogDown以外は通常通り認識出来ますが、
JogUpJogDownイベントはGetEventTypeではNsbKeyOrButton(1)が戻り値となり、GetKeyでは、11、12が戻り値となります

対策としては、GetEventTypeでNsbKeyOrButton(1)が認識された時にも処理を実行するようにしておくと良いでしょう。
※この事からも、JogDialとハードキーの動作内容を同じにしておいた方がユーザーの混乱が少ないようです

最新版のJogLauncherでは、特定のアプリ上でしか、ハードキーのエミュレートを行わなくなりました。
最新版を使う場合には、通常通りJogDialイベントが認識出来るようになります

また、PowerJOG同様にJogPressRepeatが発生するとJogLauncherメニューが開く為、
極力JogPressRepeatイベントをNS Basicで使わないようにしておく事が望ましいようです。
JogCATの場合
本来JogCATは、必要なPalmwareのみに機能拡張出来るような設定があるのですが、
ランタイムが別にあるNSBのアプリではJogCATの機能を除外する事が出来ません。

※NS BasicアプリにJogCATが対応されました。
 NS Basic製アプリも除外出来ます。

さらに、JogCATが有効時にNSBのアプリ上でJogDialを押すと(離すと?)予定表が起動してしまいます。
※正確には予定表ボタン(ハードキー)に割り当てられているPalmwareが起動してしまうようです。

この対策としては、SetEventHandledでJogDialイベントをキャンセルしてしまう事で解決します。

サンプルプログラム

    If GetEventType()=NsbJogDial Then
        theKey=Asc(GetKey())
        SetEventHandled
        Select Case thekey
        Case 0
            '---- "JogUp"
        Case 1
            '---- "JogDown"
        Case 2
            '---- "JogPressRepeat"
        Case 3
            '---- "JogPageUp"
        Case 4
            '---- "JogPageDown"
        Case 5
            '---- "JogPress"
        Case 6
            '---- "JogRelease"
        End Select
    End If

JogDialに対応させるつもりが無いアプリを作成する時も、SetEventHandled
JogDialのイベントをキャンセルするようにするとJogCAT動作中のClieで誤動作を防ぐ事が出来ると思います


サンプルプログラム

    If GetEventType()=NsbJogDial Then
        SetEventHandled
  End If

<しろクリのジョグアシストへの対応>
しろクリには、便利なジョグアシストという機能があります。
でも、Palmwareを開発するとなるとちょっと厄介です。

ジョグアシストは、表示中のフォームにスクロールバーがある時に
JogDialイベントを判別すると、NSBのアプリへイベントを渡す前にジョグアシストの方にイベントを取られてしまいます。

その為、正常にJogUpJogDownイベントが認識出来ません。

これに対する対策は現在見つかっていません。
暫定対策として、
・スクロールバーが存在する可能性がある場合、JogDialを使った処理を考えない
・JogDialのイベントを利用する時を限定し、その時はスクロールバー等を非表示にする。
 ※LinkMemoはフィールドオブジェクトを一時非表示にする事で対応しています。

出来れば、アシスト中であっても正常にJogUpJogDownイベントが認識出来ると非常に嬉しいのですが...


<バックボタンの機能について>
PEG-N700C以降の機種のClieではバックボタンが搭載されています。
その動作について解説します

ジョグアシスト時でのバックボタンの動作を解説します。

現在のフォーム内に存在する(表示されている)以下のラベルのボタンを押す事が出来ます。

選択の優先順序

同一順位のボタンが複数ある場合にはオブジェクトのインデックスが小さい方が押されます。
該当するボタンが無い場合には、ホームに戻ります(アプリケーション終了)
優先度ボタンのラベル
優先度1Cancelキャンセル(半角カナ)Previous戻る
優先度2Noいいえ閉じるClose
優先度3Done終了--
優先度4YesはいOK-
優先度5上記に該当しない場合にHomeに戻る

最後にアプリの初画面では、上記のボタンを置かない方が良いでしょう
ナゼなら初画面でバックボタンを押してもHomeに戻れなくなってしまいます


- Page End -