FMXでTPaintBoxでの描画範囲とvclでのTUpDownに相当するコンポーネント

解決


yTake  2019-04-01 02:23:23  No: 49724

yTakeです。

1)
以前、質問させて頂いて描画は可能になりました。その配置に疑問があります。
作成したBitmap画像をPaintBoxへ描画する事を考えます。
Form上にPanelを配置しその上にPaintBoxを配置しています。
PanelのPositionはX=8,y=8(LeftTop座標)で、PaintBoxのPositionもX=8,y=8(LeftTop座標)です。
コードを、
sRect :=  TRectF.Create( 0, 0, bmp.width - 1, bmp.Height - 1 );
dRect :=  TRectF.Create( 0, 0, PaintBox1.Width - 1, PaintBox1.Height - 1 );
AOpa  :=  1;
PaintBox1.Canvas.BeginScene();
PaintBox1.Canvas.DrawBitmap( bmp, sRect, dRect, AOpa );
PaintBox1.Canvas.EndScene();
としました。
描画はされるのですが、描画される位置が想定と違います。意図としてはPanelの原点(LeftTop)から(8,8)のところ(PaintBoxの原点(0,0))から描画させたかったのですが、何故かFormの原点(0,0)から描画されています。つまり、Panelの原点からみれば(-8,-8)になります。
Form座標系で言えば(16,16)が意図する座標になります。
DrawBitmap手続きの第2第3引数の矩形で、第2はコピー元のBitmapの範囲を示し、第3はコピー先のPaintBoxの範囲を示すと思います。
つまり、配置したPaintBox1の(0,0)(=Panel1の(8,8)(=Form1の(16,16)))から描画させたいのですが、実際はFormの(0,0)から描かれています。
PaintBoxの原点或いは任意の領域に描画するにはどの様にするのでしょう?

2)
FMXではvclでのTUpDownが見当たりません。代わりにTSpiンBoxを使っています。
矢印の配置を上下にしたいのですが、配置は変更できない様です。
問題といいますか、疑問は、Incrementを0.1に設定しDecimalDigitsを1、ValueTypeをFloatとした場合、整数の表示が”1.0”や”2.0”ではなく”1”,”2”となっていて少数部の”.0”が表示されません。動作上は問題ないのですが、何故でしょう?何か設定で改善されるのでしょうか?

以上、ご教授願えるでしょうか?

当方、
32bitWin10+Delphi XE6
です。

よろしくお願いします。


yTake  2019-04-01 03:01:48  No: 49725

自己レスです。

質問の趣旨が微妙ですね。

単に描画位置を合わせるだけなら、第3引数にForm座標系で描画領域の原点にオフセット(Panelの座標+PaintBoxの座標)を持たせる事で合います。

第3引数はコピー先座標系での値と解釈されます。その意味ではオフセットの必要性が理解できません。
第3引数は描画先Canvas(DrawBitmapを読んでいるコンポーネント(本例の場合PaintBox))が配置されているFormの座標系で指定するのでしょうか?

因みに、第2引数は描画元Bitmapの座標系で指定して意図する範囲を抽出出来ています。

第3引数は描画先の座標系で正しいと思いますが、何故オフセットが必要なのでしょうか?


KONNOYA  2019-04-01 21:37:18  No: 49726

2)
> 矢印の配置を上下にしたいのですが、配置は変更できない様です。 

他の方法があるかも知れませんが、スタイルでなんとかする方法です。

(01) TSpinBox を TForm上 に 配置。
(02) TSpinBox の DecimalDigitsプロパティ を「1」に 変更。
(03) TSpinBox の ValueTypeプロパティ を「Float」に 変更。
(04) TSpinBox の Incrementプロパティ を「0.1」に 変更。
(05) TSpinBox の Heightプロパティを「64くらい」に 変更。
(06) TSpinBox の Rectangleプロパティ を「90」に 変更。
(07) TSpinBoxを右クリックしてポップアップを表示させ「カスタムスタイルの編集」を選択。
(08)「構造」ツリーから「spinbox1style1」をダブルクリックしてツリーを表示させる。
(09)「spinbox1style1」の中の「content」のRectangleプロパティを「-90」に変更。

この作業の行っている事は、TSpinBoxコンポーネント自体を90度回転させた後に、
TSpinBoxのカスタムスタイルを作成して適用させ、そのカスタムスタイルの中のテキストを90度戻す
という事をしているだけです。
これで上下のTSpinBoxの出来上がりです。

