PureBasic Forum
https://www.purebasic.fr/english/

Detect SplitterGadget drag
https://www.purebasic.fr/english/viewtopic.php?f=13&t=73770
Page 1 of 1

Author:  wombats [ Wed Oct 09, 2019 2:33 pm ]
Post subject:  Detect SplitterGadget drag

Hi,

The SplitterGadget functions very slowly for me because I have a number of gadgets inside the ContainerGadgets that get resized. This is my problem.

I thought maybe unbinding the #PB_EventType_Resize event from the #RightTopContainer and #RightBottomContainer when the #MainSplitter is moved, but I would need to be able to detect when the user starts and finishes moving the SplitterGadget's handle. Is there a way I can do that?

It might also be helpful to be able to detect when the user begins and finishes resizing the window, but I don't know if there is a way to do that.

Author:  kenmo [ Wed Oct 09, 2019 3:26 pm ]
Post subject:  Re: Detect SplitterGadget drag

I'm on Windows right now so I can't see your problem in action.

But I think I understand: you resize one splitter, it fires events for other splitters, your binded procedures run, and they resize the contents unnecessarily..?

A workaround is to track the real size of your container and only resize the contents if it has actually changed.
I suggest you store a width/height variable with the problematic containers, or you can use a general-purpose but less-efficient procedure like:

Code:
Procedure.i GadgetSizeChanged(Gadget.i)
  Static NewMap Size.s()
  If (FindMapElement(Size(), Hex(Gadget)))
    If ((Hex(GadgetWidth(Gadget)) = StringField(Size(), 1, ",")) And
        (Hex(GadgetHeight(Gadget)) = StringField(Size(), 2, ",")))
      ProcedureReturn (#False)
    EndIf
  EndIf
  Size(Hex(Gadget)) = Hex(GadgetWidth(Gadget)) + "," + Hex(GadgetHeight(Gadget))
  ProcedureReturn (#True)
EndProcedure

Author:  wombats [ Wed Oct 09, 2019 4:35 pm ]
Post subject:  Re: Detect SplitterGadget drag

Hi,

That doesn't seem to help, unfortunately, as the ContainerGadgets still seem to get resized when they shouldn't. That doesn't happen on Windows. However, on both macOS and Windows, all ContainerGadgets fire their resize event when the window is resized...I'm not sure if that's the expected behaviour, especially for the RightTopContainer and RightBottomContainer as they don't actually change their size.

Here is a video: https://imgur.com/a/UfMD3FT. The SplitterGadget on the right 'jumps'. This is even more pronounced in my project that contains a lot of gadgets in those two containers. It's horribly slow and laggy.

Code:
EnableExplicit

Enumeration
  #RightSplitter
  #LeftSplitter
  #MiddleSplitter
  #MainSplitter
EndEnumeration

Procedure.i GadgetSizeChanged(Gadget.i)
  Static NewMap Size.s()
  If (FindMapElement(Size(), Hex(Gadget)))
    If ((Hex(GadgetWidth(Gadget)) = StringField(Size(), 1, ",")) And
        (Hex(GadgetHeight(Gadget)) = StringField(Size(), 2, ",")))
      ProcedureReturn (#False)
    EndIf
  EndIf
  Size(Hex(Gadget)) = Hex(GadgetWidth(Gadget)) + "," + Hex(GadgetHeight(Gadget))
  ProcedureReturn (#True)
EndProcedure

Procedure OnContainerResized()
  Protected gadget, child, itemCount
  gadget = EventGadget()
  child = GetGadgetData(EventGadget())
  If GadgetSizeChanged(gadget)
    ResizeGadget(child, #PB_Ignore, #PB_Ignore, GadgetWidth(gadget), GadgetHeight(gadget))
    SetGadgetText(child, Str(Random(100)))
  EndIf
EndProcedure

Procedure OnWindowSized()
  ResizeGadget(#MainSplitter, 0, 0, WindowWidth(0), WindowHeight(0))
EndProcedure

Procedure.i MakeContainer()
  Protected id, child
  id = ContainerGadget(#PB_Any, 0, 0, 0, 0, #PB_Container_Single)
  child = StringGadget(#PB_Any, 0, 0, 0, 0, "")
  SetGadgetData(id, child)
  CloseGadgetList()
  BindGadgetEvent(id, @OnContainerResized(), #PB_EventType_Resize)
  ProcedureReturn id
EndProcedure

Global RightTopContainer, RightBottomContainer, LeftTopContainer, LeftBottomContainer, MiddleContainer

OpenWindow(0, 0, 0, 640, 480, "", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)

BindEvent(#PB_Event_SizeWindow, @OnWindowSized(), 0)

LoadFont(0, "Verdana", 20)
SetGadgetFont(#PB_Default, FontID(0))

RightTopContainer = MakeContainer()
RightBottomContainer = MakeContainer()
LeftTopContainer = MakeContainer()
LeftBottomContainer = MakeContainer()
MiddleContainer = MakeContainer()

SplitterGadget(#RightSplitter, 0, 0, 100, 100, RightTopContainer, RightBottomContainer)
SplitterGadget(#LeftSplitter, 0, 0, 100, 100, LeftTopContainer, LeftBottomContainer)
SplitterGadget(#MiddleSplitter, 0, 0, 640, 480, MiddleContainer, #RightSplitter, #PB_Splitter_Vertical | #PB_Splitter_SecondFixed)
SplitterGadget(#MainSplitter, 0, 0, 640, 480, #LeftSplitter, #MiddleSplitter, #PB_Splitter_Vertical)

SetGadgetState(#MiddleSplitter, 100)
SetGadgetState(#LeftSplitter, 100)

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Author:  wombats [ Thu Oct 10, 2019 1:17 pm ]
Post subject:  Re: Detect SplitterGadget drag

I found a way to detect when the user moves the cursor over the splitter handle. I unbind the events and then rebind them when they move the cursor off the handle. Unfortunately, while this is a little better, there is still a lot of lag and undesirable visual effects. I don't know what to do about it. It is similar to the video I included above, but much more pronounced because I have several gadgets in the containers in the right-hand splitter.

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/