フォーラム


ゲスト  

ようこそ ゲスト さん。このフォーラムに投稿するには 登録が必要です。

ページ: 1 [2] 3 4
トピック: Delphi Advent Calendar 2013
DEKO
管理者
投稿数: 2645
Re: Delphi Advent Calendar 2013
on: 2013/12/04 11:12 Wed

引用 Mr.XRAY on 2013/12/03 23:22 Tue
それを読んで CPU 開発の中心人物であった,嶋という方のことを思い出していた記憶があります.

 
そういえば、デブキャンで FireDAC のセッションをされた田中さんがいらっしゃる会社は、その嶋さんが在籍されていた旧ビジコンだという事を知ってちょっとびっくりしました。

DEKO
管理者
投稿数: 2645
12/04 超とりあえず、現在地をシェアするiPhoneアプリをXcodeとDelphi XE5で作って比べてみた
on: 2013/12/04 22:21 Wed

[超とりあえず、現在地をシェアするiPhoneアプリをXcodeとDelphi XE5で作って比べてみた]
http://dhive.jp/blog/yama/11209.html

DEKO
管理者
投稿数: 2645
12/05 Assertの話(1)
on: 2013/12/05 00:07 Thu

[Assertの話(1)]
http://uskz.hatenablog.com/entry/2013/12/05/000020

DEKO
管理者
投稿数: 2645
12/06 RadStudio XE4のHelpにてWe are sorryが出るときの対処方法
on: 2013/12/06 12:22 Fri

[RadStudio XE4のHelpにてWe are sorryが出るときの対処方法]
http://qiita.com/sevenOfNine/items/76787e7aabee37e7e383

DEKO
管理者
投稿数: 2645
12/07 7 セグ(電卓表示)のコンポーネントを作成する。
on: 2013/12/07 01:30 Sat

[7 セグ(電卓表示)のコンポーネントを作成する。]
http://i65000.blogspot.jp/2013/12/7.html

DEKO
管理者
投稿数: 2645
12/08 FireMonkey - OS X でバージョン情報を取得する
on: 2013/12/08 14:06 Sun

[FireMonkey - OS X でバージョン情報を取得する]
http://softlab.masa-lab.net/modules/d3blog/details.php?bid=27

DEKO
管理者
投稿数: 2645
12/09 顔認識 (FMX と OpenCV でリアルタイムに顔認識 )
on: 2013/12/09 01:13 Mon

[FMX と OpenCV でリアルタイムに顔認識]
http://www.luxidea.net/delphi-lab/facedetect/

DEKO
管理者
投稿数: 2645
12/10 プロパティエディタを作ってみる (1/3)
on: 2013/12/10 00:06 Tue

{ これは Delphi Advent Calendar 2013 の 12/10 分の記事です }

Delphi といえばコンポーネントを作って開発効率を向上させる事ができるのも特徴の一つですね。コンポーネントの作り方はさておき、慣れないコンポーネントで作業効率を向上させるには

  • コンポーネントエディタ
  • プロパティエディタ

の存在が不可欠だと思います。これらはマニュアルを読まないと理解できないプロパティの値であるとか、オブジェクトインスペクタからは設定できない (しづらい) プロパティの値をセットするのに使われます。

コンポーネントエディタとプロパティエディタの違いですが、前者はコンポーネント全体、あるいは他のプロパティの値に連動して変化するようなプロパティを設定するのに使われます。後者は特定のプロパティのみを更新するものです。オブジェクトインスペクタで設定するものが、今回ご紹介するプロパティエディタです。

プロパティエディタは以下のTPropertyEditor 派生クラスを継承して作ります。

  • TBoolProperty
  • TCharProperty
  • TClassProperty
  • TComponentNameProperty
  • TComponentProperty
  • TDateProperty
  • TDateTimeProperty
  • TEnumProperty
  • TFloatProperty
  • TInt64Property
  • TIntegerProperty
  • TInterfaceProperty
  • TMethodProperty
  • TNestedProperty
  • TSetElementProperty
  • TSetProperty
  • TStringProperty
  • TTimeProperty
  • TVariantProperty
  • TWideCharProperty
  • TWideStringProperty

