How to create splitter containing components?
Asked Answered
M

4

11

I'd like to put some buttons between two resizable panels or directly on the splitter if possible. How do I achieve they will move along with the splitter; how do I anchor them ?

screenshot

Edit:
Maybe the most important thing I forgot to mention. That splitter has to be as wide as on the screenshot, and the buttons should lay on it; so those buttons are actually "floating over splitter" now.

Thanks a lot

Michelson answered 24/5, 2011 at 10:25 Comment(5)
Since TSplitter is not a windowed control, you cannot place controls on it. I would abandon the TSplitter altogether, and use a TPanel and write some logic that makes it behave like a splitter. This is probably rather easy, but since I have no Deplhi IDE/RTL/compiler available right now, I cannot make an attempt (at least not now).Keratin
@Andreas This isn't how you do it. You need to use both a splitter and a panel. That's how splitters work.Torsk
@Andreas On the other hand, you appear to have understood the question and I haven't. I've read and re-read it but I can't work out how you did it, but you appear to have infered the intended meaning of the Q!Torsk
you can set the width of this splitter and set beveled:= true this way it's not too small to hit and will stick out visually.Hepatic
@Hepatic - that's why I put there a component name; and IMHO the 3D splitter between 3D panels might be less visible than it isMichelson
D
6

Yo can't do it automatically.
Manually you can change the Left property of Buttons in OnMoved event of the splitter.
There's not a good solution (visualization on drag moment it's not good), but it can do the result that you need. You can solve this, try ResizeStyle=rsUpdate; With this when you drag the splitter the buttons move too.

procedure TForm1.Splitter1Moved(Sender: TObject);
begin
  SpeedButton1.Left := Splitter1.Left + 40;
  SpeedButton2.Left := Splitter1.Left + 40;
  SpeedButton3.Left := Splitter1.Left + 40;
  SpeedButton4.Left := Splitter1.Left + 40;
end;

Here you can view the result.

Regards

Denunciatory answered 24/5, 2011 at 10:59 Comment(1)
That's what I was thinking about rather than an attempt to write my own control. It's a little bit dirty solution but it's working; I've tried the same before I ask here. So +1 (tomorrow) for reading my mind :)Michelson
T
6

Here's a screenshot from my app:

This form has a single TSplitter located to the right of the tree view in the left-hand pane. To the right of the splitter is a TPanel which contains the button.

Here it is at design time and you can see the splitter drawn with a dashed line:

The trick is that the splitter doesn't contain controls—for that you use a panel.

So, using your naming you need to replace Splitter1 with a panel to contain the buttons and add a splitter between Panel1 and the new panel. The left and middle panels and the splitter are aligned alLeft and the right handle panel is aligned alClient. Set splitter1.autosnap:= false

Torsk answered 24/5, 2011 at 10:43 Comment(4)
The problem is that I want to let users drag the whole pane between panels. I know it's out of common behaviour but that's what the rest of the project already is. Likewise I don't like when the splitter is narrow too much so that you need to focus to drag it for a while. I forgot to mention this in my question; so I'll add it there. +1 when I got some points tomorrow.Michelson
-1 For now, tested this but the splitter doesn't stay put in-between two left aligned panels.Hepatic
@Hepatic Thanks for the downvote, but it's you that has made the mistake I'm afraid.Torsk
fixed it autosnap needs to be changed from its default(true) to false, than it will work as you describe.Hepatic
D
6

Yo can't do it automatically.
Manually you can change the Left property of Buttons in OnMoved event of the splitter.
There's not a good solution (visualization on drag moment it's not good), but it can do the result that you need. You can solve this, try ResizeStyle=rsUpdate; With this when you drag the splitter the buttons move too.

procedure TForm1.Splitter1Moved(Sender: TObject);
begin
  SpeedButton1.Left := Splitter1.Left + 40;
  SpeedButton2.Left := Splitter1.Left + 40;
  SpeedButton3.Left := Splitter1.Left + 40;
  SpeedButton4.Left := Splitter1.Left + 40;
end;

Here you can view the result.

Regards

Denunciatory answered 24/5, 2011 at 10:59 Comment(1)
That's what I was thinking about rather than an attempt to write my own control. It's a little bit dirty solution but it's working; I've tried the same before I ask here. So +1 (tomorrow) for reading my mind :)Michelson
H
1

You can nest panels inside one another.

+--------------+#+------------+
|+---------+ p |#|  panel3    |
|| panel1  | a |#|            | 
||         | n |#|            |
||         | e |#|            |
||         | l |#|            |
||         | 2 |#|            |

where # is the splitter.

Place the buttons on the right side of panel2.
Or even better put a extra panel4 on panel2, make that

panel4.align:= alRight;
panel1 align:= alClient;
panel2.Align:= alClient;
splitter1.align:= alright or alLeft //experiment here
panel3.Align:= alRight;

This should do the trick.

Hepatic answered 24/5, 2011 at 10:50 Comment(7)
Why do you need nesting here?Torsk
@David the alignment of the panels will let panel1 and panel3 resize with the splitter while keeping panel2 a fixed size. There are other ways of doing this, but I like to nest panels. And it works in all versions of Delphi, without requiring code.Hepatic
@Hepatic You don't need to nest panels to achieve what is desired without requiring code.Torsk
@David, I know you can use anchors but I prefer nesting.Hepatic
@Hepatic You don't need anchors. You need left and middle panels to have alLeft and the right panel to be alClient. Then the splitter sits between left and middle panels and it's all good.Torsk
@David, yes but if you want (the control inside) panel1 to expand you need to do some nesting (or anchors), otherwise the middle panel will expand (just tested it:) and that's not what you want, you want the leftmost panel to expand/shrink.Hepatic
Panel1, Splitter1, Panel2, Panel3 arrange left to right. Alignment alLeft for the 3 leftmost, alClient for the rightmost. Splitter changes width of Panel1 and Panel3. Width of Panel2 remains constant.Torsk
M
1

There is one important notice. Both panels between Splitter should have same parameter AlignWithMargins. (Both true or both false). Otherwise splitter doesn't work. I fought with this problem for few days

Mickeymicki answered 22/10, 2012 at 7:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.