> 問題といいますか、疑問は、Incrementを0.1に設定しDecimalDigitsを1、ValueTypeをFloatとした場合、整数の表示が”1.0”や”2.0”ではなく”1”,”2”となっていて少数部の”.0”が表示されません。

Delphi XE8 & 10.1 Berlin で検証した結果、yTake様と同様の動きでした。
  DecimalDigitsプロパティ を「1」、
  ValueTypeプロパティ を「Float」で、
  「0」は「0」と表示される。

Delphi 10.2 Tokyoで検証した結果では、
  DecimalDigitsプロパティ を「1」
  ValueTypeプロパティ を「Float」で、
  「0」は「0.0」と表示される。

これについては、仕様なのかは分かりません。


yTake  2019-04-02 00:53:18  No: 49727

KONNOYA様
ありがとうございます。
てっきり、プロパティで矢印向きを規定するものと思っていました。
目からうろこです。
カスタムスタイルの編集を試してみました。確かに配置が90度回転し矢印は上下になりました。テキストも逆向きに回転しました。
ただ、やってみて分かったのですが、当然ながら縦に長くなってしまい配置場所に困りました。TUpDownの場合はテキストの高さ分程度で上下に並べられました。
そこで、RotationAngleは0のままで、"buttonstyleobject"で矢印の画像を上矢印下矢印(若しくは、'+','−')に変更出来ないでしょうか?

'+'や'−'のキャラクターでは置き換えられないですよね。
「構造」ツリーから"buttonstyleobject"のプロパティでは画像は見当たらない様です。また、置き換えられる場合、その画像のサイズや画像形式も決まっている様に思います。

ヘルプを見てみましたが、置き換えられる様には思えません。
試みが誤りでしょうか?


yTake  2019-04-02 00:56:42  No: 49728

すみません。

コメントが抜けていました。

小数点表示の件、調査をありがとうございました。
バージョンによって挙動が違う様ですね。

たぶん、"10.2 Tokyo"以降が正しいのでしょう。
こちらは、致し方ありません。


KONNOYA  2019-04-02 02:18:04  No: 49729

> '+'や'−'のキャラクターでは置き換えられないですよね。 

これもスタイルの変更可能です。
TSpinBoxを右クリックしてポップアップを表示させ「カスタムスタイルの編集」を選択して
「plusbutton」または「minusbutton」を見てみると、StyleLookupプロパティにリンク先が入っています。

StyleContainerにその「SpinBox1Style1spinleftbutton1」または「SpinBox1Style1spinrightbutton1」があります。

「SpinBox1Style1spinleftbutton1」の NormalLinkプロパティの「…」をクリックすると、ビットマップリンクエディッタという
物が起動しますので、サイコロの五みたいな選択領域を希望する画像に移動させ割り当てます。例えば「+」とか。

それをリンク(L) にある「HotLink」「FocusedLink」「NormalLink」「PressedLink」に行います。

するとコンポーネントの画像が変わると思います。


KONNOYA  2019-04-02 02:21:17  No: 49730

> 1)
> PaintBoxの原点或いは任意の領域に描画するにはどの様にするのでしょう? 

TPaintBoxのOnPaintメソッドで描画処理を行うというのはどうでしょう?


yTake  2019-04-02 05:11:22  No: 49731

>「SpinBox1Style1spinleftbutton1」の NormalLinkプロパティの「…」をクリックすると、ビットマップリンクエディッタという 
>物が起動しますので、サイコロの五みたいな選択領域を希望する画像に移動させ割り当てます。例えば「+」とか。 

当方、XE6なのですが、「SpinBox1Style1spinminusbutton1」の NormalLinkプロパティの「…」をクリックすると、”NormalLinkの編集”が開きます。
当方、オブジェクトの名前中の"left"が"minux"、"right"が"plus"となっていて、また、”NormalLinkの編集”で開くDialogは所謂vclでの”Statusbar”での”Panels”編集の様で、サイコロの五みたいではありません。

アドバイスの趣旨は分かるのですが、実際の操作が分かりません。

もう少し、試行錯誤してみます。


yTake  2019-04-02 05:31:05  No: 49732

OnPaintのイベント中で描画すると言う事でしょうか?

OnPaintはそのPaintBoxに何かが描画された際にその描画の後に(前に)呼び出されるイベントと思います。

すると、代わりにOnPaintで描画する事は出来ない様に思います。

