(57)【要約】携帯電話上で画像と対話する方法であって、携帯電話のディスプレイに画像を表示し、ユーザーが携帯電話の入力装置を使用してディスプレイのアクティブ領域を選択したことを検知し、ディスプレイのアクティブ領域に対応する携帯電話の機能を自動的に起動することを含む。システムおよびコンピュータ読み取り可能記憶格納媒体もまた記述され請求項の対象となる。【選択図】  図１
2008516482.tif 000002
【特許請求の範囲】
【請求項１】
携帯電話上の対話型画像生成の方法であり、
携帯電話のディスプレイに画像を表示することと、
ユーザーが前記携帯電話の入力装置を使用して前記ディスプレイのアクティブ領域を選択したことを検知することと、及び、
前記ディスプレイの前記アクティブ領域に対応する前記携帯電話の機能を自動的に起動することと、を含む方法。
【請求項２】
前記入力装置はライトペンである請求項１に記載の方法。
【請求項３】
前記入力装置はキーパッドである請求項１に記載の方法。
【請求項４】
前記携帯電話の前記機能はダイヤル機能である請求項１に記載の方法。
【請求項５】
前記携帯電話の前記機能は表示機能である請求項１に記載の方法。
【請求項６】
前記画像はパノラマシーンの一部分である請求項１に記載の方法。
【請求項７】
前記ディスプレイの前記アクティブ領域は矩形の領域である請求項１に記載の方法。
【請求項８】
携帯電話から成る対話型画像生成のシステムであって、前記携帯電話が、
前記携帯電話に収納され、画像を表示するディスプレイと、及び、
前記携帯電話の内部に収納され、前記ディスプレイに結合され、ユーザーが前記携帯電話の入力装置を使用して前記ディスプレイのアクティブ領域を選択したことを検知し、前記ディスプレイの前記アクティブ領域に対応する前記携帯電話の機能を自動的に起動するプロセッサと、を備えるシステム。
【請求項９】
前記入力装置はライトペンである請求項８に記載のシステム。
【請求項１０】
前記入力装置はキーパッドである請求項８に記載のシステム。
【請求項１１】
前記携帯電話の前記機能はダイヤル機能である請求項８に記載のシステム。
【請求項１２】
前記携帯電話の前記機能は表示機能である請求項８に記載のシステム。
【請求項１３】
前記画像はパノラマシーンの一部分である請求項８に記載のシステム。
【請求項１４】
前記ディスプレイの前記アクティブ領域は矩形の領域である請求項８に記載のシステム。
【請求項１５】
プログラムコードを格納するコンピュータ読み取り可能記憶媒体であって、前記プログラムコードはコンピュータに、
携帯電話のディスプレイに画像を表示するステップと、
ユーザーが前記携帯電話の入力装置を使用して前記ディスプレイのアクティブ領域を選択したことを検知するステップと、及び、
前記ディスプレイの前記アクティブ領域に対応する前記携帯電話の機能を自動的に起動するステップと、を実行させるコンピュータ読み取り可能記憶媒体。
【請求項１６】
携帯電話上の対話型画像生成の方法であり、
携帯電話が現在インターネットに接続されているか否かを判断することと、
接続されていれば、
サーバーコンピュータに画像データを要求し、
前記要求した画像データを受信し、
前記携帯電話に格納されたローカル画像データと、前記要求した画像データに基づいて前記携帯電話のディスプレイに画像を表示し、
接続されていなければ、
携帯電話に格納されたローカル画像データに基づいて前記携帯電話の前記ディスプレイに画像を表示することと、
ユーザーが前記携帯電話の入力装置を使用して前記ディスプレイのアクティブ領域を選択したことを検知することと、及び、
前記ディスプレイの前記アクティブ領域に対応する前記携帯電話の機能を自動的に起動することと、を含む方法。
【請求項１７】
携帯電話から成る携帯電話上の対話型画像生成のシステムであり、前記携帯電話が、
前記携帯電話内に収納され、前記携帯電話が現在インターネットに接続されているか否かを判断する接続検出器と、
前記携帯電話内に収納され、サーバーコンピュータに画像データを要求する送信機と、
前記携帯電話内に収納され、前記要求した画像データを受信する受信機と、
前記携帯電話に格納されたローカル画像データと前記要求した画像データを使用して画像を表示する前記携帯電話上のディスプレイと、及び、
前記接続検出器と、前記送信機と、前記受信機と、前記ディスプレイに結合され、ユーザーが前記携帯電話の入力装置を使用して前記ディスプレイのアクティブ領域を選択したことを検出し、前記ディスプレイの前記アクティブ領域に対応する前記携帯電話の機能を自動的に起動する、前記携帯電話内のプロセッサと、を備えるシステム。
【請求項１８】
プログラムコードを格納するコンピュータ読み取り可能記憶媒体であって、前記プログラムコードはコンピュータに、
携帯電話が現在インターネットに接続されているか否かを判断するステップと、
接続されていれば、
サーバーコンピュータに画像データを要求し、
前記要求した画像データを受信し、
前記携帯電話に格納されたローカル画像データと、前記要求した画像データに基づいて前記携帯電話のディスプレイに画像を表示し、
接続されていなければ、
前記携帯電話に格納されたローカル画像データに基づいて携帯電話の前記ディスプレイに画像を表示するステップと、
ユーザーが前記携帯電話の入力装置を使用して前記ディスプレイのアクティブ領域を選択したことを検知するステップと、及び、
前記ディスプレイの前記アクティブ領域に対応する前記携帯電話の機能を自動的に起動するステップと、を実行させるコンピュータ読み取り可能格納媒体。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、画像を表示する携帯電話に関する。
【背景技術】
【０００２】
携帯電話上のカラーディスプレイと、ソフトウェアアプリケーションを開発するオペレーティングシステムの出現により、デジタル画像は多様なアプリケーションにおいて携帯電話で使用されている。画像の美的価値はさておき、情報という観点からは、デジタル画像は、小さな携帯電話のディスプレイでテキストが伝達できるよりも遥かに大量の情報を伝達する。１つの絵は千語に値する。例えば、ある場所から別の場所へ行くための道順を見つけたいと望んでいる携帯電話のユーザーを考えてみると、地図の画像はテキストによる記述よりもはるかに大量の情報を伝達する。
【０００３】
今日では、多くの携帯電話はユーザーと、メニュー駆動のテキスト選択で対話する。そのようなインタフェースは面倒であり、各段階がキーの押下またはライトペンのタップを含む、ユーザー選択の多数の段階がしばしば含まれる。画像の使用は、インタフェースの簡略化および加速化という優位点を有する。
【０００４】
このように、携帯電話のユーザーが所望する情報を簡単かつ迅速な方法で見つけることを可能にする、直感的かつ美的なユーザーインターフェースを有する対話型画像生成アプリケーションが必要とされている。
【発明の開示】
【０００５】
本発明は、携帯電話上での対話型画像生成の方法およびシステムを提供する。本発明を使用すれば、携帯電話は、ユーザーが種々のサイトの仮想ツアーを対話的に見ることができ、また「ホットスポット」により１つのツアーから別のツアーへジャンプすることができるソフトウェアまたはハードウェアを動作させることができる。ホットスポットは、仮想ツアー内のアクティブ領域であり、ユーザーはアクティブ領域に固有の仮想ツアーへジャンプするためにホットスポットを起動できる。例えば、ユーザーは、市街地図内に位置するサイトのホットスポットを起動することにより、市街地図から、関心対象のサイトの仮想ツアーへジャンプできる。更に、本発明の好適な実施形態によれば、ホットスポットを、ダイヤル機能のような、携帯電話の機能を自動的に起動するために使用できる。例えば、あるサイトの仮想ツアーを見ているユーザーは、仮想ツアー内のホットスポットを起動することにより、そのサイトのオフィスへ自動的に電話をかけることができる。
【０００６】
本発明は好ましくは、仮想ツアー内に３つの表示画像を設ける。それは（ｉ）地図表示画像（map view）と、（ｉｉ）「目の視点での表示画像（eye view）」と、（ｉｉｉ）メタ表示画像（meta-view）である。好ましくは、地図表示画像は、仮想ツアーの全体地図を示し、ユーザーはそれにより仮想ツアーが現在どこに位置しているかを知ることができる。好ましくは、目の視点での表示画像は、全体地図内に位置するあるサイトのパノラマシーンを示す。目の視点での表示画像はまた、サイトのより精細で詳細な地図も示すことができる。好ましくは、メタ表示画像は、仮想ツアーを行っているサイトを記述する情報テキストを示す。ユーザーは、携帯電話上の特定のキーを押すことにより、またはライトペンでディスプレイの領域をタップすることによりこれら３つの表示画像を切替えることができる。
【０００７】
このように、本発明は、携帯電話のディスプレイに表示された対話型仮想ツアー内のホットスポットに、携帯電話の機能を自動的にリンクする機能を提供するということは理解されよう。
【０００８】
本発明の好適な実施形態によれば、携帯電話のディスプレイに画像を表示することと、ユーザーが携帯電話の入力装置を使用してディスプレイのアクティブ領域を選択したことを検知することと、そのディスプレイのアクティブ領域に対応する携帯電話の機能を自動的に起動することとを含む、携帯電話上の対話型画像生成の方法がこのように提供される。
【０００９】
本発明の好適な実施形態によれば、携帯電話上に収納され、画像を表示するディスプレイと、携帯電話の内部に収納され、ディスプレイに結合され、ユーザーが携帯電話の入力装置を使用してディスプレイのアクティブ領域を選択したことを検知し、そのディスプレイのアクティブ領域に対応する携帯電話の機能を自動的に起動するプロセッサと、から成る携帯電話を含む対話型画像生成のシステムが更に提供される。
【００１０】
本発明の好適な実施形態によれば、コンピュータに、携帯電話のディスプレイに画像を表示するステップと、ユーザーが携帯電話の入力装置を使用してディスプレイのアクティブ領域を選択したことを検知するステップと、そのディスプレイのアクティブ領域に対応する携帯電話の機能を自動的に起動するステップと、を実行させるプログラムコードを格納するコンピュータ読み取り可能記憶媒体が更に提供される。
【００１１】
本発明の好適な実施形態によれば、携帯電話が現在インターネットに接続されているか否かを判断することと、接続されていれば、サーバーコンピュータに画像データを要求し、要求した画像データを受信し、携帯電話に格納されたローカル画像データと要求した画像データに基づいて携帯電話のディスプレイに画像を表示し、接続されていなければ、携帯電話に格納されたローカル画像データに基づいて携帯電話のディスプレイに画像を表示することと、ユーザーが携帯電話の入力装置を使用してディスプレイのアクティブ領域を選択したことを検知することと、そのディスプレイのアクティブ領域に対応する携帯電話の機能を自動的に起動することと、を含む携帯電話上の対話型画像生成の方法が更に提供される。
【００１２】
本発明の好適な実施形態によれば、携帯電話内に収納され、携帯電話が現在インターネットに接続されているか否かを判断する接続検出器と、携帯電話内に収納され、サーバーコンピュータから画像データを要求する送信機と、携帯電話内に収納され、要求した画像データを受信する受信機と、携帯電話に格納されたローカル画像データと要求した画像データを使用して画像を表示する携帯電話上のディスプレイと、接続検出器と、送信機と、受信機と、ディスプレイに結合され、ユーザーが携帯電話の入力装置を使用してディスプレイのアクティブ領域を選択したことを検出し、そのディスプレイのアクティブ領域に対応する携帯電話の機能を自動的に起動するための、携帯電話内のプロセッサと、から成る携帯電話を含む、携帯電話上の対話型画像生成のシステムが追加的に提供される。
【００１３】
プログラムコードを格納するコンピュータ読み取り可能記憶媒体であり、プログラムコードはコンピュータに、携帯電話が現在インターネットに接続されているか否かを判断するステップと、接続されていれば、サーバーコンピュータから画像データを要求し、要求した画像データを受信し、携帯電話に格納されたローカル画像データと、要求した画像データに基づいて携帯電話のディスプレイに画像を表示し、接続されていなければ、携帯電話に格納されたローカル画像データに基づいて携帯電話のディスプレイに画像を表示するステップと、ユーザーが携帯電話の入力装置を使用してディスプレイのアクティブ領域を選択したことを検知するステップと、そのディスプレイのアクティブ領域に対応する携帯電話の機能を自動的に起動するステップと、を実行させるコンピュータ読み取り可能記憶媒体。
【発明を実施するための最良の形態】
【００１４】
本発明は、携帯電話上の対話型画像生成の方法とシステムに関する。
【００１５】
本発明は好ましくは、中央処理装置、プログラムとデータを格納するメモリ装置、キーパッド、およびディスプレイを含む携帯電話内で実現される。好ましくは、中央処理装置、メモリ装置、およびキーパッドとディスプレイのデバイスドライバは、従来のデータバスを使用して通信可能に結合される。好ましくは、中央処理装置はシンビアン（Symbian）ＯＳのようなオペレーティングシステムを実行する。
【００１６】
図１Ａ〜図２Ｇ（図１〜図２−４）は、ノキア（Nokia）の携帯電話内の本発明の動作を示す。
【００１７】
ここで図１Ａを参照すると、キーパッド１１０と、コントロールボタンと、カラーディスプレイ１２０を含むノキアシリーズ（Nokia Series）６０スマート携帯電話１００が示されている。キーパッド１１０は１０個の数字１〜０の従来のボタンと、「＊」と「＃」のボタンを含む。コントロールボタンは、４個の方向ボタン１３０、「ＯＫ」ボタン１４０、およびディスプレイ１２０の左下と右下に現れるコマンドを起動するためのボタン１５０を含む。当業者には、画面のタップ用のライトペンなど、他の入力装置もまた、キーボード１１０とボタン１３０、１４０、および１５０の代わりに、またはそれらと共に使用できるということは理解されよう。そのような入力装置は、例えば、ソニーエリクソン（Sony Ericsson）携帯電話に装備されている。
【００１８】
携帯電話１００が起動すると、電話にロードされた種々のアプリケーション用のアイコン１６０がディスプレイ１３０に現れる。現在選択されているアプリケーションは、それを取り囲むボックス枠１７０により特定される。
【００１９】
ユーザーは、方向ボタン１３０を押すことにより種々のアイコン間を移動できる。ユーザーは、ＯＫボタン１４０を押すことにより選択されたアプリケーションを始動できる。
【００２０】
そのような１つのアイコン１６０は、本発明の好適な実施形態に従う「アイシービュー（iSeeVU）」という名称の対話型画像生成アプリケーション用である。アイシービューが始動されると、図１Ｂに示すように、地図のリストがディスプレイ１２０に現れる。各地図は以下に記述するように、１つ以上のサイトの仮想ツアーである。
【００２１】
現在選択されている地図は斜線の入ったテキストにより示される。ユーザーは、上下方向ボタン１３０を押すことにより地図のリスト間を上下に移動でき、「ＯＫ」ボタンを押すことにより現在選択されている地図を起動できる。
【００２２】
ここで図２Ａを参照すると、ディスプレイ１２０にパディントン（Paddington）の仮想ツアー用の地図が現された携帯電話１００が示されている。パディントン地図は、ディスプレイ１２０の表示領域よりも大きいが、４個の方向ボタン１３０を使用して左右上下に移動することができる。
【００２３】
パディントン地図内には、「ホットスポット」と称される、正方形のアイコンで示されるアクティブ領域２０５がある。以下に記述するように、ユーザーがホットスポットを起動すると、仮想ツアーは１つの表示から別の表示にジャンプする。現在使用中のホットスポット２１０は、二重線の太い境界線２１５で指定されている。図２Ａに示す図では、パディントン駅のホットスポットが、現在使用中のホットスポットである。これはまた、ディスプレイ１２０の上部の記述２２０によっても明白となる。好ましくは、ユーザーは、「＊」キーを押すことにより１つのホットスポットから別のホットスポットに移動し、ユーザーは、「ＯＫ」ボタンを押すことにより現在選択されているホットスポットを起動する。
【００２４】
ここで図２Ｂを参照すると、ディスプレイ１２０の上部に「聖マリー病院（St. Mary's Hospital）」と記載されている、現在選択されている別のホットスポット２２５が示されている。ホットスポット２２５は、パディントンの地図において、プリードストリート（Praed Street）とノーフォーク（Norfolk）の交差点に位置している。
【００２５】
ユーザーが「ＯＫ」ボタンを押すことによりホットスポット２２５を起動すると、仮想ツアーは、図２Ｃに示すように、プリードストリートにある聖マリー病院のパノラマシーンへジャンプする。地図表示画像から、「目の視点による表示画像（Eye View）」と称されるパノラマシーンへの切替えはまた、タブ２３０と２３５によっても示されている。好ましくは、ユーザーはキーパッド１１０上の「１」キーを押すことにより、地図表示画像とパノラマシーンを切替えることができる。実際は、図２Ｆを参照して下記に記述するように、ユーザーが選択できる「メタ表示画像（Meta View）」と称される第３の表示画像があり、ユーザーはこの３つすべての表示画像間で切替えることができる。
【００２６】
聖マリー病院のパノラマシーンはディスプレイ１２０に収まりきれないほど大きい。好ましくは、ユーザーは、携帯電話上の方向ボタンを押すことにより、パノラマ内を移動できる。図２Ｄを参照すると、ユーザーが左方向矢印を押したときの聖マリー病院の表示画像が示されている。図２Ｃと図２Ｄの間でパノラマが移動した距離は、ホットスポット２４０により明白である。図２Ｃにおいて、ホットスポット２４０は、ディスプレイ１２０の中心近くに位置しており、図２Ｄでは、ホットスポット２４０は、右に移動している。
【００２７】
図２Ａのパディントン駅に戻って、ユーザーがホットスポット２１０を起動したとき、仮想ツアーは、図２Ｅに示されるパディントン駅のパノラマ画像にジャンプする。図２Ｅには、ディスプレイ１２０の上部に「メタ／一般情報（META/General Information）」と記述されたホットスポット２４５が示されている。ホットスポット２４５は、情報ホットスポットである。ユーザーがホットスポット２４５を起動すると、表示画像は、図２Ｆに図示されまたタブ２３５と２５０に示されるように、目の視点による表示画像からメタ表示画像に切替わる。図２Ｆには、メタデータと称される、パディントン駅に関する情報テキストが示されている。この情報の下には、パディントン駅に関連する種々のサービスを呼出すための電話ホットスポット２５５がある。好ましくは、ユーザーは「＊」キーを押すことにより電話ホットスポット間を移動する。現在選択されている電話ホットスポット２６０は、それを囲む正方形の枠２６５により示されている。ユーザーは、「ＯＫ」ボタンを押すことにより選択されている電話ホットスポットを起動する。
【００２８】
ここで図２Ｇを参照するが、この画面はユーザーが「テームズトレイン（Thames Trains）」ホットスポットを起動した後に現れる。テームズトレインの電話番号はディスプレイ１２０に現れる。ユーザーが左ボタン１５０を押して「Ｙｅｓ」を選択すると、携帯電話１００は自動的にその電話番号をダイヤルする。
【００２９】
ここで図３Ａ〜図３Ｈを参照すると、ロンドン（London）の仮想ツアーが示されている。そのような仮想ツアーは、ユーザーが、図１Ｂに示される地図のリストから「ロンドン」を選択して「ＯＫ」ボタンを押すと起動される。
【００３０】
図３Ａには、携帯電話１００の上部の記述３２０に示されるように、グレーターロンドン（Greater London）に対して現在選択されているホットスポット３１０を伴うロンドンの地図が示されている。右移動方向ボタン１３０を押すことにより、地図は右に移動する。地図の移動は、図３Ａにおけるホットスポット３１０の位置を、図３Ｂの位置と比較することにより明白である。
【００３１】
ユーザーが「ＯＫ」ボタン１４０を押すことによりホットスポット３１０を起動すると、仮想ツアーは、ロンドンの地図表示画像（Map View）から、図３Ｃに示すグレーターロンドンの目の視点による表示画像（Eye View）にジャンプする。図３Ｃの地図は種々のホットスポット３３０を含み、現在選択されているホットスポット３４０は、ワーテルロー（Waterloo）の地図へのジャンプ用である。
【００３２】
ユーザーが「ＯＫ」ボタンを押すことによりホットスポット３４０を起動すると、仮想ツアーはグレーターロンドンの目の視点による表示画像（Eye View）から図３Ｄに示されるワーテルローの目の視点による表示画像（Eye View）へジャンプする。今度は、ワーテルローの地図はゴールデンジュビリーブリッジ（Golden Jubilee Bridge）へジャンプするためのホットスポット３５０を含む。
【００３３】
ユーザーが「ＯＫ」ボタン１４０を押すことによりホットスポット３５０を起動すると、仮想ツアーは図３Ｅに示されるゴールデンジュビリーブリッジのパノラマシーンにジャンプする。パノラマシーンは、ワーテルロー地図にジャンプして戻るためのホットスポット３６０を含む。ユーザーは、方向ボタン１３０を押すことによりパノラマ画像間を移動する。ユーザーはまた、「＊」を押すことによりホットスポット間を移動することもできる。図３Ｆは、図３Ｅに示された区域から約９０°回転した、メタデータホットスポット３７０を含むパノラマシーンの区域を示している。
【００３４】
ユーザーが「ＯＫ」ボタン１４０を押すことによりホットスポット３７０を起動すると、図３Ｇに示される情報テキストがディスプレイに現れる。図３Ｇには電話ホットスポット３８０が示され、ユーザーは「ＯＫ」ボタン１４０を押すことによりそれを起動できる。ユーザーがホットスポット３８０を起動すると、図３Ｈのように電話番号が表示され、ユーザーは左ボタン１５０を押すことによりディスプレイ上の左下にある「Ｙｅｓ」コマンドを選択する。これに応答して、携帯電話１００は、表示された電話番号を自動的にダイヤルする。
【００３５】
本発明は好ましくは、ホットスポットが起動されたときに、ホットスポットの領域と取るべき行動を規定するXML文書を介して実現される。ここで、本発明の好適な実施形態による、図２Ａ〜図２Ｇに示されたパディントンの仮想ツアーを実現するために使用されるXML文書のリストである付録Ａ１を参照する。リストから分かるように、ImageFileのタグは、図４Ａに示されるJPEG画像Paddington_map.jpgを参照する。なお、画像はその中に埋め込まれたホットスポットのアイコンを有している。
【００３６】
付録Ａにおけるリストはまた、複数のホットスポットを含む。ユーザーが携帯電話の「＊」キーを押すといつでも、ホットスポットを進めることになる。各ホットスポットは、（ｉ）正規化された座標に基づく、ディスプレイ内のホットスポットの矩形の位置と、（ｉｉ）ホットスポットのXMLファイルと、（ｉｉｉ）ホットスポットの簡単な記述を含む「参考」を指定する。このように、聖マリー病院のホットスポットは、その幅が０.５５８から０.６に広がり、高さは０.６２０５８８から０.６７９４１２に広がる。これらの座標はディスプレイ全体が１の幅および高さを有するように正規化されている。聖マリー病院のホットスポットは、St_marys_hospital.xmlという名前のXMLファイルを参照し、「聖マリー病院」というテキストの「参考」を備えている。このように、このホットスポットが現在選択されているホットスポットのときは、図２Ｂに示すように「聖マリー病院」というテキストが携帯電話のディスプレイに現れる。このホットスポットがユーザーにより選択されると、仮想ツアーは、聖マリー病院のXMLファイルにジャンプする。
【００３７】
聖マリー病院のXMLファイルは、本発明の好適な実施形態による付録Ａ２にリストされている。このリストは、図４Ｂに示される球形パノラマ画像St_marys_hospital.jpgを参照する。パノラマ画像のタグは、視野の垂直フィールドおよびピッチ範囲のようないくつかの視覚パラメータを含む。リストはまた２つのホットスポットを参照し、その１つは「プリードサウスワーフ（Praed South Wharf）」でありもう１つは、「プリードロンドンストリート（Praed London St）」である。なお、パノラマ画像は、その中に組み込まれた２つのホットスポットのアイコンを有している。
【００３８】
パディントン駅のXMLファイルは、本発明の好適な実施形態による付録Ａ３にリストされている。このファイルは、付録Ａ１にリストされているパディントン駅のホットスポットから呼び出される。このリストは、図４Ｃに示される球形パノラマ画像paddinton_station_interior.jpgを参照する。付録Ａ３のリストは２つのホットスポットを示しており、１つは「プリードストリートへの歩道（Walkway to Praed St.）」と示され、もう１つは「メタ／一般情報テキスト」と示されている。一般情報テキストファイルは図２Ｆに示されたテキストを含む。電話ホットスポットの絵は図４Ｄに示されている。
【００３９】
携帯電話の自動ダイヤリングは好ましくは、シンビアンオペレーティングシステム機能であるcall.OpenNewCall (line, newCallName)およびcall.Dial (aPhoneNumber)を介して実現され、lineはシンビアンクラスRLineのインスタンスであり、callはシンビアンクラスRCallのインスタンスである。
【００４０】
上記の記述を読めば、当業者であれば、上述の方法およびシステムに適用可能な多数の明白な変形例があることを理解するであろう。このように、本明細書は、すでに携帯電話に格納されている画像コンテンツの対話型画像生成を記述したが、ある代替実施形態においては、画像コンテンツは、サーバーコンピュータから動的にダウンロードできる。具体的には、携帯電話のユーザーが、図１Ａに示すアイシービューソフトウェアアプリケーションをサーバーコンピュータからダウンロードすると、そのダウンロードにはすべての画像コンテンツを含むか、一部の画像コンテンツを含むか、またはまったく画像コンテンツを含まないかもしれない。更に、携帯電話がアイシービューアプリケーションを実行するとき、携帯電話はインターネットに接続されていても、いなくてもよい。携帯電話がインターネットに接続されていないと、携帯電話は利用できるローカルコンテンツは何でも使用してアイシービューアプリケーションを実行する。携帯電話がインターネットに接続されていると、携帯電話がオンデマンドでコンテンツを引き出すか、サーバーが携帯電話にコンテンツを送るかのいずれかにより、携帯電話はサーバーからコンテンツをダウンロードする。
【００４１】
コンテンツを動的にダウンロードできる機能は、とりわけ、ユーザープロフィールに基づいてカスタムコンテンツをユーザーが利用可能にする機能、およびコンテンツを定期的に変更するという機能を含む、付加的機能を可能にする。
【００４２】
上述した明細書において、本発明は、その具体的な典型的実施形態を参照して記述された。しかし、付随する請求項に記載される本発明のより広い精神および範囲を逸脱することなく、この具体的な典型的実施形態に対して、種々の変形および変更が可能であることは明白であろう。従って、本明細書と図は、限定的な意味ではなく、例示的な意味を持つものと見なされるべきである。
【図面の簡単な説明】
【００４３】
【図１】図１Ａ＆図１Ｂ：本発明の好適な実施形態による、対話型画像生成アプリケーションを実行するノキア（Nokia）スマート携帯電話を示している。図１ＡApplication:アプリケーションTO-DO:予定事項リストHelp:ヘルプCommunic~:通信Tool:ツールConfigura:構成Option:オプションExit:終了iSeaVU:アイシービューLogs:ログ図１ＢiSeaVU:アイシービューMap view:地図表示画像London:ロンドンPaddington:パディントンReal estate demo:不動産デモRome:ローマWaterloe:ワーテルローCancel:キャンセル
【図２−１】図２Ａ＆Ｂ：本発明の好適な実施形態による、携帯電話上に表示されたパディントン駅（Paddington Station）の仮想ツアーを示している。図２ＡPaddington Station:パディントン駅Map View:地図表示画像Help:ヘルプExit:終了図２ＢSt. Mary's Hospital:聖マリー病院Help:ヘルプExit:終了S Waarf Road:ＳワーフロードPREED:プリードNORFOLK:ノーフォークMap View:地図表示画像
【図２−２】図２Ｃ＆Ｄ：同上図２ＣPread St. Mary's:プリード聖マリーEye View:目の視点での表示画像Help:ヘルプExit:終了図２ＤPread St. Mary's:プリード聖マリーEye View:目の視点での表示画像Help:ヘルプExit:終了
【図２−３】図２Ｅ＆Ｆ：同上図２ＥMETA/General information:メタ／一般情報Eye View:目の視点での表示画像Help:ヘルプExit:終了図２ＦPhone:電話説明：パディントン駅へようこそ。この駅は最初、１８５４年にオープンし、最近再開発されました。Heathrow  Express:ヒースロー急行Thamas train:テームズトレインHelp:ヘルプExit:終了
【図２−４】図２Ｇ：同上図２ＧPhone:電話説明：パディントン駅へようこそ。この駅は最初、１８５４年にオープンし、Phone:電話Dial this number?:この番号をダイヤルしますか？
【図３−１】図３Ａ＆Ｂ：本発明の好適な実施形態による、携帯電話上に表示されたロンドン（London）の仮想ツアーを示している。図３ＡGreater London:グレーターロンドンMap View:地図表示画像Help:ヘルプExit:終了図３ＢGreater London:グレーターロンドンMap View:地図表示画像Help:ヘルプExit:終了
【図３−２】図３Ｃ＆Ｄ：同上図３ＣWaterloo:ワーテルローEye View:目の視点での表示画像Help:ヘルプExit:終了図３ＤGoldenjablee bridge:ゴールデンジャブリーブリッジEye View:目の視点での表示画像Help:ヘルプExit:終了
【図３−３】図３Ｅ＆Ｆ：同上図３ＥWaterloo:ワーテルローEye View:目の視点での表示画像Help:ヘルプExit:終了図３ＦWaterloo:ワーテルローEye View:目の視点での表示画像Help:ヘルプExit:終了
【図３−４】図３Ｇ＆Ｈ：同上図３ＧPhone:電話説明：息をのむような新しい庭園で、ロンドンの最も人気のある場所の１つで、園芸家の夢であり、王族の住まいであるウィンザー城への見学は、Call for more info.:更なる情報は、電話をHelp:ヘルプExit:終了図３ＨPhone:電話説明：息をのむような新しい庭園で、ロンドンの最も人気のある場所の１つで、園芸家の夢で、〜Dial this number?:この番号をダイヤルしますか？
【図４−１】図４Ａ：本発明の好適な実施形態による、パディントン駅（Paddington Station）の仮想ツアーを生成するために使用される画像である。図４ＡBISHOP BRIDGE ROAD:ビショップブリッジロードLondon Street:ロンドンストリートS Wharf Street:SウヮーフストリートPREAD STREET:プリードストリートChapel Street:チャペルストリートFINISH:完了SALE PL:セールPLSUSSEX GARDENS:サセックスガーデンPaddington Station:パディントン駅EASTBOURRNETER:イーストバーンターSTART:スタートWinsland Street:ウィンズランドストリートNORFORK:ノーフォーク
【図４−２】図４Ｂ＆Ｃ＆Ｄ：同上図４ＤNational Rail equiry service:国有鉄道問合せサービスFirst Great Western:ファーストグレートウェスタンHeathrow Express:ヒースロー急行Thames Train:テームズトレインLeft luggage:置き忘れ荷物Lost property:紛失物説明：更に電話呼出しを表示するには左右にドラッグしてください。アイコンをタップすれば電話をか〜
【符号の説明】
【００４４】
１００：携帯電話
１１０：キーパッド
１２０：カラーディスプレイ
１３０：４個の方向ボタン１３０
１４０：「ＯＫ」ボタン
１５０：左下と右下に現れるコマンドを起動するためのボタン
１６０：電話にロードされた種々のアプリケーション用のアイコン
１７０：ボックス枠
２０５：正方形のアイコンで示されるアクティブ領域
２１０：現在使用中のホットスポット
２１５：二重線の太い境界線２１５
２２０：記述
２２５：現在選択されている別のホットスポット
２３０：タブ
２３５：タブ
２４０：ホットスポット
２４５：ホットスポット
２５０：タブ
２５５：電話ホットスポット
２６０：現在選択されている電話ホットスポット
２６５：正方形の枠
３１０：現在選択されているホットスポット
３２０：記述
３３０：種々のホットスポット
３４０：ホットスポット
３５０：ホットスポット
３７０：メタデータホットスポット
３８０：電話ホットスポット
【００４５】
（付録）
付録Ａ１〜Ａ４は、本発明の好適な実施形態による、対話型画像生成のシステムを実現するために使用されるXMLファイルのソースリストである。
[0046] APPENDIX Al
[0047] <?xml version = "1.0" ?> <VirtualTourLocatio[pi]>
[0048] <ImageNavigator>
[0049] <ImageFile>PHOTOS/paddington_map.jpg</ImageFile>
[0050] <ViewerType>.l2D</ViewerType> </ImageNavigator> < Hotspot>
[0051] <Position>0.26 0.688235 0.302 0.750035</Position> <XMLSource>XML/paddington_station_interior.xml</XMLSource>
[0052] <Tip>Paddington Station</Tip> </Hotspot> < Hotspot>
[0053] <Position>0.74 0.370588 0.78 0.432353 </Position>
[0054] <XMLSource>XML/sale_place.xml</XMLSource>
[0055] <Tip>Sale Place</Tip> </Hotspot> <Hotspot>
[0056] <Position>0.67 0.461765 0.712 0.523529</Position>
[0057] <XMLSource>XML/south_wharf_road.xml</XMLSource>
[0058] <Tip>South Wharf</Tip> </Hotspot> <Hotspot>
[0059] <Position>O.558 0.620588 0.6 0.679412</Positio[pi]>
[0060] <XMLSource>XML/st_marys_hospital.xml</XMLSource>
[0061] <Tip>St. Mary's Hospital</Tip> </H[omicron]tspot> <Hotspot>
[0062] <Position>0.346 0.752941 0.388 0.814706</Position>
[0063] <XMLSource>XML/london_street.xml</XMLSource>
[0064] <Tip>London St</Tip> </Hotspot> <Hotspot>
[0065] <Position>O.836 0.220588 0.878 0.282388</Position> <XMLSource>XML/hilton_londo[pi]_metropole.xml </XMLSource>
[0066] <Tip>Hilton London Metropole</Tip> </Hotspot> </VirtualTourLocation> 
[0067] APPENDIX A2
[0068] <?xml version = "1.0" ?> <VirtualTourLocation>
[0069] <ImageNavigator>
[0070] <ImageFile>PHOTOS/st_marys_hospital.jpg</ImageFile>
[0071] <ViewerType>Pano</ViewerType>
[0072] < panotype>SPHERE</panotype>
[0073] < pitchRange>-0.231 0.231 </pitchRange>
[0074] <vFov>-O.231 0.231</vFov>
[0075] <initialView>0.00286517 84.7636 26.4649</i[pi]itialView>
[0076] <Autospin>0</Autospin> </ImageNavigator> < Hotspot>
[0077] <XMLSource>XML/south_wharf_road.xml</XMLSource>
[0078] < Position>0.21572 0.730924 0.231289 0.904535</Position>
[0079] <Tip>Praed South Wharf</Tip> </Hotspot> < Hotspot>
[0080] <XMLSource>XML/london_street.xml</XMLSource>
[0081] < Position>0.752424 0.823293 0.767659 O.995984</Position>
[0082] <Tip>Praed London St</Tip> </Hotspot> </VirtualTourLocation>
[0083] APPENDIX A3
[0084] <?xml version = "1.0" ?> <VirtualTourLocation>
[0085] <ImageNavigator>
[0086] <ImageFile>PHOTOS/paddington_station_interior.jpg</ImageFile>
[0087] <ViewerType>Pano</ViewerType>
[0088] <panotype>SPHERE</panotype>
[0089] < pitchRange>-0.236 0.236</pitchRange>
[0090] <vFov>-O.236 0.236</vFov>
[0091] <i[pi]itialView>0.00286517 148.971 27.0379</initialView>
[0092] <Autospin>0</Autospin> </ImageNavigator> <Hotspot>
[0093] <XMLSource>XML/london_street.xml</XMLSource>
[0094] <Position>0.380086 0.650602 0.395028 0.817046</Position>
[0095] <Tip> Walkway To Praed St. </Tip> </Hotspot> <Hotspot>
[0096] <XMLSource>XML/paddington_Ge[pi]Info_meta.xml</XMLSource>
[0097] < Position>0.292291 0.666667 0.308291 O.847667</Position>
[0098] <Tip>META\General Information. txt</Tip> </Hotspot> </VirtualTourLocation> APPENDIX A4
[0099] <?xml version = "1.0" ?> <VirtualTourl_ocation>
[0100] <ImageNavigator>
[0101] <ImageFile>PHOTOS/paddington_GenInfo_meta.jpg</ImageFile>
[0102] <ViewerType>J2D</ViewerType> </ImageNavigator> <Hotspot>
[0103] <XMLSource>XML/paddington_station_interior.xml</XMLSource>
[0104] <Position>0.0148 0.111 0.0529 0.444</Position>
[0105] <Tip> Phone / +44 8457 484950</Tip> </Hotspot> < Hotspot>
[0106] <XML[Xi]ource>XML/paddington_station_i[pi]terior.xml </XMLSource>
[0107] <Position>0.229 0.143 0.2682 0.461 </Position>
[0108] <Tip>Phone / +44 8456 005604</Tip> </Hotspot> < Hotspot>
[0109] <XMLSource>XML/paddington_station_interior.xml</XMLSource>
[0110] <Position>0.403 0.127 0.4423 0.445</Position >
[0111] <Tip>Phone / +44 8456 001515</Tip> </Hotspot> < Hotspot>
[0112] <XMLSource>XML/paddington_station_interior.xml </XMLSource>
[0113] <Position>0.564 0.143 0.6032 0.461</Position>
[0114] <T[iota]p>Phone / +44 8453 303728</Tip> </Hotspot> <Hotspot>
[0115] <XMLSource>XML/paddington_station_interior.xml </XMLSource>
[0116] <Position>O.71 0.111 0.7492 0.444</Position>
[0117] <Tip>Phone / +44 2072 620344</Tip> </Hotspot> <Hotspot>
[0118] <XMLSource>XML/paddington_station_interior.xml </XMLSource>
[0119] < Position>0.852 0.127 0.8914 0.445</Position>
[0120] <Tip>Phone / +44 2072 620344</Tip> </Hotspot> </VirtualTourLocation> 
[0121] APPENDIX Bl
[0122] const Tint KMaxPhoneLength = 0x10;
[0123] CHintController: :CHintController(): ipProjectManager(NULL), ipDrawEngine(NULL), ipProjectSniffler(NULL) { }
[0124] CHintController: : ~CHintController()
[0125] { delete ipProjectManager; delete ipProjectSniffler; delete ipDrawEngine; delete iScrollTimer; delete iLogFile; } void CHintController: :Constructl_()
[0126] { ipProjectSniffler = CHintProjectSniffler: :NewL(); if(!ipProjectSniffler->Sniff(KDataDirectoryC)) if( !ipProjectSniffler->Sniff(KDataDirectoryD)) if( !ipProjectSniffler->Sniff(KDataDirectoryE))
[0127] {
[0128] ShowErrorDialog(KNoContentErrorMsgLnl,
[0129] KNoContentErrorMsgLn2);
[0130] ExitApplicationO; return;
[0131] >
[0132] TFileName chosenProjDir; if(!ChooseProjectL(chosenProjDir))
[0133] {
[0134] ExitApplication(); return;
[0135] } ipProjectManager = CHintProjectManager: :NewL(chosenProjDir); ipProjectManager- >LoadVTourL(); ipDrawEngine = CHintDrawEngine: :NewL(); ipDrawEngine- >SetProject(ipProjectMa[pi]ager); ipDrawEngine->SetController(this); iPenDown = false; iPenDrag = false; iPenUp = false; iScrollTimer = CPeriodic: :NewL(CActive: :EPriorityStandard); iPointerEventDown.iPosition.iX = 0; iPointerEventDown.iPosition.iY = 0; iPointerEventDrag.iPosition.iX = 0; iPointerEventDrag.iPosition.iY = 0; iPointerEventUp.iPosition.iX = 0; iPointerEventUp.iPosition.iY = 0; >
[0136] TBool CHintController: :ChooseProjectL(TFileName& chosenProjDir, TBool bAddCrtNb) TBool bOk = true; RArray<TName> projects; CleanupClosePushL(projects); ipProjectSniffler->GetProjects(projects); if(projects.Count() == 1)
[0137] { ipProjectSniffler->GetProjectDir(projects[0], chosenProjDir); CleanupStack: :PopAndDestroy(); return bOk;
[0138] }
[0139] CDesCArrayFlat* items = new(ELeave) CDesCArrayFlat(projects.Count());
[0140] CleanupStack: : PushL(items); for(int i = 0; i < projects. CountQ; i + + )
[0141] {
[0142] TName name; if(bAddCrtNb)
[0143] { name.AppendNum(i + 1); name.Append(_L("\t"));
[0144] } name.Append(projects[i]); items- >AppendL(name);
[0145] }
[0146] Tint nChosenProj = 0; if(GetUserChosenProject(nChosenProj, items)) ipProjectSniffler->GetProjectDir(projects[nChosenProj], chosenProjDir); else bOk = false; items->Reset();
[0147] CleanupStack: :PopAndDestroy(); ' CleanupStack: :PopAndDestroy(); return bOk; }
[0148] TKeyResponse CHintController: :HandleKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
[0149] {
[0150] TKeyResponse keyResponse = EKeyWasConsumed; Tint active = GetActiveViewIndex(); Tint count = GetViewCountQ; if( aType ! = EEventKey) return EKeyWasNotConsumed; TFileName metaFileName; ipProjectManager->GetProjectDirectory(metaFileName); switch (aKeyEvent. iScanCode)
[0151] { case EStdKeyUpArrow: ipDrawEngine->ScrollUp(); break; case EStdKeyDownArrow: ipDrawEngine->ScrollDown(); break; case EStdKeyLeftArrow: ipDrawEngine->ScrollLeft(); break; case EStdKeyRightArrow: ipDrawEngine->ScrollRight(); break; case 49: case 48: case 51:
[0152] { ipDrawEngine->ClearCache(); if(aKeyEvent.iScanCode == 49)
[0153] { active-; active = active < 0 ? count - 1 : active;
[0154] } else
[0155] { active+ + ; active = active % count; >
[0156] Display ViewNameBylndex(active); PrepareViewToActivate(active); SetActiveViewBylndex(active);
[0157] } break; case EStdKeyNkpAsterisk: case 42: case EStdKeyHash: case EStdKeyNkpMinus: ipProjectManager->GetCrtGallery()->inCrtHotSpot = ipProjectManager->GetCrtGallery()->GetNextHotSpot(aKeyEvent.iScanCode == 42 aKeyEvent.iScanCode == EStdKeyNkpAsterisk);
[0158] ShowTooltip(ipProjectManager->GetCrtGallery()- >GetCrtHotSpot()->iTip); ipDrawEngine->Update(); break; case EStdKeyDevice3: if(active == 0)
[0159] { ipDrawEngine->ClearCache(); CHintHotSpot* pCrtHotSpot = ipProjectManager- >GetCrtGallery()->GetCrtHotSpot(); bool bMetaSpot = false; TFileName& tip = pCrtHotSpot->iTip; if(tip.Find(KMetaFileTag) ! = KErrNotFound)
[0160] { bMetaSpot = true; metaFileName. Append (tip);
[0161] MetaViewSetFileNameL(metaFileName);
[0162] }
[0163] TFileName& link = pCrtHotSpot->iLink; if(!ipProjectManager->GalleryIsLoaded(link))
[0164] { ipProjectManager->LoadvTourl_ocationL(li[pi]k); ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterTpCrtHotSpot = true;
[0165] > else
[0166] { TFileName& crtGalleryName = ipProjectMa[pi]ager- >GetCrtGallery()->iXMLFileName; if(link != crtGalleryName)
[0167] { <-> ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterToCrtHotSpot = true- } }
[0168] Tint active = 1; if(bMetaSpot) active = 2;
[0169] DisplayViewNameBylndex(active); SetActiveViewBylndex(active); } else inactive == 1)
[0170] { ipDrawEngine->ClearCache(); CHintHotSpot* pCrtHotSpot = ipProjectManager- >GetCrtGallery()->GetCrtHotSpot(); bool bMetaSpot = false; TFileName& tip = pCrtHotSpot->iTip; if(tip.Fi[pi]d(KMetaFileTag) ! = KErrNotFound)
[0171] { bMetaSpot = true; metaFileName.Append(tip);
[0172] MetaViewSetFileNameL(metaFileName);
[0173] }
[0174] TFileName& link = pCrtHotSpot->iLink; if(!ipProjectManager->GalleryIsLoaded(link))
[0175] { ipProjectManager->LoadVTourLocationL(li[pi]k); ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterToCrtHotSpot = true; if(lbMetaSpot) ipDrawEngine->Update();
[0176] } else !
[0177] {
[0178] TFileNameS. crtGalleryName = ipProjectManager-
[0179] >GetCrtGallery()->iXMLFileName; if(link != crtGalleryName)
[0180] { ipProjectManager->SetCrtGallery(link); ipDrawE[pi]gine->ibCenterToCrtHotSpot = true; if(! bMetaSpot) ipDrawEngine->Update();
[0181] } else
[0182] { keyResponse = EKeyWasNotConsumed;
[0183] } } if(bMetaSpot)
[0184] { active = 2;
[0185] SetActiveViewBylndex(active); } } else if( active == 2 )
[0186] {
[0187] CHintHotSpot* pCrtHotSpot = ipProjectManager- >GetCrtGallery()->GetCrtHotSpot();
[0188] TFileName& tip = pCrtHotSpot->iTip; Tint pos = tip.Find(KMetaPhoneTag); if(pos ! = KErrNotFound) { pos += KMetaPhoneTag().Length(); Tint phoneNbLength = tip.LengthQ - pos; TBuf<KMaxPhoneLength> buf; buf = tip.Right(phoneNbLength); if(!ConfirmDialog(tip, KDialConfMsg)) break;
[0189] TRAPDferr. DialNumberUbun : ): if (err)
[0190] User: :InfoPrint(_L("Error dialing")); break;
[0191] } else if(tip.Find(KMetaEmailTag) I = KErrNotFound)
[0192] { break;
[0193] } } default: keyResponse = EKeyWasNotConsumed;
[0194] } return keyResponse;
[0195] } void CHintController: :PrepareViewToActivate(TInt active)
[0196] { inactive == 0)
[0197] {
[0198] HBufC* locationName = HBufC: :Newl_C(ipProjectManager- >GetCrtGallery()->iXMLFileName.Length());
[0199] *locationName = ipProjectManager->GetCrtGallery()->iXMLFileName; TFileName map; ipProjectManager->GetStartupLocation(map); if(!ipProjectManager->GalleryIsLoaded(map))
[0200] { ipProjectManager->LoadVTourLocationl_(map); ipProjectManager->SetCrtGallery(map); ipDrawEngine->ibCenterToCrtHotSpot = true;
[0201] > else
[0202] { ipProjectManager->SetCrtGallery(map); ipDrawEngine->ibCenterToCrtHotSpot = true;
[0203] >. ipProjectManager->GetCrtGallery()- >SetCurrentHotSpotByLink(*locationName);
[0204] CleanupStack: : PopAndDestroy(locationName);
[0205] } else if(active == 1)
[0206] { CHintHotSpot* pCrtHotSpot = ipProjectManager->GetCrtGallery()- >GetCrtHotSpot();
[0207] TFileName& link = pCrtHotSpot->il_ink; if(!ipProjectManager->GalleryIsLoaded(link))
[0208] { ipProjectManager->LoadVTourLocationL(link); ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterToCrtHotSpot = true; } else
[0209] { ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterToCrtHotSpot = true; } } else inactive == 2)
[0210] {
[0211] CHintHotSpot* pCrtHotSpot = ipProjectManager->GetCrtGallery()- >GetCrtHotSpot();
[0212] TFileName& tip = pCrtHotSpot->iTip; i
[0213] TFileName& link = pCrtHotSpot->iLink; TFileName metaFileName; ipProjectManager->GetProjectDirectory(metaFileName); metaFileName.Append(tip); MetaViewSetFileNameL( metaFileName);
[0214] MetaViewUseDrawEngine(tip.Find(KMetaFileTag) != KErrNotFound); if(!ipProjectManager->GalleryIsLoaded(link))
[0215] { ipProjectManager->LoadVTourl_ocationL(link); ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterToCrtHotSpot = true;
[0216] } else
[0217] { ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterToCrtHotSpot = true;
[0218] } void CHintController: :HandlePointerEventL(const TPointerEvent& aPointerEvent)
[0219] { switch(aPointerEvent.iType)
[0220] { case TPointerEvent: :EButtonlDown: iPenDown = true; iPenDrag = false; iPointerEventDown = aPointerEvent; iPointerEventDrag = aPointerEvent; break; case TPointerEvent: :EDrag: if([upsilon]PenDown) return; . iPenDrag = true;
[0221] {
[0222] TStdScanCode direction =
[0223] CheckPenDragDirection( iPointerEventDrag, aPointerEvent); switch (direction)
[0224] { case EStdKeyUpArrow: ipDrawEngine->ScrollDown(); break; case EStd Key Down Arrow: ipDrawEngine->ScrollUp(); break; case EStdKeyLeftArrow: ipDrawEngine->ScrollRight(); break; case EStdKeyRightArrow: ipDrawEngine->Scrolll_eft(); break; default: iPenDrag = false; } } iPointerEventDrag = aPointerEvent; break; case TPointerEvent: :EButtonlUp: if(iPenDrag && iScrollTimer && iScrollTimer->IsActive()) iScrollTimer->Cancel(); if([upsilon]PenDrag)
[0225] {
[0226] TPoint imagePos(0,0); ipDrawEngine->ImagePosFromScreenPos(imagePos, aPointerEvent.iPosition);
[0227] Tint nTappedSpot = ipProjectManager->GetCrtGallery()- >GetHotSpotFromPos(imagePos); if( nTappedSpot ! = -1)
[0228] { ipProjectManager->GetCrtGallery()->inCrtHotSpot nTappedSpot;
[0229] ShowTooltip(ipProjectManager->GetCrtGallery()- >GetCrtHotSpot()->iTip); ipDrawEngine->ibCenterToCrtHotSpot = false; ipDrawEngine->Update();
[0230] TKeyEvent aKeyEvent = {0}; aKeyEvent.iScanCode = EStdKeyDevice3; TEventCode aType; aType = EEventKey; HandleKeyEventUaKevEvent. aType) :
[0231] } } iPenDown = false; iPenDrag = false; iPointerEventUp = aPointerEvent; iPointerEventDrag. iPosition.iX = 0; iPointerEventDrag. iPosition.iY = 0; break; default:
[0232] {
[0233] Tint dummy = 1; dummy+ + ;
[0234] > } } void CHintController: :HandleUserTabSwitchEventL()
[0235] { if(ipDrawEngine) ipDrawEngine->ClearCache();
[0236] Tint index = GetActiveViewIndex(); PrepareViewToActivate( index); SetActiveViewBylndex(index); }
[0237] Tint CHintController: :ScrollTimerCallBack(TAny*)
[0238] { return 0;
[0239] }
[0240] TStdScanCode CHintController: :CheckPenDragDirection(const TPointerEvent& aPointerEventDragl, const TPointerEvent& aPointerEventDrag2)
[0241] {
[0242] TStdScanCode direction = EStdKeyNull;
[0243] TPoint delta = aPointerEventDrag2.iPosition - aPointerEventDragl. iPosition; if(delta.iX == 0 && delta. iY == 0)
[0244] { direction = EStdKeyNull;
[0245] > else if(delta.iX >= 0 && delta. iY >= 0)
[0246] { if(delta.iX > delta. iY) direction = EStdKeyRightArrow; else direction = EStdKeyDownArrow;
[0247] } else if(delta.iX >= 0 && delta. iY <= 0)
[0248] { delta. iY = -delta. iY; if(delta.iX > delta. iY) direction = EStdKeyRightArrow; else direction = EStdKeyUpArrow;
[0249] } else if(delta.iX <= 0 && delta. iY <= 0)
[0250] { delta. iX = -delta. iX; delta. iY = -delta. iY; if(delta.iX > delta. iY) direction = EStdKeyLeftArrow; else direction = EStdKeyUpArrow;
[0251] > else if(delta.iX <= 0 && delta. iY >= 0)
[0252] { delta. iX = -delta. iX; if(delta.iX > delta. iY) direction = EStdKeyLeftArrow; else direction = EStdKeyDownArrow;
[0253] } return direction;
[0254] } void CHintController: : DialNumberl_( const TDesC& aPhoneNumber)
[0255] {
[0256] RTelServer server;
[0257] CleanupClosePushLCserver);
[0258] User: : LeaveIfError(server.Connect());
[0259] TName tsy;
[0260] User: : LeaveIfError(server.GetTsyName(0, tsy)) ;
[0261] User: : LeaveIfError(server.LoadPhoneModu!e(tsy));
[0262] Tint numberPhones;
[0263] User: :LeaveIfError(server.EnumeratePhones(numberPhones));<'> if (numberPhones < 1)
[0264] User: : Leave(KErrNotFound);
[0265] RTelServer: :TPhoneInfo info;
[0266] User: : LeaveIfError(server.GetPhoneInfo(0, info));
[0267] RPhone phone;
[0268] CleanupClosePushL( phone);
[0269] User: : LeaveIfError(phone.Open(server, info.iName));
[0270] RPhone: :TLineInfo linelnfo;
[0271] User: : LeaveIfError(phone.GetLineInfo(0, linelnfo));
[0272] RLine line;
[0273] CleanupClosePushL(line);
[0274] User: : LeaveIfError(line.Open(phone, linelnfo. iName));
[0275] TBuf < 100> newCallName;
[0276] RCaII call;
[0277] CleanupClosePushL(call);
[0278] User: : LeaveIfError(call.OpenNewCall(line, newCallName));
[0279] User: :LeaveIfErrorfcall.Dialf aPhoneNumber));
[0280] CleanupStack: :PopAndDestroy(3);
[0281] User: : LeaveIfError(server.UnloadPhoneModule(tsy));
[0282] CleanupStack: :PopAndDestroy(&server); } 
[0283] APPENDIX B 2
[0284] const Tint KScrollStep = 20; const Tint KScrollArrow = 5;
[0285] CHintDrawEngine* CHintDrawEngine: :NewL()
[0286] {
[0287] CHintDrawEngine* self = CHintDrawEngine: : NewLC();
[0288] CleanupStack: :Pop(); return self; }
[0289] CHintDrawEngine* CHintDrawEngine: :NewLC()
[0290] {
[0291] CHintDrawEngine* self = new (ELeave) CHintDrawEngineQ;
[0292] CleanupStack: : PushL(self); self->ConstructL(); return self; } void CHintDrawEngine: :Constructl_()
[0293] { ipProjectManager = NULL; ipDisplayCallback = NULL; ipController = NULL; ipArrlmages = new (ELeave) CArrayPtrFlat<CHintImageAdapter> (1);
[0294] }
[0295] CHintDrawEngine: :CHintDrawEngine() : iClientRect(0, 0,0,0)
[0296] { iCrtlmage = -1; iMaxCachedAdapters = 1; iTopLeft.iX = 0; iTopLeft.iY = 0; ibMarkHotSpots = false; ibCenterToCrtHotSpot = true; ibScrollUpBtn = false; ibScrollDownBtn = false; ibScrollLeftBtn = false; ibScrollRightBtn = false;
[0297] }
[0298] CHintDrawEngine: : ~CHintDrawEngine()
[0299] { ipProjectManager = NULL; ipDisplayCallback = NULL; ipController = NULL; if (ipArrlmages)
[0300] { for(TInt idx = 0; idx < ipArrImages->Count(); + + idx) ipArrImages->At(idx)->Cancel(); ipArrImages->ResetAndDestroy(); delete ipArrlmages; ipArrlmages = NULL; } > void CHintDrawEngine: :ClearCache()
[0301] { if (ipArrlmages)
[0302] { for(TInt idx = 0; idx < ipArrImages->Count(); + + idx) ipArrlmages- >At(idx)->Cancel(); ipArrlmages- >ResetAndDestroy (); delete ipArrlmages; ipArrlmages = NULL;
[0303] > iCrtlmage = -1; ipArrlmages = new (ELeave) CArrayPtrFlat<CHintImageAdapter> (1); } void CHintDrawEngine: :SetProject(CHintProjectManager* apHintProjectManager)
[0304] { ipProjectManager = apHintProjectManager;
[0305] > void CHintDrawEngine: :SetController(MHintController* apController)
[0306] { ipController = apController;
[0307] } void CHintDrawEngine: :Update()
[0308] {
[0309] CHintlmageNavigator* pCrtlmageNav = ipProjectManager->GetCrtImgNav(); . TFileName crtlmageName = pCrtImageNav->iImageFileName; Tint idx = 0; for(idx = 0; idx < ipArrImages->Count(); ++idx)
[0310] { if(crtImageName == ipArrImages->At(idx)->GetImageFileName()) break;
[0311] > if(idx == ipArrImages->Count())
[0312] {
[0313] CHintlmageAdapter* plmageAdapter = NULL; plmageAdapter =
[0314] CHintlmageAdapter: :NewLC(NEikonEnvironment: :EikEnv().DefaultDisplayMode()); plmageAdapter- >SetImageFileName(crtImageName); plmageAdapter- >SetDispCallback(ipDisplayCallback); plmageAdapter- >SetEngCallback(this); plmageAdapter- >ExecuteCommandL(EDecodeImage); ipArrImages->AppendL(pImageAdapter); CleanupStack: :Pop(pImageAdapter); iCrtlmage = idx;
[0315] > else
[0316] { iCrtlmage = idx; CheckScrollersO; if(ibCenterToCrtHotSpot)
[0317] CenterToCrtHotSpot(); if(ipDisplayCallback) ipDisplayCallback->Redraw(); } } void CHintDrawEngine: :CenterToCrtHotSpot()
[0318] {
[0319] CHintHotSpot* pSpot = NULL; pSpot = ipProjectManager->GetCrtGallery()->GetCrtHotSpot(); iTopLeft.iX = iClientRect.iTI.iX + iClientRect.Width()/2 - (pSpot->iX + pSpot- >iWidth / 2); iTopLeft.iY = iClientRect.iTI.iY + iClientRect.Height()/2 - (pSpot->iY + pSpot- >iHeight / 2);
[0320] CFbsBitmap* bitmap = &(ipArrImages->At(iCrtImage)->Image());
[0321] Tint nBitmapHeight = bitmap->SizeInPixels().iHeight; if(iTopLeft.iY < = iClientRect.iTI.iY + iClientRect.HeightQ - nBitmapHeight) iTopLeft.iY = iClientRect.iTI.iY + iClientRect.Height() - nBitmapHeight; if(iTopLeft.iY >= iClientRect.iTI.iY) iTopLeft.iY = iClientRect.iTI.iY;
[0322] Tint nBitmapWidth = bit[pi][eta]ap->SizeInPixels().iWidth; if(iTopLeft.iX <= iClientRect.iTI.iX + iClientRect.Width() - nBitmapWidth) iTopLeft.iX = iClientRect.iTI.iX + iClientRect.Width() - nBitmapWidth; if(iTopLeft.iX >= iClientRect.iTI.iX) iTopLeft.iX = iClientRect.iTI.iX; <'>
[0323] > void CHintDrawEngine: :SystemRedraw()
[0324] { if(ipDisplayCallback) ipDisplayCallback->Redraw();
[0325] } void CHintDrawEngine: :ImageReady()
[0326] {
[0327] NormalizeHotSpots(iCrtlmage);
[0328] CenterToCrtHotSpot(); CheckScrollersO; ipController-> ImageReady (); if(ipDisplayCallback) ipDisplayCallback->Redraw();
[0329] } void CHintDrawEngine: :SetDisplayReference(MDisplayCallback* apDisplayRef)
[0330] { ipDisplayCallback = apDisplayRef; if(ipDisplayCallback)
[0331] { ipDisplayCallback->GetWindowClientRect(iClientRect);
[0332] TopLeft = iClientRect.iTI; > } void CHintDrawEngine: :Draw(CWindowGc& gc, const TRect&) const
[0333] { if(iCrtImage == -1) return; if(ipArrImages->At(iCrtImage)->GetErr() ! = KErrNone) return; if(!ipArrImages->At(iCrtImage)->ImageLoaded()) { return;
[0334] >
[0335] CFbsBitmap* bitmap = &(ipArrImages->At(iCrtImage)->Image()); TBool bUseVirtualTI = false; if(ipProjectMa[pi]ager->GetCrtImgNav()->iViewerType == 1)
[0336] { if(iTopLeft.iX > iClientRect.iTI.iX)
[0337] {
[0338] TPoint virtTopLeft(iTopLeft.iX - bitmap->SizeInPixels().iWidth, iTopLeftiY); gc.BitBlt(virtTopLeft, bitmap); bUseVirtualTI = true;
[0339] } gc.BitBlt(iTopLeft, bitmap);
[0340] } else <~> gc.BitBlt(iTopLeft, bitmap); CHintHotSpot* pSpot = NULL; gc.SetPenColor(KRgbRed); if(ibMarkHotSpots)
[0341] { for(TInt idx = 0; idx < ipProjectManager->GetCrtGallery()- >ipArrHotSpots->Count(); ++idx)
[0342] { pSpot = ipProjectManager->GetCrtGallery()->ipArrHotSpots-
[0343] >At(idx); gc.DrawRect( TRect( iTopLeft + TPoint(pSpot->iX, pSpot->iY), TSize(pSpot->iWidth, pSpot->iHeight) ) ); if(bUseVirtualTI)
[0344] {
[0345] TPoint virtTopLeft(iTopLeft.iX - bitmap- >SizeInPixels().iWidth, iTopLeft. iY); gc.DrawRect( TRect( virtTopLeft + TPoint(pSpot->iX, pSpot- >iY), TSize(pSpot->iWidth, pSpot->iHeight) ) );
[0346] } }
[0347] } pSpot = ipProjectManager->GetCrtGallery()->GetCrtHotSpot(); gc.DrawRect( TRect( iTopLeft + TPoint(pSpot->iX - 2, pSpot->iY - 2), TSize(pSpot->iWidth + 4, pSpot->iHeight + 4) ) );
[0348] DrawScrollers(gc); } void CHintDrawEngine: :ScrollUp()
[0349] { if(iTopLeft.iY == iCljentRect.iTI.iY) return; iTopLeft. iY += KScrollStep; if ( iTopLeft. iY >= iClientRect.iTI.iY) iTopLeft. iY = iClientRect.iTI.iY; CheckScrollersO; SystemRedrawQ;
[0350] > void CHintDrawEngine: :ScrollDown() CFbsBitmap* bitmap = &(ipArrImages->At(iCrtImage)->Image());
[0351] Tint nBitmapHeight = bitmap->SizeInPixels().iHeight; if(iTopLeft.iY = = iClientRect.iTI.iY + iClientRect.Height() - nBitmapHeight) return; iTopLeft.iY -= KScrollStep; if(iTopLeft.iY <= iClientRect.iTI.iY + iClientRect.HeightQ - nBitmapHeight) iTopLeft.iY = iClientRect.iTI.iY + iClientRect.HeightQ - nBitmapHeight; CheckScrollersQ; SystemRedraw();
[0352] } void CHintDrawEngine: :ScrollLeft()
[0353] { if(ipProjectManager->GetCrtImgNav()->iViewerType == 1)
[0354] { iTopLeft.iX += KScrollStep; if(iTopLeft.iX >= iClientRect.Width())
[0355] {
[0356] CFbsBitmap* bitmap = &(ipArrImages->At(iCrtImage)->Image()); Tint nBitmapWidth = bitmap->SizeInPixels().iWidth; iTopLeft.iX = iClientRect.Width() - nBitmapWidth; } } else
[0357] { if(iTopLeft.iX == iClientRect.iTI.iX) return; iTopLeft.iX += KScrollStep; if(iTopLeft.iX >= iClientRect.iTI.iX) iTopLeft.iX = iClientRect.iTI.iX;
[0358] }
[0359] CheckScrollersQ;
[0360] SystemRedrawQ;
[0361] void CHintDrawEngine: :ScrollRight()
[0362] {
[0363] CFbsBitmap* bitmap = &(ipArrImages->At(iCrtImage)->Image()); Tint nBitmapWidth = bitmap->SizeInPixels().iWidth; if(ipProjectManager->GetCrtImgNav()->iViewerType == 1)
[0364] { iTopLeft.iX -= KScrollStep; if(iTopLeft.iX <= iClientRect.WidthQ - nBitmapWidth)
[0365] { iTopLeft.iX = iClientRect.WidthQ;
[0366] } } else
[0367] { if(iTopLeft.iX == iClientRect.iTI.iX + iClientRect.WidthQ - nBitmapWidth) return; iTopLeft.iX -= KScrollStep; if(iTopLeft.iX <= iClientRect.iTI.iX + iClientRect.WidthQ - nBitmapWidth) iTopLeft.iX = iClientRect.iTI.iX + iClientRect.WidthQ - nBitmapWidth; } CheckScrollersQ; SystemRedrawQ; } void CHintDrawEngine: :NormalizeHotSpots(TInt aCrtlmage)
[0368] {
[0369] CFbsBitmap* bitmap = &(ipArrImages->At(aCrtImage)->Image()); Tint nBitmapWidth = bitmap->SizeInPixels().iWidth; Tint nBitmapHeight = bitmap->SizeInPixels().iHeight; if(!nBitmapWidth inBitmapHeight)
[0370] {
[0371] ASSERT(false); return;
[0372] }
[0373] CHintHotSpot* pSpot = NULL; for(TInt idx = 0; idx < ipProjectManager->GetCrtGallery()->ipArrHotSpots- >Count(); + + idx)
[0374] { pSpot = ipProjectManager->GetCrtGallery()->ipArrHotSpots->At(idx); pSpot->iX = TInt(nBitmapWidth * pSpot->iXsReal); pSpot->iY = TInt(nBitmapHeight * pSpot->iYsReai); pSpot->iWidth = TInt(nBitmapWidth * (pSpot->iXeReal - pSpot- >iXsReal)); pSpot->iHeight = TInt(nBitmapHeight * (pSpot->iYeReal - pSpot- >iYsReal));
[0375] > ipProjectManager->GetCrtGallery()->SortTheSpots();
[0376] } void CHintDrawEngine: :SetMarkHotSpots(TBool abMarkThem)
[0377] { ibMarkHotSpots = abMarkThem;
[0378] > void CHintDrawEngine: :CheckScrollers()
[0379] {
[0380] CFbsBitmap* pBitmap = &(ipArrImages->At(iCrtImage)->Image()); if(lpBitmap) return; ibScrollUpBtn = (iTopLeft.iY < iClientRect.iTI.iY); ibScrollDownBtn = (iTopLeft.iY + pBitmap->SizeInPixels().iHeight > iClientRect.iBr.iY); ibScrollLeftBtn = (iTopLeft.iX < iClientRect.iTI.iX); ibScrollRightBtn = (iTopLeft.iX + pBitmap->SizeInPixels().iWidth > iClientRect.iBr.iX); if(ipProjectManager->GetCrtImgNav()->iViewerType == 1)
[0381] { ibScrollLeftBtn = false; ibScrollRightBtn = false; } } void CHintDrawEngine: : DrawScrollers(CWindowGc& gc) const
[0382] {
[0383] TPoint ptOrig = TPoint(iClientRect.iTl.iX, iClientRect.iTI.iY);
[0384] Tint width = iClientRect.WidthQ; Tint height = iClientRect.HeightQ; Tint arrow = KScrollArrow; if(ibScrollLeftBtn) { gc.Drawl_ine(ptOrig + TPoint(0, height/2), ptOrig + TPoint(arrow, height/2 - arrow)); gc.Draw[upsilon]ne(ptOrig + TPoint(0, height/2), ptOrig + TPoint(arrow, height/2 + arrow)); gc.DrawLine(ptOrig + TPoint(arrow, height/2 - arrow), ptOrig + TPoint(arrow, height/2 + arrow));
[0385] > if(ibScrollRightBtn)
[0386] { gc.DrawLine(ptOrig + TPoint(width - arrow, height/2 - arrow), ptOrig + TPoint(width, height/2)); gc.Drawl_ine(ptOrig + TPoint(width - arrow, height/2 + arrow), ptOrig + TPoint(width, height/2)); gc.DrawLine(ptOrig + TPoint(width - arrow, height/2 - arrow), ptOrig + TPoint(width - arrow, height/2 + arrow));
[0387] } if(ibScrollUpBtn)
[0388] { gc.DrawLine(ptOrig + TPoint(width/2 - arrow, arrow), ptOrig + TPoint(width/2, O)); gc.DrawLine(ptOrig + TPoint(width/2, 0), ptOrig + TPoint(width/2 + arrow, arrow)); gc.DrawLine(ptOrig + TPoint(width/2 - arrow, arrow), ptOrig + TPoint(width/2 + arrow, arrow));
[0389] > if(ibScrollDownBtn)
[0390] { gc.Drawl_ine(ptOrig + TPoint(width/2 - arrow, height - arrow), ptOrig +
[0391] TPoint(width/2, height)); gc.DrawLine(ptOrig + TPoint(width/2, height), ptOrig + TPoint(width/2 + arrow, height - arrow)); gc.DrawLine(ptOrig + TPoint(wi[0046] APPENDIX Al
[0047] <?xml version = "1.0" ?> <VirtualTourLocatio[pi]>
[0048] <ImageNavigator>
[0049] <ImageFile>PHOTOS/paddington_map.jpg</ImageFile>
[0050] <ViewerType>.l2D</ViewerType> </ImageNavigator> < Hotspot>
[0051] <Position>0.26 0.688235 0.302 0.750035</Position> <XMLSource>XML/paddington_station_interior.xml</XMLSource>
[0052] <Tip>Paddington Station</Tip> </Hotspot> < Hotspot>
[0053] <Position>0.74 0.370588 0.78 0.432353 </Position>
[0054] <XMLSource>XML/sale_place.xml</XMLSource>
[0055] <Tip>Sale Place</Tip> </Hotspot> <Hotspot>
[0056] <Position>0.67 0.461765 0.712 0.523529</Position>
[0057] <XMLSource>XML/south_wharf_road.xml</XMLSource>
[0058] <Tip>South Wharf</Tip> </Hotspot> <Hotspot>
[0059] <Position>O.558 0.620588 0.6 0.679412</Positio[pi]>
[0060] <XMLSource>XML/st_marys_hospital.xml</XMLSource>
[0061] <Tip>St. Mary's Hospital</Tip> </H[omicron]tspot> <Hotspot>
[0062] <Position>0.346 0.752941 0.388 0.814706</Position>
[0063] <XMLSource>XML/london_street.xml</XMLSource>
[0064] <Tip>London St</Tip> </Hotspot> <Hotspot>
[0065] <Position>O.836 0.220588 0.878 0.282388</Position> <XMLSource>XML/hilton_londo[pi]_metropole.xml </XMLSource>
[0066] <Tip>Hilton London Metropole</Tip> </Hotspot> </VirtualTourLocation> 
[0067] APPENDIX A2
[0068] <?xml version = "1.0" ?> <VirtualTourLocation>
[0069] <ImageNavigator>
[0070] <ImageFile>PHOTOS/st_marys_hospital.jpg</ImageFile>
[0071] <ViewerType>Pano</ViewerType>
[0072] < panotype>SPHERE</panotype>
[0073] < pitchRange>-0.231 0.231 </pitchRange>
[0074] <vFov>-O.231 0.231</vFov>
[0075] <initialView>0.00286517 84.7636 26.4649</i[pi]itialView>
[0076] <Autospin>0</Autospin> </ImageNavigator> < Hotspot>
[0077] <XMLSource>XML/south_wharf_road.xml</XMLSource>
[0078] < Position>0.21572 0.730924 0.231289 0.904535</Position>
[0079] <Tip>Praed South Wharf</Tip> </Hotspot> < Hotspot>
[0080] <XMLSource>XML/london_street.xml</XMLSource>
[0081] < Position>0.752424 0.823293 0.767659 O.995984</Position>
[0082] <Tip>Praed London St</Tip> </Hotspot> </VirtualTourLocation>
[0083] APPENDIX A3
[0084] <?xml version = "1.0" ?> <VirtualTourLocation>
[0085] <ImageNavigator>
[0086] <ImageFile>PHOTOS/paddington_station_interior.jpg</ImageFile>
[0087] <ViewerType>Pano</ViewerType>
[0088] <panotype>SPHERE</panotype>
[0089] < pitchRange>-0.236 0.236</pitchRange>
[0090] <vFov>-O.236 0.236</vFov>
[0091] <i[pi]itialView>0.00286517 148.971 27.0379</initialView>
[0092] <Autospin>0</Autospin> </ImageNavigator> <Hotspot>
[0093] <XMLSource>XML/london_street.xml</XMLSource>
[0094] <Position>0.380086 0.650602 0.395028 0.817046</Position>
[0095] <Tip> Walkway To Praed St. </Tip> </Hotspot> <Hotspot>
[0096] <XMLSource>XML/paddington_Ge[pi]Info_meta.xml</XMLSource>
[0097] < Position>0.292291 0.666667 0.308291 O.847667</Position>
[0098] <Tip>META\General Information. txt</Tip> </Hotspot> </VirtualTourLocation> APPENDIX A4
[0099] <?xml version = "1.0" ?> <VirtualTourl_ocation>
[0100] <ImageNavigator>
[0101] <ImageFile>PHOTOS/paddington_GenInfo_meta.jpg</ImageFile>
[0102] <ViewerType>J2D</ViewerType> </ImageNavigator> <Hotspot>
[0103] <XMLSource>XML/paddington_station_interior.xml</XMLSource>
[0104] <Position>0.0148 0.111 0.0529 0.444</Position>
[0105] <Tip> Phone / +44 8457 484950</Tip> </Hotspot> < Hotspot>
[0106] <XML[Xi]ource>XML/paddington_station_i[pi]terior.xml </XMLSource>
[0107] <Position>0.229 0.143 0.2682 0.461 </Position>
[0108] <Tip>Phone / +44 8456 005604</Tip> </Hotspot> < Hotspot>
[0109] <XMLSource>XML/paddington_station_interior.xml</XMLSource>
[0110] <Position>0.403 0.127 0.4423 0.445</Position >
[0111] <Tip>Phone / +44 8456 001515</Tip> </Hotspot> < Hotspot>
[0112] <XMLSource>XML/paddington_station_interior.xml </XMLSource>
[0113] <Position>0.564 0.143 0.6032 0.461</Position>
[0114] <T[iota]p>Phone / +44 8453 303728</Tip> </Hotspot> <Hotspot>
[0115] <XMLSource>XML/paddington_station_interior.xml </XMLSource>
[0116] <Position>O.71 0.111 0.7492 0.444</Position>
[0117] <Tip>Phone / +44 2072 620344</Tip> </Hotspot> <Hotspot>
[0118] <XMLSource>XML/paddington_station_interior.xml </XMLSource>
[0119] < Position>0.852 0.127 0.8914 0.445</Position>
[0120] <Tip>Phone / +44 2072 620344</Tip> </Hotspot> </VirtualTourLocation> 
[0121] APPENDIX Bl
[0122] const Tint KMaxPhoneLength = 0x10;
[0123] CHintController: :CHintController(): ipProjectManager(NULL), ipDrawEngine(NULL), ipProjectSniffler(NULL) { }
[0124] CHintController: : ~CHintController()
[0125] { delete ipProjectManager; delete ipProjectSniffler; delete ipDrawEngine; delete iScrollTimer; delete iLogFile; } void CHintController: :Constructl_()
[0126] { ipProjectSniffler = CHintProjectSniffler: :NewL(); if(!ipProjectSniffler->Sniff(KDataDirectoryC)) if( !ipProjectSniffler->Sniff(KDataDirectoryD)) if( !ipProjectSniffler->Sniff(KDataDirectoryE))
[0127] {
[0128] ShowErrorDialog(KNoContentErrorMsgLnl,
[0129] KNoContentErrorMsgLn2);
[0130] ExitApplicationO; return;
[0131] >
[0132] TFileName chosenProjDir; if(!ChooseProjectL(chosenProjDir))
[0133] {
[0134] ExitApplication(); return;
[0135] } ipProjectManager = CHintProjectManager: :NewL(chosenProjDir); ipProjectManager- >LoadVTourL(); ipDrawEngine = CHintDrawEngine: :NewL(); ipDrawEngine- >SetProject(ipProjectMa[pi]ager); ipDrawEngine->SetController(this); iPenDown = false; iPenDrag = false; iPenUp = false; iScrollTimer = CPeriodic: :NewL(CActive: :EPriorityStandard); iPointerEventDown.iPosition.iX = 0; iPointerEventDown.iPosition.iY = 0; iPointerEventDrag.iPosition.iX = 0; iPointerEventDrag.iPosition.iY = 0; iPointerEventUp.iPosition.iX = 0; iPointerEventUp.iPosition.iY = 0; >
[0136] TBool CHintController: :ChooseProjectL(TFileName& chosenProjDir, TBool bAddCrtNb) TBool bOk = true; RArray<TName> projects; CleanupClosePushL(projects); ipProjectSniffler->GetProjects(projects); if(projects.Count() == 1)
[0137] { ipProjectSniffler->GetProjectDir(projects[0], chosenProjDir); CleanupStack: :PopAndDestroy(); return bOk;
[0138] }
[0139] CDesCArrayFlat* items = new(ELeave) CDesCArrayFlat(projects.Count());
[0140] CleanupStack: : PushL(items); for(int i = 0; i < projects. CountQ; i + + )
[0141] {
[0142] TName name; if(bAddCrtNb)
[0143] { name.AppendNum(i + 1); name.Append(_L("\t"));
[0144] } name.Append(projects[i]); items- >AppendL(name);
[0145] }
[0146] Tint nChosenProj = 0; if(GetUserChosenProject(nChosenProj, items)) ipProjectSniffler->GetProjectDir(projects[nChosenProj], chosenProjDir); else bOk = false; items->Reset();
[0147] CleanupStack: :PopAndDestroy(); ' CleanupStack: :PopAndDestroy(); return bOk; }
[0148] TKeyResponse CHintController: :HandleKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
[0149] {
[0150] TKeyResponse keyResponse = EKeyWasConsumed; Tint active = GetActiveViewIndex(); Tint count = GetViewCountQ; if( aType ! = EEventKey) return EKeyWasNotConsumed; TFileName metaFileName; ipProjectManager->GetProjectDirectory(metaFileName); switch (aKeyEvent. iScanCode)
[0151] { case EStdKeyUpArrow: ipDrawEngine->ScrollUp(); break; case EStdKeyDownArrow: ipDrawEngine->ScrollDown(); break; case EStdKeyLeftArrow: ipDrawEngine->ScrollLeft(); break; case EStdKeyRightArrow: ipDrawEngine->ScrollRight(); break; case 49: case 48: case 51:
[0152] { ipDrawEngine->ClearCache(); if(aKeyEvent.iScanCode == 49)
[0153] { active-; active = active < 0 ? count - 1 : active;
[0154] } else
[0155] { active+ + ; active = active % count; >
[0156] Display ViewNameBylndex(active); PrepareViewToActivate(active); SetActiveViewBylndex(active);
[0157] } break; case EStdKeyNkpAsterisk: case 42: case EStdKeyHash: case EStdKeyNkpMinus: ipProjectManager->GetCrtGallery()->inCrtHotSpot = ipProjectManager->GetCrtGallery()->GetNextHotSpot(aKeyEvent.iScanCode == 42 aKeyEvent.iScanCode == EStdKeyNkpAsterisk);
[0158] ShowTooltip(ipProjectManager->GetCrtGallery()- >GetCrtHotSpot()->iTip); ipDrawEngine->Update(); break; case EStdKeyDevice3: if(active == 0)
[0159] { ipDrawEngine->ClearCache(); CHintHotSpot* pCrtHotSpot = ipProjectManager- >GetCrtGallery()->GetCrtHotSpot(); bool bMetaSpot = false; TFileName& tip = pCrtHotSpot->iTip; if(tip.Find(KMetaFileTag) ! = KErrNotFound)
[0160] { bMetaSpot = true; metaFileName. Append (tip);
[0161] MetaViewSetFileNameL(metaFileName);
[0162] }
[0163] TFileName& link = pCrtHotSpot->iLink; if(!ipProjectManager->GalleryIsLoaded(link))
[0164] { ipProjectManager->LoadvTourl_ocationL(li[pi]k); ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterTpCrtHotSpot = true;
[0165] > else
[0166] { TFileName& crtGalleryName = ipProjectMa[pi]ager- >GetCrtGallery()->iXMLFileName; if(link != crtGalleryName)
[0167] { <-> ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterToCrtHotSpot = true- } }
[0168] Tint active = 1; if(bMetaSpot) active = 2;
[0169] DisplayViewNameBylndex(active); SetActiveViewBylndex(active); } else inactive == 1)
[0170] { ipDrawEngine->ClearCache(); CHintHotSpot* pCrtHotSpot = ipProjectManager- >GetCrtGallery()->GetCrtHotSpot(); bool bMetaSpot = false; TFileName& tip = pCrtHotSpot->iTip; if(tip.Fi[pi]d(KMetaFileTag) ! = KErrNotFound)
[0171] { bMetaSpot = true; metaFileName.Append(tip);
[0172] MetaViewSetFileNameL(metaFileName);
[0173] }
[0174] TFileName& link = pCrtHotSpot->iLink; if(!ipProjectManager->GalleryIsLoaded(link))
[0175] { ipProjectManager->LoadVTourLocationL(li[pi]k); ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterToCrtHotSpot = true; if(lbMetaSpot) ipDrawEngine->Update();
[0176] } else !
[0177] {
[0178] TFileNameS. crtGalleryName = ipProjectManager-
[0179] >GetCrtGallery()->iXMLFileName; if(link != crtGalleryName)
[0180] { ipProjectManager->SetCrtGallery(link); ipDrawE[pi]gine->ibCenterToCrtHotSpot = true; if(! bMetaSpot) ipDrawEngine->Update();
[0181] } else
[0182] { keyResponse = EKeyWasNotConsumed;
[0183] } } if(bMetaSpot)
[0184] { active = 2;
[0185] SetActiveViewBylndex(active); } } else if( active == 2 )
[0186] {
[0187] CHintHotSpot* pCrtHotSpot = ipProjectManager- >GetCrtGallery()->GetCrtHotSpot();
[0188] TFileName& tip = pCrtHotSpot->iTip; Tint pos = tip.Find(KMetaPhoneTag); if(pos ! = KErrNotFound) { pos += KMetaPhoneTag().Length(); Tint phoneNbLength = tip.LengthQ - pos; TBuf<KMaxPhoneLength> buf; buf = tip.Right(phoneNbLength); if(!ConfirmDialog(tip, KDialConfMsg)) break;
[0189] TRAPDferr. DialNumberUbun : ): if (err)
[0190] User: :InfoPrint(_L("Error dialing")); break;
[0191] } else if(tip.Find(KMetaEmailTag) I = KErrNotFound)
[0192] { break;
[0193] } } default: keyResponse = EKeyWasNotConsumed;
[0194] } return keyResponse;
[0195] } void CHintController: :PrepareViewToActivate(TInt active)
[0196] { inactive == 0)
[0197] {
[0198] HBufC* locationName = HBufC: :Newl_C(ipProjectManager- >GetCrtGallery()->iXMLFileName.Length());
[0199] *locationName = ipProjectManager->GetCrtGallery()->iXMLFileName; TFileName map; ipProjectManager->GetStartupLocation(map); if(!ipProjectManager->GalleryIsLoaded(map))
[0200] { ipProjectManager->LoadVTourLocationl_(map); ipProjectManager->SetCrtGallery(map); ipDrawEngine->ibCenterToCrtHotSpot = true;
[0201] > else
[0202] { ipProjectManager->SetCrtGallery(map); ipDrawEngine->ibCenterToCrtHotSpot = true;
[0203] >. ipProjectManager->GetCrtGallery()- >SetCurrentHotSpotByLink(*locationName);
[0204] CleanupStack: : PopAndDestroy(locationName);
[0205] } else if(active == 1)
[0206] { CHintHotSpot* pCrtHotSpot = ipProjectManager->GetCrtGallery()- >GetCrtHotSpot();
[0207] TFileName& link = pCrtHotSpot->il_ink; if(!ipProjectManager->GalleryIsLoaded(link))
[0208] { ipProjectManager->LoadVTourLocationL(link); ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterToCrtHotSpot = true; } else
[0209] { ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterToCrtHotSpot = true; } } else inactive == 2)
[0210] {
[0211] CHintHotSpot* pCrtHotSpot = ipProjectManager->GetCrtGallery()- >GetCrtHotSpot();
[0212] TFileName& tip = pCrtHotSpot->iTip; i
[0213] TFileName& link = pCrtHotSpot->iLink; TFileName metaFileName; ipProjectManager->GetProjectDirectory(metaFileName); metaFileName.Append(tip); MetaViewSetFileNameL( metaFileName);
[0214] MetaViewUseDrawEngine(tip.Find(KMetaFileTag) != KErrNotFound); if(!ipProjectManager->GalleryIsLoaded(link))
[0215] { ipProjectManager->LoadVTourl_ocationL(link); ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterToCrtHotSpot = true;
[0216] } else
[0217] { ipProjectManager->SetCrtGallery(link); ipDrawEngine->ibCenterToCrtHotSpot = true;
[0218] } void CHintController: :HandlePointerEventL(const TPointerEvent& aPointerEvent)
[0219] { switch(aPointerEvent.iType)
[0220] { case TPointerEvent: :EButtonlDown: iPenDown = true; iPenDrag = false; iPointerEventDown = aPointerEvent; iPointerEventDrag = aPointerEvent; break; case TPointerEvent: :EDrag: if([upsilon]PenDown) return; . iPenDrag = true;
[0221] {
[0222] TStdScanCode direction =
[0223] CheckPenDragDirection( iPointerEventDrag, aPointerEvent); switch (direction)
[0224] { case EStdKeyUpArrow: ipDrawEngine->ScrollDown(); break; case EStd Key Down Arrow: ipDrawEngine->ScrollUp(); break; case EStdKeyLeftArrow: ipDrawEngine->ScrollRight(); break; case EStdKeyRightArrow: ipDrawEngine->Scrolll_eft(); break; default: iPenDrag = false; } } iPointerEventDrag = aPointerEvent; break; case TPointerEvent: :EButtonlUp: if(iPenDrag && iScrollTimer && iScrollTimer->IsActive()) iScrollTimer->Cancel(); if([upsilon]PenDrag)
[0225] {
[0226] TPoint imagePos(0,0); ipDrawEngine->ImagePosFromScreenPos(imagePos, aPointerEvent.iPosition);
[0227] Tint nTappedSpot = ipProjectManager->GetCrtGallery()- >GetHotSpotFromPos(imagePos); if( nTappedSpot ! = -1)
[0228] { ipProjectManager->GetCrtGallery()->inCrtHotSpot nTappedSpot;
[0229] ShowTooltip(ipProjectManager->GetCrtGallery()- >GetCrtHotSpot()->iTip); ipDrawEngine->ibCenterToCrtHotSpot = false; ipDrawEngine->Update();
[0230] TKeyEvent aKeyEvent = {0}; aKeyEvent.iScanCode = EStdKeyDevice3; TEventCode aType; aType = EEventKey; HandleKeyEventUaKevEvent. aType) :
[0231] } } iPenDown = false; iPenDrag = false; iPointerEventUp = aPointerEvent; iPointerEventDrag. iPosition.iX = 0; iPointerEventDrag. iPosition.iY = 0; break; default:
[0232] {
[0233] Tint dummy = 1; dummy+ + ;
[0234] > } } void CHintController: :HandleUserTabSwitchEventL()
[0235] { if(ipDrawEngine) ipDrawEngine->ClearCache();
[0236] Tint index = GetActiveViewIndex(); PrepareViewToActivate( index); SetActiveViewBylndex(index); }
[0237] Tint CHintController: :ScrollTimerCallBack(TAny*)
[0238] { return 0;
[0239] }
[0240] TStdScanCode CHintController: :CheckPenDragDirection(const TPointerEvent& aPointerEventDragl, const TPointerEvent& aPointerEventDrag2)
[0241] {
[0242] TStdScanCode direction = EStdKeyNull;
[0243] TPoint delta = aPointerEventDrag2.iPosition - aPointerEventDragl. iPosition; if(delta.iX == 0 && delta. iY == 0)
[0244] { direction = EStdKeyNull;
[0245] > else if(delta.iX >= 0 && delta. iY >= 0)
[0246] { if(delta.iX > delta. iY) direction = EStdKeyRightArrow; else direction = EStdKeyDownArrow;
[0247] } else if(delta.iX >= 0 && delta. iY <= 0)
[0248] { delta. iY = -delta. iY; if(delta.iX > delta. iY) direction = EStdKeyRightArrow; else direction = EStdKeyUpArrow;
[0249] } else if(delta.iX <= 0 && delta. iY <= 0)
[0250] { delta. iX = -delta. iX; delta. iY = -delta. iY; if(delta.iX > delta. iY) direction = EStdKeyLeftArrow; else direction = EStdKeyUpArrow;
[0251] > else if(delta.iX <= 0 && delta. iY >= 0)
[0252] { delta. iX = -delta. iX; if(delta.iX > delta. iY) direction = EStdKeyLeftArrow; else direction = EStdKeyDownArrow;
[0253] } return direction;
[0254] } void CHintController: : DialNumberl_( const TDesC& aPhoneNumber)
[0255] {
[0256] RTelServer server;
[0257] CleanupClosePushLCserver);
[0258] User: : LeaveIfError(server.Connect());
[0259] TName tsy;
[0260] User: : LeaveIfError(server.GetTsyName(0, tsy)) ;
[0261] User: : LeaveIfError(server.LoadPhoneModu!e(tsy));
[0262] Tint numberPhones;
[0263] User: :LeaveIfError(server.EnumeratePhones(numberPhones));<'> if (numberPhones < 1)
[0264] User: : Leave(KErrNotFound);
[0265] RTelServer: :TPhoneInfo info;
[0266] User: : LeaveIfError(server.GetPhoneInfo(0, info));
[0267] RPhone phone;
[0268] CleanupClosePushL( phone);
[0269] User: : LeaveIfError(phone.Open(server, info.iName));
[0270] RPhone: :TLineInfo linelnfo;
[0271] User: : LeaveIfError(phone.GetLineInfo(0, linelnfo));
[0272] RLine line;
[0273] CleanupClosePushL(line);
[0274] User: : LeaveIfError(line.Open(phone, linelnfo. iName));
[0275] TBuf < 100> newCallName;
[0276] RCaII call;
[0277] CleanupClosePushL(call);
[0278] User: : LeaveIfError(call.OpenNewCall(line, newCallName));
[0279] User: :LeaveIfErrorfcall.Dialf aPhoneNumber));
[0280] CleanupStack: :PopAndDestroy(3);
[0281] User: : LeaveIfError(server.UnloadPhoneModule(tsy));
[0282] CleanupStack: :PopAndDestroy(&server); } 
[0283] APPENDIX B 2
[0284] const Tint KScrollStep = 20; const Tint KScrollArrow = 5;
[0285] CHintDrawEngine* CHintDrawEngine: :NewL()
[0286] {
[0287] CHintDrawEngine* self = CHintDrawEngine: : NewLC();
[0288] CleanupStack: :Pop(); return self; }
[0289] CHintDrawEngine* CHintDrawEngine: :NewLC()
[0290] {
[0291] CHintDrawEngine* self = new (ELeave) CHintDrawEngineQ;
[0292] CleanupStack: : PushL(self); self->ConstructL(); return self; } void CHintDrawEngine: :Constructl_()
[0293] { ipProjectManager = NULL; ipDisplayCallback = NULL; ipController = NULL; ipArrlmages = new (ELeave) CArrayPtrFlat<CHintImageAdapter> (1);
[0294] }
[0295] CHintDrawEngine: :CHintDrawEngine() : iClientRect(0, 0,0,0)
[0296] { iCrtlmage = -1; iMaxCachedAdapters = 1; iTopLeft.iX = 0; iTopLeft.iY = 0; ibMarkHotSpots = false; ibCenterToCrtHotSpot = true; ibScrollUpBtn = false; ibScrollDownBtn = false; ibScrollLeftBtn = false; ibScrollRightBtn = false;
[0297] }
[0298] CHintDrawEngine: : ~CHintDrawEngine()
[0299] { ipProjectManager = NULL; ipDisplayCallback = NULL; ipController = NULL; if (ipArrlmages)
[0300] { for(TInt idx = 0; idx < ipArrImages->Count(); + + idx) ipArrImages->At(idx)->Cancel(); ipArrImages->ResetAndDestroy(); delete ipArrlmages; ipArrlmages = NULL; } > void CHintDrawEngine: :ClearCache()
[0301] { if (ipArrlmages)
[0302] { for(TInt idx = 0; idx < ipArrImages->Count(); + + idx) ipArrlmages- >At(idx)->Cancel(); ipArrlmages- >ResetAndDestroy (); delete ipArrlmages; ipArrlmages = NULL;
[0303] > iCrtlmage = -1; ipArrlmages = new (ELeave) CArrayPtrFlat<CHintImageAdapter> (1); } void CHintDrawEngine: :SetProject(CHintProjectManager* apHintProjectManager)
[0304] { ipProjectManager = apHintProjectManager;
[0305] > void CHintDrawEngine: :SetController(MHintController* apController)
[0306] { ipController = apController;
[0307] } void CHintDrawEngine: :Update()
[0308] {
[0309] CHintlmageNavigator* pCrtlmageNav = ipProjectManager->GetCrtImgNav(); . TFileName crtlmageName = pCrtImageNav->iImageFileName; Tint idx = 0; for(idx = 0; idx < ipArrImages->Count(); ++idx)
[0310] { if(crtImageName == ipArrImages->At(idx)->GetImageFileName()) break;
[0311] > if(idx == ipArrImages->Count())
[0312] {
[0313] CHintlmageAdapter* plmageAdapter = NULL; plmageAdapter =
[0314] CHintlmageAdapter: :NewLC(NEikonEnvironment: :EikEnv().DefaultDisplayMode()); plmageAdapter- >SetImageFileName(crtImageName); plmageAdapter- >SetDispCallback(ipDisplayCallback); plmageAdapter- >SetEngCallback(this); plmageAdapter- >ExecuteCommandL(EDecodeImage); ipArrImages->AppendL(pImageAdapter); CleanupStack: :Pop(pImageAdapter); iCrtlmage = idx;
[0315] > else
[0316] { iCrtlmage = idx; CheckScrollersO; if(ibCenterToCrtHotSpot)
[0317] CenterToCrtHotSpot(); if(ipDisplayCallback) ipDisplayCallback->Redraw(); } } void CHintDrawEngine: :CenterToCrtHotSpot()
[0318] {
[0319] CHintHotSpot* pSpot = NULL; pSpot = ipProjectManager->GetCrtGallery()->GetCrtHotSpot(); iTopLeft.iX = iClientRect.iTI.iX + iClientRect.Width()/2 - (pSpot->iX + pSpot- >iWidth / 2); iTopLeft.iY = iClientRect.iTI.iY + iClientRect.Height()/2 - (pSpot->iY + pSpot- >iHeight / 2);
[0320] CFbsBitmap* bitmap = &(ipArrImages->At(iCrtImage)->Image());
[0321] Tint nBitmapHeight = bitmap->SizeInPixels().iHeight; if(iTopLeft.iY < = iClientRect.iTI.iY + iClientRect.HeightQ - nBitmapHeight) iTopLeft.iY = iClientRect.iTI.iY + iClientRect.Height() - nBitmapHeight; if(iTopLeft.iY >= iClientRect.iTI.iY) iTopLeft.iY = iClientRect.iTI.iY;
[0322] Tint nBitmapWidth = bit[pi][eta]ap->SizeInPixels().iWidth; if(iTopLeft.iX <= iClientRect.iTI.iX + iClientRect.Width() - nBitmapWidth) iTopLeft.iX = iClientRect.iTI.iX + iClientRect.Width() - nBitmapWidth; if(iTopLeft.iX >= iClientRect.iTI.iX) iTopLeft.iX = iClientRect.iTI.iX; <'>
[0323] > void CHintDrawEngine: :SystemRedraw()
[0324] { if(ipDisplayCallback) ipDisplayCallback->Redraw();
[0325] } void CHintDrawEngine: :ImageReady()
[0326] {
[0327] NormalizeHotSpots(iCrtlmage);
[0328] CenterToCrtHotSpot(); CheckScrollersO; ipController-> ImageReady (); if(ipDisplayCallback) ipDisplayCallback->Redraw();
[0329] } void CHintDrawEngine: :SetDisplayReference(MDisplayCallback* apDisplayRef)
[0330] { ipDisplayCallback = apDisplayRef; if(ipDisplayCallback)
[0331] { ipDisplayCallback->GetWindowClientRect(iClientRect);
[0332] TopLeft = iClientRect.iTI; > } void CHintDrawEngine: :Draw(CWindowGc& gc, const TRect&) const
[0333] { if(iCrtImage == -1) return; if(ipArrImages->At(iCrtImage)->GetErr() ! = KErrNone) return; if(!ipArrImages->At(iCrtImage)->ImageLoaded()) { return;
[0334] >
[0335] CFbsBitmap* bitmap = &(ipArrImages->At(iCrtImage)->Image()); TBool bUseVirtualTI = false; if(ipProjectMa[pi]ager->GetCrtImgNav()->iViewerType == 1)
[0336] { if(iTopLeft.iX > iClientRect.iTI.iX)
[0337] {
[0338] TPoint virtTopLeft(iTopLeft.iX - bitmap->SizeInPixels().iWidth, iTopLeftiY); gc.BitBlt(virtTopLeft, bitmap); bUseVirtualTI = true;
[0339] } gc.BitBlt(iTopLeft, bitmap);
[0340] } else <~> gc.BitBlt(iTopLeft, bitmap); CHintHotSpot* pSpot = NULL; gc.SetPenColor(KRgbRed); if(ibMarkHotSpots)
[0341] { for(TInt idx = 0; idx < ipProjectManager->GetCrtGallery()- >ipArrHotSpots->Count(); ++idx)
[0342] { pSpot = ipProjectManager->GetCrtGallery()->ipArrHotSpots-
[0343] >At(idx); gc.DrawRect( TRect( iTopLeft + TPoint(pSpot->iX, pSpot->iY), TSize(pSpot->iWidth, pSpot->iHeight) ) ); if(bUseVirtualTI)
[0344] {
[0345] TPoint virtTopLeft(iTopLeft.iX - bitmap- >SizeInPixels().iWidth, iTopLeft. iY); gc.DrawRect( TRect( virtTopLeft + TPoint(pSpot->iX, pSpot- >iY), TSize(pSpot->iWidth, pSpot->iHeight) ) );
[0346] } }
[0347] } pSpot = ipProjectManager->GetCrtGallery()->GetCrtHotSpot(); gc.DrawRect( TRect( iTopLeft + TPoint(pSpot->iX - 2, pSpot->iY - 2), TSize(pSpot->iWidth + 4, pSpot->iHeight + 4) ) );
[0348] DrawScrollers(gc); } void CHintDrawEngine: :ScrollUp()
[0349] { if(iTopLeft.iY == iCljentRect.iTI.iY) return; iTopLeft. iY += KScrollStep; if ( iTopLeft. iY >= iClientRect.iTI.iY) iTopLeft. iY = iClientRect.iTI.iY; CheckScrollersO; SystemRedrawQ;
[0350] > void CHintDrawEngine: :ScrollDown() CFbsBitmap* bitmap = &(ipArrImages->At(iCrtImage)->Image());
[0351] Tint nBitmapHeight = bitmap->SizeInPixels().iHeight; if(iTopLeft.iY = = iClientRect.iTI.iY + iClientRect.Height() - nBitmapHeight) return; iTopLeft.iY -= KScrollStep; if(iTopLeft.iY <= iClientRect.iTI.iY + iClientRect.HeightQ - nBitmapHeight) iTopLeft.iY = iClientRect.iTI.iY + iClientRect.HeightQ - nBitmapHeight; CheckScrollersQ; SystemRedraw();
[0352] } void CHintDrawEngine: :ScrollLeft()
[0353] { if(ipProjectManager->GetCrtImgNav()->iViewerType == 1)
[0354] { iTopLeft.iX += KScrollStep; if(iTopLeft.iX >= iClientRect.Width())
[0355] {
[0356] CFbsBitmap* bitmap = &(ipArrImages->At(iCrtImage)->Image()); Tint nBitmapWidth = bitmap->SizeInPixels().iWidth; iTopLeft.iX = iClientRect.Width() - nBitmapWidth; } } else
[0357] { if(iTopLeft.iX == iClientRect.iTI.iX) return; iTopLeft.iX += KScrollStep; if(iTopLeft.iX >= iClientRect.iTI.iX) iTopLeft.iX = iClientRect.iTI.iX;
[0358] }
[0359] CheckScrollersQ;
[0360] SystemRedrawQ;
[0361] void CHintDrawEngine: :ScrollRight()
[0362] {
[0363] CFbsBitmap* bitmap = &(ipArrImages->At(iCrtImage)->Image()); Tint nBitmapWidth = bitmap->SizeInPixels().iWidth; if(ipProjectManager->GetCrtImgNav()->iViewerType == 1)
[0364] { iTopLeft.iX -= KScrollStep; if(iTopLeft.iX <= iClientRect.WidthQ - nBitmapWidth)
[0365] { iTopLeft.iX = iClientRect.WidthQ;
[0366] } } else
[0367] { if(iTopLeft.iX == iClientRect.iTI.iX + iClientRect.WidthQ - nBitmapWidth) return; iTopLeft.iX -= KScrollStep; if(iTopLeft.iX <= iClientRect.iTI.iX + iClientRect.WidthQ - nBitmapWidth) iTopLeft.iX = iClientRect.iTI.iX + iClientRect.WidthQ - nBitmapWidth; } CheckScrollersQ; SystemRedrawQ; } void CHintDrawEngine: :NormalizeHotSpots(TInt aCrtlmage)
[0368] {
[0369] CFbsBitmap* bitmap = &(ipArrImages->At(aCrtImage)->Image()); Tint nBitmapWidth = bitmap->SizeInPixels().iWidth; Tint nBitmapHeight = bitmap->SizeInPixels().iHeight; if(!nBitmapWidth inBitmapHeight)
[0370] {
[0371] ASSERT(false); return;
[0372] }
[0373] CHintHotSpot* pSpot = NULL; for(TInt idx = 0; idx < ipProjectManager->GetCrtGallery()->ipArrHotSpots- >Count(); + + idx)
[0374] { pSpot = ipProjectManager->GetCrtGallery()->ipArrHotSpots->At(idx); pSpot->iX = TInt(nBitmapWidth * pSpot->iXsReal); pSpot->iY = TInt(nBitmapHeight * pSpot->iYsReai); pSpot->iWidth = TInt(nBitmapWidth * (pSpot->iXeReal - pSpot- >iXsReal)); pSpot->iHeight = TInt(nBitmapHeight * (pSpot->iYeReal - pSpot- >iYsReal));
[0375] > ipProjectManager->GetCrtGallery()->SortTheSpots();
[0376] } void CHintDrawEngine: :SetMarkHotSpots(TBool abMarkThem)
[0377] { ibMarkHotSpots = abMarkThem;
[0378] > void CHintDrawEngine: :CheckScrollers()
[0379] {
[0380] CFbsBitmap* pBitmap = &(ipArrImages->At(iCrtImage)->Image()); if(lpBitmap) return; ibScrollUpBtn = (iTopLeft.iY < iClientRect.iTI.iY); ibScrollDownBtn = (iTopLeft.iY + pBitmap->SizeInPixels().iHeight > iClientRect.iBr.iY); ibScrollLeftBtn = (iTopLeft.iX < iClientRect.iTI.iX); ibScrollRightBtn = (iTopLeft.iX + pBitmap->SizeInPixels().iWidth > iClientRect.iBr.iX); if(ipProjectManager->GetCrtImgNav()->iViewerType == 1)
[0381] { ibScrollLeftBtn = false; ibScrollRightBtn = false; } } void CHintDrawEngine: : DrawScrollers(CWindowGc& gc) const
[0382] {
[0383] TPoint ptOrig = TPoint(iClientRect.iTl.iX, iClientRect.iTI.iY);
[0384] Tint width = iClientRect.WidthQ; Tint height = iClientRect.HeightQ; Tint arrow = KScrollArrow; if(ibScrollLeftBtn) { gc.Drawl_ine(ptOrig + TPoint(0, height/2), ptOrig + TPoint(arrow, height/2 - arrow)); gc.Draw[upsilon]ne(ptOrig + TPoint(0, height/2), ptOrig + TPoint(arrow, height/2 + arrow)); gc.DrawLine(ptOrig + TPoint(arrow, height/2 - arrow), ptOrig + TPoint(arrow, height/2 + arrow));
[0385] > if(ibScrollRightBtn)
[0386] { gc.DrawLine(ptOrig + TPoint(width - arrow, height/2 - arrow), ptOrig + TPoint(width, height/2)); gc.Drawl_ine(ptOrig + TPoint(width - arrow, height/2 + arrow), ptOrig + TPoint(width, height/2)); gc.DrawLine(ptOrig + TPoint(width - arrow, height/2 - arrow), ptOrig + TPoint(width - arrow, height/2 + arrow));
[0387] } if(ibScrollUpBtn)
[0388] { gc.DrawLine(ptOrig + TPoint(width/2 - arrow, arrow), ptOrig + TPoint(width/2, O)); gc.DrawLine(ptOrig + TPoint(width/2, 0), ptOrig + TPoint(width/2 + arrow, arrow)); gc.DrawLine(ptOrig + TPoint(width/2 - arrow, arrow), ptOrig + TPoint(width/2 + arrow, arrow));
[0389] > if(ibScrollDownBtn)
[0390] { gc.Drawl_ine(ptOrig + TPoint(width/2 - arrow, height - arrow), ptOrig +
[0391] TPoint(width/2, height)); gc.DrawLine(ptOrig + TPoint(width/2, height), ptOrig + TPoint(width/2 + arrow, height - arrow)); gc.DrawLine(ptOrig + TPoint(width/2 - arrow, height - arrow), ptOrig + TPoint(width/2 + arrow, height - arrow));
[0392] } } void CHintDrawEngine: :ImagePosFromScree[pi]Pos(TPoint& almagePos, const TPoint& aScreenPos)
[0393] { almagePos = aScreenPos - iTopLeft; if(iTopLeft.iX > iClientRect.iTI.iX && aScreenPos. iX < iTopLeft. iX)
[0394] {
[0395] CFbsBitmap* bitmap = &(ipArrImages->At(iCrtImage)->Image());
[0396] TPoint virtTopLeft(iTopl_eft.iX - bitmap->SizeInPixels().iWidth, iTopLeft. iY); almagePos = aScreenPos - virtTopLeft; } } dth/2 - arrow, height - arrow), ptOrig + TPoint(width/2 + arrow, height - arrow));
[0392] } } void CHintDrawEngine: :ImagePosFromScree[pi]Pos(TPoint& almagePos, const TPoint& aScreenPos)
[0393] { almagePos = aScreenPos - iTopLeft; if(iTopLeft.iX > iClientRect.iTI.iX && aScreenPos. iX < iTopLeft. iX)
[0394] {
[0395] CFbsBitmap* bitmap = &(ipArrImages->At(iCrtImage)->Image());
[0396] TPoint virtTopLeft(iTopl_eft.iX - bitmap->SizeInPixels().iWidth, iTopLeft. iY); almagePos = aScreenPos - virtTopLeft; } } 
【図１】
2008516482.tif 000003
【図２−１】
2008516482.tif 000004
【図２−２】
2008516482.tif 000005
【図２−３】
2008516482.tif 000006
【図２−４】
2008516482.tif 000007
【図３−１】
2008516482.tif 000008
【図３−２】
2008516482.tif 000009
【図３−３】
2008516482.tif 000010
【図３−４】
2008516482.tif 000011
【図４−１】
2008516482.tif 000012
【図４−２】
2008516482.tif 000013
【国際調査報告】
2008516482.tif 000014
2008516482.tif 000015