DelFusa Blog 総本山

プログラミングの話題とかです。

NEW | PAGE-SELECT | NEXT

≫ EDIT

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

| スポンサー広告 | --:-- | comments(-) | trackbacks(-) | TOP↑

≫ EDIT

位置とサイズを%で指定してみる。ScaledLayout


  ∧,,∧  サムイ ヒハ
  ミ,,゚ 3 ゚彡    アツイ オチャニ カギル
  ミ つ旦)~~
~と,,,~),,~) 


さてさて、いまさらながら、Scaledレイアウトを実装してみました。

ちょっと前から適当にパラパラっと作った
アノニマスさん対策ソフト....じゃなかった....
タイムキーパーさん用のパネリストコントローラー黒板ソフトで使いたかったから。


最近の.NET、WPFでも、コントロールの位置情報はピクセル指定や%指定できます。
Windows8スタイルはそういうの考える事はないかもしれませんが、
リサイズ可能なデスクトップアプリではいろいろ考える必要があります。


黒板ソフトは、VCLのアンカープロパティでやっていたのですが
このアンカープロパティはピクセル指定のみですから、相対的に今時はちょっと不便というか時代遅れでしょう。

Formサイズにあわせて、%でコントロールが可変するような仕組みが欲しいものでして、

XE3のFireMonkeyでは、こんなレイアウト設定が出来る様子です。

FireMonkey のレイアウト戦略 - RAD Studio XE3
http://docwiki.embarcadero.com/RADStudio/XE3/ja/FireMonkey_のレイアウト戦略


ですが、俺が未だにFireMonkeyをもっていないのと
ちょっと、まあ、この程度は実装しておいてもいいかなと思い、さらっと作ってみました。

旧バージョンから新バージョンへの移行というのが
Delphi業界の旬ですから、旧バージョンのレイアウトを改良して
スケールレイアウトにしたい人にも、これが使えるかもしれませんね。



ユニット化しておいたソースはこんな感じ


unit ScaleLayoutUnit;

interface

uses
 Controls,
 Generics.Collections,

end_uses;

type
 TRectExtended = record
 private
  procedure SetWidth(const Value: Extended);
  procedure SetHeight(const Value: Extended);
  function GetHeight: Extended;
  function GetWidth: Extended;
 public
  Left, Top, Rigth, Bottom: Extended;
  property Width: Extended read GetWidth write SetWidth;
  property Height: Extended read GetHeight write SetHeight;
 end;

 TScaleLayoutItem = class
  TargetControl: TControl;
  TargetDesignedRect: TRectExtended;
  ParentControl: TControl;
 end;

 TControlScaleLayout = class
  FScaleLayoutControlList: TObjectList;
 public
  constructor Create;
  destructor Destroy; override;
  procedure SetInitialize(Target: TControl);
  procedure ResizeLayout(Target: TControl);
 end;


implementation


{ TRectExtended }

function TRectExtended.GetHeight: Extended;
begin
 Result := Bottom - Top;
end;

function TRectExtended.GetWidth: Extended;
begin
 Result := Rigth - Left;
end;

procedure TRectExtended.SetHeight(const Value: Extended);
begin
 Bottom := Top + Value;
end;

procedure TRectExtended.SetWidth(const Value: Extended);
begin
 Rigth := Left + Value;
end;

{ TControlScaleLayout }

constructor TControlScaleLayout.Create;
begin
 FScaleLayoutControlList := TObjectList.Create;
 FScaleLayoutControlList.OwnsObjects := True;
end;

destructor TControlScaleLayout.Destroy;
begin
 FScaleLayoutControlList.Free;
 inherited;
end;

procedure TControlScaleLayout.SetInitialize(Target: TControl);
var
 ScaleItem: TScaleLayoutItem;
begin
 ScaleItem := TScaleLayoutItem.Create;
 ScaleItem.TargetControl := Target;
 ScaleItem.ParentControl := Target.Parent;
 with ScaleItem.TargetDesignedRect do
 begin
  Left := Target.Left / Target.Parent.ClientWidth;
  Width := Target.Width / Target.Parent.ClientWidth;
  Top := Target.Top / Target.Parent.ClientHeight;
  Height := Target.Height/ Target.Parent.ClientHeight;
 end;

 FScaleLayoutControlList.Add(ScaleItem)
end;

procedure TControlScaleLayout.ResizeLayout(Target: TControl);
var
 Index, I: Integer;
begin
 Index := -1;
 for I := 0 to FScaleLayoutControlList.Count - 1 do
 begin
  if FScaleLayoutControlList.Items[I].TargetControl = Target then
  begin
   Index := I;
   Break;
  end;
 end;

 if Index <> -1 then
 begin
  with FScaleLayoutControlList.Items[Index] do
  begin
   TargetControl.Left := Round(TargetDesignedRect.Left * ParentControl.ClientWidth);
   TargetControl.Width := Round(TargetDesignedRect.Width * ParentControl.ClientWidth);
   TargetControl.Top := Round(TargetDesignedRect.Top * ParentControl.ClientHeight);
   TargetControl.Height:= Round(TargetDesignedRect.Height* ParentControl.ClientHeight);
  end;
 end;
end;

end.


使い方は簡単。
SetInitializeとResizelayoutを呼び出すだけ。

procedure TFormMain.FormCreate(Sender: TObject);
begin
 FControlScaleLayout := TControlScaleLayout.Create;
 FControlScaleLayout.SetInitialize(Label1);
 FControlScaleLayout.SetInitialize(Label2);
 FControlScaleLayout.SetInitialize(Label3);
end;

procedure TFormMain.FormDestroy(Sender: TObject);
begin
 FControlScaleLayout.Free;
end;


procedure TFormMain.FormResize(Sender: TObject);
begin//
 FControlScaleLayout.ResizeLayout(Label1);
 FControlScaleLayout.ResizeLayout(Label2);
 FControlScaleLayout.ResizeLayout(Label3);
end;

これで、小さいときのレイアウトが大きくしても
比率が同じで拡大されます。

Label1を青、Label3を赤にして、サイズを変更して動かしてみました。


001281.png

001282.png

昔はニュートンって所でリサイズコンポーネントがありました。
(今もあるようです)
ニュートン製品案内 ResizeKit2(フォームリサイズコンポーネント/コントロール・ソフト開発ツール)
http://www.newtone.co.jp/productrs200.html

全自動でフォントサイズまで変更してくれて
お安く高機能そうなので、これを使って業務アプリを作る人も多そうですが
スクラッチビルド的な実装でも、そんなに難しくは無いようですね。

これでちょっと黒板ソフトの性能がアップで、
大きい画面の縮小サイズで小さい画面が表示されるようになりました。


001283.png

001284.png

ちょっとデカデカと主張してみました。
デベロッパーキャンプで客席からでもパネリストに意見が届くように見せつける事ができますよ。

早く欲しいですね。
DelphiでiPhoneアプリやアンドロイドアプリが作れるモバイルスタジオ...

スポンサーサイト

| 未分類 | 01:19 | comments:0 | trackbacks(-) | TOP↑

COMMENT















非公開コメント

PREV | PAGE-SELECT | NEXT

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。