プロパティの型に応じて派生元のクラスを選択します。

[プロパティエディタ クラスを派生させる (DocWiki)]
http://docwiki.embarcadero.com/RADStudio/ja/%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF_%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E6%B4%BE%E7%94%9F%E3%81%95%E3%81%9B%E3%82%8B

これだけではまだピンとこないと思うので、プロパティエディタを実際に作りながら解説したいと思います。

TLabel (VCL) には Caption というプロパティがあります。TCaption は String 型なので、オブジェクトインスペクタで設定する事ができます。ここにプロパティエディタの存在意義はないように思えますよね?しかしながら、TLabel の Caption は実際には改行コードを含めて複数行表示が可能なのです…オブジェクトインスペクタではどうやっても改行を入力できません。これを可能にするにはプロパティエディタが必要になります。

[frmuStringPropEditor.pas]
{*******************************************************}
{ }
{ 文字列用プロパティエディタダイアログ }
{ }
{*******************************************************}
unit frmuStringPropEditor;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Controls, Forms,
Consts, Dialogs, StdCtrls, ExtCtrls, DesignIntf, DesignEditors;

type
{TfrmStringPropertyEditor}
TfrmStringPropEditor = class(TForm)
pnlBottom: TPanel;
mmString: TMemo;
btnOK: TButton;
btnCancel: TButton;
procedure FormCreate(Sender: TObject);
procedure mmStringKeyPress(Sender: TObject; var Key: Char);
public
function ShowModal(PropName: string): Integer; reintroduce; overload;
end;

{ TCustomizedStringProperty }
TCustomizedStringProperty = class (TStringProperty)
public
procedure Edit; override;
function GetAttributes: TPropertyAttributes; override;
end;

implementation

{$R *.dfm}

{TfrmStringPropertyEditor}

procedure TfrmStringPropEditor.FormCreate(Sender: TObject);
// フォーム作成時
begin
btnOK.Caption := SOKButton;
btnCancel.Caption := SCancelButton;
mmString.Font.Size := mmString.Font.Size + 1; // 好みで調整してください
end;

procedure TfrmStringPropEditor.mmStringKeyPress(Sender: TObject;
var Key: Char);
// TMemo で 〔Ctrl〕+〔A〕による全選択を可能にする
begin
if Key = ^A then
begin
(Sender as TMemo).SelectAll;
Key := #$00;
end;
end;

function TfrmStringPropEditor.ShowModal(PropName: string): Integer;
// ShowModal オーバーロードメソッド
begin
Caption := Format('%s: %s', [SPropertiesVerb, PropName]);
result := inherited ShowModal;
end;

{ TCustomizedStringProperty }

procedure TCustomizedStringProperty.Edit;
// プロパティ編集用メソッド
var
StringPropertyEditor: TfrmStringPropEditor;
begin
inherited;
StringPropertyEditor := TfrmStringPropEditor.Create(nil);
try
StringPropertyEditor.mmString.Text := Self.GetStrValue;
if StringPropertyEditor.ShowModal(Self.GetName) = mrOK then
SetStrValue(StringPropertyEditor.mmString.Text);
finally
StringPropertyEditor.Free;
end;
end;

function TCustomizedStringProperty.GetAttributes: TPropertyAttributes;
// プロパティエディタ属性取得メソッド
begin
result := [paDialog, paMultiSelect]; // ダイアログ形式プロパティエディタ, 複数選択対応
end;

end.

 
ダイアログを出してプロパティを設定するタイプのプロパティエディタはこのようなコードになります。今回のような簡単なプロパティエディタは Edit() メソッドと GetAttributes() メソッドを実装するだけなのでそう難しいものではないと思います。

