TScaledLayout anchor point - delphi

In a form I have a Layout aligned as alContent and inside I have a new button aligned as alRight. The problem is when I reduce the scale, the direction is always from right to left. Is there any way to when I decrease the scale of the Layout the button continue right-aligned in relation to the Form changing the direction of left to right?

I believe that is not a definitive solution but so far I haven't found another alternative to reposition the TScaledLayout proportionally when I change the scale.
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
with ScaledLayout1
do Position.X := OriginalWidth - (OriginalWidth / (1 / TrackBar1.Value));
end;

Related

Get Top and Left position of an FMX Control, based on screen bounds

I'm trying to place an outside program right into an FMX TPanel using SetWindowPOS from WinAPI.
In order to do that I need the exact Top and Left values of the TPanel to pass it to SetWindowPOS. However, this value is always according to its parent, so i.e. if the Tpanel's parent is a TLayout and no margins are set, then the value of Top will be 0.
I need the Top value according to the screen.
I tried searching for that quite a bit but I can't figure it out.
Any help with that would be greatly appreciated.
After just posting the question I got the simple solution
var
pnt: TPointF;
begin
pnt := myRctngl.LocalRect.TopLeft;
pnt := myRctngl.LocalToAbsolute(pnt);
pnt := ClientToScreen(pnt);
End;
pnt should now have the value of the Point according to the screen.
You can now use pnt.x and pnt.y to get the top/left values.

How set Panel position always above of hole region?

I have a code that creates a hole in Form using the mouse.
var
FormRegion, HoleRegion: HRGN;
begin
FormRegion := CreateRectRgn(0, 0, Form1.Width, Form1.Height);
HoleRegion := CreateRectRgn(X1, Y1, X2, Y2);
CombineRgn(FormRegion, FormRegion, HoleRegion, RGN_DIFF);
SetWindowRgn(Form1.Handle, FormRegion, True);
end;
Now i wish put one Panel (that already have a fixed height) always above of hole region (and with same width of hole) to simulate a title bar, something like this:
How can be made?
You did not read carefully my request for additional information, so I leave it to you to adjust however you like.
Anyway, I believe your actual question is concerning the alignment of the panel with the transparent region. You probably do not consider that the region calculations with the form window includes the borders, so you have an offset to the right and downwards.
Since the regions are calculated including the borders of the form, you will need a variable ClientOffset: TPoint to hold the values of width of the left border and the height of the top border (incl. title bar of the form).
var
ClientOffset: TPoint;
To calculate the ClientOffset you can use the predefined ClientOrigin and the forms Left and Top properties.
ClientOffset.X := Form36.ClientOrigin.X - Form36.Left; // Left border width
ClientOffset.Y := Form36.ClientOrigin.Y - Form36.Top; // Top border height (incl. title bar)
Then, either subtract ClientOffset from the panels Left and Top properties, or add ClientOffset to the HoleRegions coordinates. The latter being more correct if you use the mouse (and presumably the forms client coordinates) to define the "hole" region

FlowPanel how to Wrap every given number of components?

is there any way, not that complicated to wrap the components of a FlowPanel for instance every 3 components?
as it works with the property autowrap but by a given amount of controls.
thanks in advance.
You left the actual image sizes open, so here its the general idea with some example sizes that you will have to adopt to your liking. I made some initial tests with buttons (normal width = 75), so I sized the TFlowPanel to 235 px wide.
The idea is to have a TFlowPanel with a fixed width (Constraints.MaxWidth = 235; Constraints.MinWidth = 235;) but AutoSize=True so it can grow downward. If you add e.g. 75px wide components, 3 of them fit perfectly on one row. If wider, only 2 or even only 1 fit on a row. So far as you wish. But if the width is only 56px (mean value) or less the number of compnents will be four or more.
I suggest a solution to place such a smaller component on a panel of its own, with a width of 75px, and that panel on the TFlowPanel. Thus no more than three components will fit on one row.
This is the code with which a number of buttons were placed on a TFlowPanel.
procedure TForm3.Button1Click(Sender: TObject);
var
btn: TButton;
pan: TPanel;
begin
inc(count);
btn := TButton.Create(self);
btn.Width := random(60)+35;
if btn.Width < 75 then
begin
pan := TPanel.Create(self);
pan.Width := 75;
pan.Height := 30;
pan.BevelOuter := bvNone;
btn.Parent := pan;
pan.Parent := FlowPanel1;
end
else
begin
btn.Parent := FlowPanel1;
end;
btn.Caption := IntToStr(count);
end;
And the end result
Alternative solution
Another solution (since you mentioned TImages) is to always create the TImages with a width of at least 75px. The picture (if smaller than that) can be centered in the TImage, if you like. This is based on the fact that the image doesn't affect the size of the TImage control (unless you want it to).
Also, if you don't really absolutely need to show the images in their full actual size, you can set the Proportional property true. From the docs:
When Proportional is true, images that are too large to fit in the image control are scaled down (while maintaining the same aspect ratio) until they fit in the image control.

TeeChart VCL chart scale issue

