スケールと回転

スケール変更とその問題点

iPhone / iPod Touch / iPad の有利な点はハードウェアが固定されている事です。特に固定された画面解像度だと座標を決め打ちで指定できますし、画像をふんだんに使うことができます。第3世代の iPad は 2,048×1,536 という解像度を持っていますが、これは必然でした。1,920×1,080 は絶対に採用されなかったと思います。何故なら、それまでの iPad は 1,024×768 であったからです。縦横 2 倍、面積比 4 倍であれば、過去に作られたソフトウェアが問題なく動作し、画像の拡大もリニア 2 倍で済むので、画像がボケたりする事はありません。

しかしながら、Windows / Mac OSX / Android 等は一筋縄ではいきません。使われているディスプレイのサイズはまちまちですし、特に Windows / OSX は基本的にリサイズ可能なマルチウィンドウだからです。

Windows アプリを作っていると、「ディスプレイを変えたらアプリの画面が小さくなった」 という事をよく言われます。もちろん、アプリの画面が小さくなっているのではありません。解像度が高くなったために相対的にアプリケーションの画面が小さくみえてしまうのです。加えて、「ディスプレイ変えたら文字が小さくてよく見えない」 「全画面で表示したい」 と困ったことを言われる事があります。

VCL アプリケーションでは、ChangeScale() というメソッドを呼べば、フォームのサイズを任意に変更する事ができます。しかし、この機能は多くの場合期待通りに動作しません。Windows ではフォントの拡大/縮小に一定の制限があるため、収まっていたはずの文字列がコントロールをはみだしてしまって見切れたり、ワードラップ行数が増えておかしな事になったりします。

...これらの制限は Delphi / C++Builder によるものなのでしょうか?いいえ、違います。例えば、Excel を例に取って検証してみましょう。

  

セルに "折り返して表示" を指定したものを、右下のスライダーで縮小してみた所です。ワードラップ位置も違えば、セルにキッチリ収まってもいません。このように、フォントのサイズや縮尺率によってはレイアウトが破綻してしまうのです。

加えて VCL 側の問題もあります。一部のコントロールはサイズだけしか拡大/縮小されないものがあり、例えば、VCL の TStringGrid は拡大/縮小してもカラム幅等は追従しません。

このスケールの問題が何故重要なのか、そしてその対応策が如何に困難なものであるかは、"高 DPI 対応の Win32 アプリケーションを記述する (Windows デベロッパー センター)" を読んで頂ければお解り頂けると思います。

FireMonkey のスケール変更

FireMonkey では、コントロールを自前で描画しているため、上記のような問題は一切発生しません。

  

画像は、フォームに TScaledLayout を "Align = alFit" で貼り、フォームをリサイズしてみた所です。破綻なく拡大されているのが判ります。キャプチャ画像を単純に拡大したというトリックではない事は、キャプションバーのサイズやウィンドウフレーム枠の幅を見れば一目瞭然でしょう。グリッドの幅や高さもスケール変更に追従している事が判ります。

上記でフォームのリサイズによるスケール変更をご紹介しましたが、フォームやコントロールにある Scale プロパティを変更する事でもスケール変更を行う事ができます。アニメーション効果と組み合わせると面白い視覚効果を狙う事ができます。

回転とその問題点

昨今のモバイル系端末には 3 軸加速度センサーやジャイロセンサーが内蔵されています。これによって傾きが検知され、画面の方向が変わります。

Windows のスレート PC だと、画面の回転はハードウェアの機能で行われます。当サイトの "スレート PC プログラミング" には回転の検知方法や、回転検知後に画面を回転させる方法を記載してあります。そして、結論付けてありますね、"縦横で UI を変更すべき" だと。

しかしながら、ハードウェアによる画面の回転はコストが高すぎます。これは、コントロールパネルから画面の解像度を変更した時に数秒掛かる PC がある事でもお解り頂けるでしょう。"Windows でのハードウェアによる画面の回転は解像度変更と同じコストが掛かる" のです。場合によっては回転に 1~2 秒掛かりますし、それ以前の問題として 90°単位での回転しかできません。

FireMonkey の回転

FireMonkey では、コントロール単位で回転が可能です。親コントロールを回転させれば配置されている子コントロールも同時に回転します。

RotationAngle プロパティで任意の角度を指定 (時計回り / 単位は度) できますし、入力系のコントロールは回転した状態で文字入力可能です。もちろん、日本語入力も可能です。

画面回転の用途であれば、RotationCenter プロパティの X / Y を初期値の 0.5 で使います。初期値のままだとコントロールはコントロールの中央を軸として回転が行われます。X=0 / Y=0 だと回転軸はコントロールの左上、X=1 / Y=1 だと、回転軸はコントロールの右下になります。

この回転機能を使って新しい UI を工夫する事もできます。例えば、TSwitchTPanel 上に複数並べた上で TPanel を回転させると...

ディップスイッチの UI を作ることができました。

この回転機能は他にも応用が利きます。3D モデルを表示しておき、センサーの傾きによってモデルの向きや位置を変更するという事も可能です。これで動画系コンポーネント (Web カメラ入力をそのままプレビューできればなお良し) があれば、AR (拡張現実) のような事ができたのですが...それは今後に期待するとしましょうか。

See Also:


 BACK