プロパティエディタはコンポーネント同様、(設計時) パッケージに登録して利用するのですが、そのためにはパッケージ登録用のユニットが必要となります。プロパティエディタのユニットの中にパッケージ登録用のコードを書いてもいいのですが、複数のプロパティエディタを登録できるよう、パッケージ登録用のユニットは別にしておいた方が管理はしやすいかと思います。

[uStringPropEditorReg.pas]
{*******************************************************}
{ }
{ String プロパティエディタ登録用ユニット }
{ }
{*******************************************************}
unit uStringPropEditorReg;

interface

uses
Controls,
DesignIntf;

procedure Register;

implementation

uses
frmuStringPropEditor; // 文字列用プロパティエディタ

procedure Register;
begin
// String 型のプロパティ (すべて) に関連付け
RegisterPropertyEditor(TypeInfo(string), nil, '', TCustomizedStringProperty);

// TCaption 型のプロパティ (すべて) に関連付け
RegisterPropertyEditor(TypeInfo(TCaption), nil, '', TCustomizedStringProperty);
end;
end.

 
プロパティが String 或いは TCaption 型の場合にプロパティエディタを表示できるようにしています。TLabel の Caption プロパティ専用にするのは勿体無いですからね。ちなみに、クラスやプロパティ名を限定してプロパティエディタを表示させる事も可能です。

ここまでできれば、パッケージを作って組み込むだけとなります。実際に動作しているスクリーンショットがコレです。

オブジェクトインスペクタで Caption プロパティの右端にある […] ボタンを押すとダイアログ形式のプロパティエディタが開きます。ダイアログのキャプションやボタンのキャプションは文字列定数 (Consts.pas) から持ってきていますので、Delphi 2010 以降ならライブラリの言語を切り替えて英語版を作る事ができます。

この String 用プロパティエディタは VCL / FMX いずれでも利用できるのですが、改行コードを含む TLabel を OS X で表示すると空行ができてしまいます。これは Windows の改行コードが CRLF なのに対し、OS X が LF のみであるからです。この問題を回避するには

  • Delphi のプリプロセッサでフォームファイル (*.FMX) をパースしCRLF を LF に置換
  • Delphi のポストプロセッサでフォームファイル (*.FMX) をパースしLF を CRLF に置換

このような解決方法が考えられます。他の解決方法として、ターゲットプラットフォームが Windows 以外の場合には OnCreate 等で CRLF を LF に置換するという方法もありますが、いずれにせよ面倒なのでマルチプラットフォームを対象とするのであればコードで改行した方が簡単かもしれません。

プロパティエディタ側に改行コードを指定できるようにするという解決方法では、別プラットフォームをコンパイルする度にプロパティエディタを開かなくてはならず、効率面から考えると本末転倒な気がします。

DEKO
管理者
投稿数: 2645
12/10 プロパティエディタを作ってみる (2/3)
on: 2013/12/10 00:06 Tue

細川さんが twitter で以下のようなツイートをされました。

