Locking a TPairSplitter lazarus / 31-LCL ---------------------------------------------------------------------- MarkMLl · 2019-12-29 14:49 Uisng Lazarus trunk and GTK2. Is it possible to lock a splitter such that it cannot be moved (except by a maven who knows the unlock sequence)? Forcing the position back to the original value in the resize handler appears not to work, and simply disabling the splitter has the effect of rendering the content inaccessible- including the bits needed to unlock it :-) MarkMLl ---------------------------------------------------------------------- jamie · 2019-12-29 17:51 create a localized Class override and override the WM_MOUSE Handler messages.. For example Type TPairSplitter =  Class(TheUNitTheSplitterIsIn.TPairSplitter);  Do all of the overrides here. and you can monitor user actions before allowing it to continue on. End; ---------------------------------------------------------------------- MarkMLl · 2019-12-29 18:03 Quote from: jamie on December 29, 2019, 06:51:33 pmcreate a localized Class override and override the WM_MOUSE Handler messages.. For example Type TPairSplitter =  Class(TheUNitTheSplitterIsIn.TPairSplitter);  Do all of the overrides here. and you can monitor user actions before allowing it to continue on. End; Where would that have to be defined in order to be effective on the program's main form? Above the form definition in the corresponding unit? MarkMLl ---------------------------------------------------------------------- howardpc · 2019-12-29 18:39 You could do this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.Splitter1CanOffset(Sender: TObject; var NewOffset: Integer; var Accept: Boolean);begin  Accept := False;end; ---------------------------------------------------------------------- lucamar · 2019-12-29 18:42 Quote from: MarkMLl on December 29, 2019, 07:03:56 pmWhere would that have to be defined in order to be effective on the program's main form? Above the form definition in the corresponding unit? That's the "standard" position for interposed classes but you can also have it in its own unit and add that unit to the interface "uses" in your form's unit after [t]PairSplitter[/tt], so that it really "interposes". It really depends (IMHO) on how much code the interposed class has got. ---------------------------------------------------------------------- MarkMLl · 2019-12-29 18:50 Quote from: howardpc on December 29, 2019, 07:39:37 pmYou could do this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.Splitter1CanOffset(Sender: TObject; var NewOffset: Integer; var Accept: Boolean);begin  Accept := False;end; How does that hook in? Is it relevant to a TSplitterPair (which is what I'm using) or just a TSplitter? MarkMLl ---------------------------------------------------------------------- MarkMLl · 2019-12-29 18:52 Quote from: lucamar on December 29, 2019, 07:42:28 pmQuote from: MarkMLl on December 29, 2019, 07:03:56 pmWhere would that have to be defined in order to be effective on the program's main form? Above the form definition in the corresponding unit? That's the "standard" position for interposed classes but you can also have it in its own unit and add that unit to the interface "uses" in your form's unit after [t]PairSplitter[/tt], so that it really "interposes". It really depends (IMHO) on how much code the interposed class has got. Thanks for that. I see that the control is in its own PairSplitter unit, so presumably I could simply replace that in the uses clause. MarkMLl ---------------------------------------------------------------------- lucamar · 2019-12-29 19:35 Quote from: MarkMLl on December 29, 2019, 07:52:16 pmThanks for that. I see that the control is in its own PairSplitter unit, so presumably I could simply replace that in the uses clause. Don't do it unless that unit defines only the TPairSplitter class. If it defines some other "special" types or constants or whatever you'll (probably) still need it. ---------------------------------------------------------------------- MarkMLl · 2019-12-29 19:52 Quote from: lucamar on December 29, 2019, 08:35:15 pmQuote from: MarkMLl on December 29, 2019, 07:52:16 pmThanks for that. I see that the control is in its own PairSplitter unit, so presumably I could simply replace that in the uses clause. Don't do it unless that unit defines only the TPairSplitter class. If it defines some other "special" types or constants or whatever you'll (probably) still need it. OK, thanks for that. So as long as I get my interposed (is that the correct palare? :-) unit in front of the original I should be OK. MarkMLl ---------------------------------------------------------------------- wp · 2019-12-29 19:58 The PairSplitterSides have a property Constraints like most other LCL controls. When you set the Constraints.MaxWidth and .MinWidth equal to the Widths of the Sides then the splitter cannot be moved any more. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure LockPairSplitter(APairSplitter: TPairSplitter; Locked: Boolean);var  w: Integer;begin  with APairSplitter.Sides[0] do  begin    if Locked then w := Width else w := 0;    Constraints.MinWidth := w;    Constraints.MaxWidth := w;  end;  with APairSplitter.Sides[1] do  begin    if Locked then w := Width else w := 0;    Constraints.MinWidth := w;    Constraints.MaxWidth := w;  end;end; And this could be called this way to toggle between locked and unlocked states: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.Button1Click(Sender: TObject);begin  LockPairSplitter(PairSplitter1, PairSplitterSide1.Constraints.MinWidth = 0);end; ---------------------------------------------------------------------- howardpc · 2019-12-29 20:43 Quote from: MarkMLl on December 29, 2019, 07:50:01 pmQuote from: howardpc on December 29, 2019, 07:39:37 pmYou could do this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.Splitter1CanOffset(Sender: TObject; var NewOffset: Integer; var Accept: Boolean);begin  Accept := False;end; How does that hook in? Is it relevant to a TSplitterPair (which is what I'm using) or just a TSplitter? MarkMLl No, it applies only to TSplitter. TSplitterPair, although the names look similar, is a completely different beast. ---------------------------------------------------------------------- MarkMLl · 2019-12-29 21:15 Quote from: wp on December 29, 2019, 08:58:17 pmThe PairSplitterSides have a property Constraints like most other LCL controls. When you set the Constraints.MaxWidth and .MinWidth equal to the Widths of the Sides then the splitter cannot be moved any more. But lo what light through yonder window breaks... thanks, I think I've got that and will check in the morning. I'd seen those in the TPairSplitter itself but hadn't investigated the two sides. I've got a form with two splitters, and one quadrant is full of a grid of panels which will change colour depending on what's happening elsewhere in the system. I don't want a semi-authorised user (or me on a particularly bleary morning) messing the layout up, or resizing the overall form beyond what I can convenientlyy check using VNC if I have to. MarkMLl Update: that works nicely, many thanks.