I have an issue using Delphi 2007 & TChart 7.0.10.0 or 7.0.11.0 or the latest evaluation 9.0.5.0 on the TChart scaling.
The problem arises as soon I enlarge the window after a certain width and KEEP the Form height!
This is the drawing using a smaller form size.
now if I enlarge to 1200 weight I get this ugly scaling:
If I export in the designer without the aspect ratio set and with 1200 weight you will se this:
How to get ride of this?
Hp
I see you've set top and bottom margins to Chart1 in your project (8 and 20 percent respectively). I guess this has the intention of giving more space (in height) for Chart2 when you resize the form making it bigger.
Chart1's Top and Height properties should be set according to fill this blank space in the Form's OnResize event.
Try this:
procedure TGSSkillgroupStatisticForm.FormResize(Sender: TObject);
begin
Chart1.Draw;
Chart2.Top:=Chart1.ChartRect.Bottom + 25;
Chart2.Height:=Chart1.Height-Chart1.ChartRect.Bottom-40;
end;
Steema Support Central
Keep in mind that I only scale in the x-axis. Your 3-D bar / construct will after a certain width, overlap the scaling numbers! Your given answer do not fix this issue at all. To see the real problem in a better way, I added on the form creation:
Chart2.BottomAxis.Maximum := 20;
Series2.AddBar(12, 'Hallo', clred);
Here the result:

How to find the real size ("logical area") of a TScrollBox

I need to find the entire size (also called "logical area") of a TScrollBox - as opposite to visible area that you get via Width and Height property (or ClientWidth ClientHeight).
I want to create some controls inside that TScrollBox. One of them (called TViewer) needs to be as high as the TScrollBox itself. The thing is that during creation, the TScrollBox is scrolled down to show last created control. So, using Top=1 will not work because my control will have top=1 which is not the top of the logical area.
Delphi 7
Drop a component, like a TLabel, on the TScrollBox.
Set the component's Left and Top properties to 0.
Set the component's Visible property to False.
Now you always have the origin. The "logical height" is now:
myScrollBox.Height + (myOriginControl.Top * -1);
Maybe ScrollBox.HorzScrollBar.Range and ScrollBox.VertScrollBar.Range + the corresponding .Positions are what you need.
Look at Scrollbars:
ScrollBox1.VertScrollBar.Range
ScrollBox1.HorzScrollBar.Range
It can be less than height and width if the scrollbox logical area is not bigger than phisical area (scrollbars not visible in that case)
Or use this to get the max of both:
var
AHeight, AWidth: Integer;
begin
AHeight := Max(ScrollBox1.VertScrollBar.Range, ScrollBox1.Height);
AWidth := Max(ScrollBox1.HorzScrollBar.Range, ScrollBox1.Width);
ShowMessageFmt('%d,%d', [AHeight, AWidth]);
end;
Edit
From #Altar comments, I can add the logical height and/or width is not the problem. If you want to add any control which occupies all the height of the scrollbar, use the AHeight from the above calculation, but set the Top to the negative of VertScrollBar.Position, something like this:
procedure TForm2.Button3Click(Sender: TObject);
var
AHeight, AWidth: Integer;
Btn: TButton;
begin
AHeight := Max(ScrollBox1.VertScrollBar.Range, Height);
AWidth := Max(ScrollBox1.HorzScrollBar.Range, Width);
Btn := TButton.Create(Self);
Btn.Parent := ScrollBox1;
Btn.Left := 15;
Btn.Top := -ScrollBox1.VertScrollBar.Position;
Btn.Height := AHeight;
end;
Im not sure i understand exactly what you want to do, but to get the complete area defined as "scrollable" you would have to write ScrollBox.HorScrollBar.Range + ScrollBox.Clientwidth (and the same thing for the vertical section). The scrollbox always deducts the visible "page" size from the total. So if you define a height of 1000 pixels, with 100 pixels showing - it will have a scrolling range of 900. You have to add the clientheight to get the rest.
Also, to get the correct "top" position you will have to read Canvas.Cliprect.Top, since a scrolling window does not change the top position of sub-controls. Windows handles this for you and only tells you what to re-draw once the scrollbars are initialized.
Since you want to create a control that is just as high as the complete scrollable area, i presume you are creating an editor of sorts?
If so you would probably get better results taking a look at SynEdit and extract the base-class that adds scrollbars to a normal TCustomControl (it's quite easy). That way you can control both the painting and the layout of your controls.
Here is one I wrote for Lazarus and FreePascal a while back. If you add messages to the uses clause and prefix the message handlers with WM rather than TLM it will compile under Delphi.
(code to long, had to use external link): http://delphimax.wordpress.com/2010/09/20/platform-independent-image-component-for-lazarus/
I have tried to do that, and believe me, I was not able to.
If you have the instances of the controls that are inside TScrollBox, you can use them to calculate (not precisely) the area.
Here is a complicated (but complete) solution:
I create my first child control during TScrollBox.Create (when TScrollBox does not have yet a scrollbar)
Set Child.Top:= 1
Create the rest of the child controls (this may force the TScrollBox to show the scrollbar)
Scroll the TScrollBox up
Use one of the above solutions to calculate the height of the TScrollBox

Resources