引用 @pik on twitter 2013/12/02
https://twitter.com/pik/status/407427086089854976
TAlignLayout のプロパティエディタ
(DocWiki の説明を図示した画像を表示する http://docwiki.embarcadero.com/Libraries/XE5/ja/FMX.Types.TAlignLayout
作りたかったけど、それどころじゃない。誰か作ってくれないかなー……(チラッ

 
Delphi Advent Calendar のネタに困っていたので渡りに船… んじゃ、作りますか (w

FireMonkey 用のプロパティエディタだからと臆する事はありません。プロパティエディタを FireMonkey で作らなければならないという理由はないからです。

TAlignLayout というのは、VCL で言う TAlign で、FireMonkey の Align プロパティの型です。TAlignLayout は TAlign よりも多くの値があります。名前からではどういった動作になるのか判断しにくいので、画像で例示してやればイチイチヘルプを引く必要もなくなります。

参考になるのは Cursor プロパティでしょうか?Cursor プロパティは値をドロップダウンするとカーソルの形状が画像で表示されるので一目瞭然ですよね。

[uAlignPropEditor.pas]
{*******************************************************}
{ }
{ TAlignLayout プロパティエディタ }
{ }
{*******************************************************}
unit uAlignPropEditor;

interface

uses
System.Types, System.SysUtils, FMX.Types, WinAPI.Windows, Vcl.Graphics,
DesignIntf, DesignEditors, VCLEditors;

type
TAlignProperty = class(TEnumProperty, ICustomPropertyListDrawing)
public
function GetAttributes: TPropertyAttributes; override;
{ ICustomPropertyListDrawing }
procedure ListMeasureHeight(const Value: string; ACanvas: TCanvas;
var AHeight: Integer);
procedure ListMeasureWidth(const Value: string; ACanvas: TCanvas;
var AWidth: Integer);
procedure ListDrawValue(const Value: string; ACanvas: TCanvas;
const ARect: TRect; ASelected: Boolean);
end;

implementation

uses
System.Math;

const
ICON_HEIGHT = 32;
ITEM_HEIGHT = ICON_HEIGHT + 4;

{ TAlignProperty }

function TAlignProperty.GetAttributes: TPropertyAttributes;
// プロパティエディタの属性を返す
begin
result := [paMultiSelect, paValueList, paSortList, paRevertable];
end;

procedure TAlignProperty.ListDrawValue(const Value: string; ACanvas: TCanvas;
const ARect: TRect; ASelected: Boolean);
// リスト (コンボボックス) の描画
var
Right: Integer;
Bitmap: TBitmap;
begin
Right := ARect.Left + ITEM_HEIGHT;
with ACanvas do
begin
FillRect(ARect);
// アイコンの描画
Bitmap := TBitmap.Create;
try
Bitmap.LoadFromResourceName(hInstance, UpperCase('IMG_' + Value));
Draw(ARect.Left + 2, ARect.Top + 2, Bitmap);
finally
Bitmap.Free;
end;
// 値の描画
DefaultPropertyListDrawValue(Value, ACanvas,
Rect(Right, ARect.Top, ARect.Right, ARect.Bottom), ASelected);
end;
end;

procedure TAlignProperty.ListMeasureHeight(const Value: string;
ACanvas: TCanvas; var AHeight: Integer);
// リスト (コンボボックス) の高さを設定
begin
AHeight := Max(ACanvas.TextHeight('Wg'), ITEM_HEIGHT);
end;

procedure TAlignProperty.ListMeasureWidth(const Value: string; ACanvas: TCanvas;
var AWidth: Integer);
// リスト (コンボボックス) の幅を設定
begin
AWidth := AWidth + ITEM_HEIGHT;
end;

end.

 
TAlignLayout は列挙型なので、TEnumProperty から派生し、ドロップダウンした時だけ判ればいいプロパティなので、ICustomPropertyListDrawing インターフェイスを加えてあります。このインターフェイスは VCLEditors で定義されています。

ICustomPropertyListDrawing は、プロパティの値のリスト (コンボボックス) を自前で描画するのに利用するインターフエイスで、ListDrawValue / ListMeasureHeight / ListMeasureWidth を実装するだけです。前回にご紹介した文字列用プロパティエディタと同じく GetAttributes も実装してありますが、今回はダイアログ形式のプロパティエディタではないので、Edit メソッドの実装はありません。

Color プロパティのように、ドロップダウンしていない時にも自前で描画する必要があったり、値部分ではなくプロパティ名の部分を自前で描画しなければならない時には追加で別のインターフェイスを加えてメソッドを実装する必要があります。

実際に動作している画像は以下になります。

プロパティエディタも、作り方が判ってしまえば大した事はないでしょう?事実、プロパティエディタを作っている時間よりも画像を用意している時間の方が長かったですからね (^^;A

画像の意味は以下の通りです。

  • 赤線: アンカー
  • 青線: 非アンカー
  • 黒矢印: 親がリサイズされた時にリサイズされる方向。対角線の矢印はアスペクト比固定のリサイズ。
  • 緑矢印: 寄せの方向

直感的に理解しやすい画像にしてみたつもりですけれどいかがでしょうか?

See Also:

[FMX.Types.TAlignLayout (DocWiki)]
http://docwiki.embarcadero.com/Libraries/ja/FMX.Types.TAlignLayout

DEKO
管理者
投稿数: 2645
12/10 プロパティエディタを作ってみる (3/3)
on: 2013/12/10 00:07 Tue

そして細川さんが twitter で以下のようなツイートをされました。

引用 @pik on twitter 2013/12/02
https://twitter.com/pik/status/407694851665190912
@ht_deko 最初は実は TInterpolationType 用のプロパティエディタを作ろうとしたんです(DEKO さんのページの画像を表示させる)でも画像を用意するのが面倒だったのと、あれ?それだったら TAlignLayout の方が使いでがあるのでは?という思いに……

 
Delphi Advent Calendar のネタに困っていたので渡りに船… そうだね、細川さん!アナタの言う通りだよ!!

…という事で TInterpolationType のプロパティエディタも作る事にしました。"DEKO さんのページの画像" というのはコレ (http://ht-deko.minim.ne.jp/techf001_animations.html) の事です。

まぁ、TAlignLayout のプロパティエディタをちょこっといじるだけで作れますからね。面倒なのは画像を用意する事なのですから…(ToT)

そして出来たのがコレです。

確かに一目瞭然ですね。"itQu" で始まる名前が多いのでどれが何なのか訳がわからなくなるという事もないかと思います…ただ、画像だけではカーブの違いが判りにくいものがあるので、文字で式を書いて視認性をよくしてみました (itCircular だけは arc って文字で誤魔化してますけれど)。

これでも充分実用的ではあるのですが、Interpolation プロパティは AnimationType プロパティと密接な関係にあるので、もう少し直感的にプロパティを設定したいのであれば、プロパティエディタではなくコンポーネントエディタを作るべきなのでしょうね。

…さてさて、今回の記事では 3 種類のプロパティエディタを紹介してみましたが、いかがだったでしょうか?"作り方" と銘打っておきながらあまり作り方は紹介していませんが、"$(BDS)\source\Property Editors" には、標準で使われているプロパティエディタのソースコードが格納されていますので、それを参考にすればプロパティエディタを作るのはそう難しいものではないと思います。

何度使ってもヘルプを読まないと思い出せないようなプロパティは、 "プロパティエディタを作って作業の効率化を図る" というのも一考の価値があると思いませんか?特にチームで Delphi を使っている企業にとっては "学習コストを下げる" という意味でも有用な手段ではないでしょうか?

See Also:
[FMX.Types.TInterpolationType (DocWiki)]
http://docwiki.embarcadero.com/Libraries/ja/FMX.Types.TInterpolationType
[プロパティエディタの追加 (DocWiki)]
http://docwiki.embarcadero.com/RADStudio/ja/%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF%E3%81%AE%E8%BF%BD%E5%8A%A0

一連の記事で紹介したプロパティエディタのアーカイブは以下にあります。利用制限は特にないのでご自由にお使いください。

ダウンロード:
[String プロパティエディタ]
http://ht-deko.minim.ne.jp/delphiforum/?vasthtmlaction=viewtopic&t=1363
[TAlignLayout プロパティエディタ]
http://ht-deko.minim.ne.jp/delphiforum/?vasthtmlaction=viewtopic&t=1364
[TInterpolation プロパティエディタ]
http://ht-deko.minim.ne.jp/delphiforum/?vasthtmlaction=viewtopic&t=1362

※ String 用プロパティエディタは VCL / FMX いずれでも使えます。
※ String 用プロパティエディタは dproj を削除して dpk からインストールするか、パッケージを自分で作れば 古い Delphi でも利用可能です。
※ TAlignLayout / TInterpolationType 用プロパティエディタは FireMonkey 用です。

ページ: 1 [2] 3 4
WP Forum Server by ForumPress | LucidCrew
バージョン: 1.7.5 ; ページロード: 0.064 sec.