そこで試しにOnPaintで直線を引いてみました。
    pnt1  :=  TPointF.Create( 0, 0 );
    pnt2  :=  TPointF.Create( 200, 200 );
    PaintBox1.Canvas.BeginScene();
    PaintBox1.Canvas.Stroke.Color  :=  $FF0000FF;     //  clRed
    PaintBox1.Canvas.StrokeThickness  :=  3 ;
    PaintBox1.Canvas.DrawLine( pnt1, pnt2, 1.0 );
    PaintBox1.Canvas.EndScene();

しかしながら、何も描画されません。

こちらも試行錯誤が必要な様です。


yTake  2019-04-02 05:32:47  No: 49733

すみません。

PaintBoxのOnPaintのテスト結果は、直線は描画されませんの意です。


yTake  2019-04-02 06:05:45  No: 49734

TPointBoxの件です。

単純なテストプログラムで試し直してみました。

結果、OnPaintイベント内での描画は配置されているPaintBoxの位置に基づいて(0,0)から描画されました。

ボタンクリックイベント内ではFormの(0,0)から描画されます。

ボタンイベント内:
    pnt1  :=  TPointF.Create( 0, 0 );
    pnt2  :=  TPointF.Create( 200, 200 );
    PaintBox1.Canvas.BeginScene();
    PaintBox1.Canvas.Stroke.Color  :=  $FFFF0000;
    PaintBox1.Canvas.StrokeThickness  :=  3 ;
    PaintBox1.Canvas.DrawLine( pnt1, pnt2, 1.0 );
    PaintBox1.Canvas.EndScene();

ボタンイベント内:
    pnt1  :=  TPointF.Create( 0, 0 );
    pnt2  :=  TPointF.Create( 200, 200 );
    PaintBox1.Canvas.BeginScene();
    PaintBox1.Canvas.Stroke.Color  :=  $FF0000FF;
    PaintBox1.Canvas.StrokeThickness  :=  3 ;
    PaintBox1.Canvas.DrawLine( pnt1, pnt2, 1.0 );
    PaintBox1.Canvas.EndScene();

両者で色のみ変更しています。

何故か線が引かれる場所が異なります。

これはTImageでも同様です。


yTake  2019-04-02 17:11:03  No: 49735

念の為、補足させて頂きます。

先ず初めに訂正から。コードの記述で2番目の”ボタンイベント”は”OnPaintイベント”の事です。

補足:
TPaintBoxの描画される場所の問題で、PaintBoxはForm上の(50,50)に原点(LeftTop)が来ています。

つまり、描画される直線はForm座標系の、ボタンクリックイベントの方は(0,0)から(200,200)まで、OnPaintイベントの方は(50,50)から(250,250)です。


yTake  2019-04-02 20:26:49  No: 49736

SpinBoxの方ですが、コンポーネント上の矢印画像を差し換える事は出来ませんでしたが、既存の矢印画像を回転させる事で上下矢印に変更する事ができました。
KONNOYA様ありがとうございました。

TSpinBox上で右クリックから”カスタムスタイルの編集”を選択、「構造」ツリーから”spinboxstyle”の子ツリーで”minusbutton”を選択します。
そのプロパティで”RotationAngle”を-90に設定し、適用すると、左矢印が下矢印になりました。

SpinBoxの件は一応これで進めて行きたいと思います。


KONNOYA  2019-04-02 22:16:06  No: 49737

検索してみたら過去ログに同じ質問をされていた方が居た様です。
Mae様のやり方で出来る様です。

https://www.petitmonte.com/bbs/answers?question_id=8907

TPaintBoxなら出来る限り、OnPaintメソッドで書いた方が良いと思うのですが、


KONNOYA  2019-04-02 22:18:11  No: 49738

失礼リンクを間違えました。

https://www.petitmonte.com/bbs/answers?question_id=7455


yTake  2019-04-03 04:21:05  No: 49739

KONNOYA様ありがとうございます。
過去ログにあったのですね。
見つけ切れなかった様です。失礼致しました。
”SetMatrix”を使うのですね。
うまく行きました。
しかし、同じコンポーネントが呼び出されるイベントによって座標系が異なるとは難解です。

全て”OnPaint”で描画した方が良さそうですが、呼び出し元イベントの切り分けが必要ですね。
呼び出し元のイベントを知る手立てはあるのでしょうか?

単純には、自分でフラッグを用意して、イベント時にフラッグを立てる事が考えられます。

こんな感じで試してみます。


yTake  2019-04-03 17:12:28  No: 49740

KONNOYA様、はじめ皆様

おかげ様で2題共にクリアできました。

”OnPaint"でのイベント元の判別もフラッグを用いる事で切り分けできました。

大変ありがとうございました。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加