ScrollArea - Can it be butchered?
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
ScrollArea - Can it be butchered?
Windows only:
I would like to be able to scroll a ScrollArea Gadget by dragging the mouse on it's client area and not have scrollbars.
Any ideas?
I would like to be able to scroll a ScrollArea Gadget by dragging the mouse on it's client area and not have scrollbars.
Any ideas?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: ScrollArea - Can it be butchered?
Something like this? (Still buggy though)
Code: Select all
OpenWindow(0, 0, 0, 405, 240, "ScrollAreaGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ScrollAreaGadget(0, 10, 10, 390,220, 575, 455, 30)
ButtonGadget (1, 10, 10, 230, 30,"Button 1")
ButtonGadget (2, 50, 250, 230, 30,"Button 2")
SetWindowLong_(GadgetID(0), #GWL_STYLE, GetWindowLong_(GadgetID(0), #GWL_STYLE)&~#WS_HSCROLL&~#WS_VSCROLL)
SetWindowPos_(GadgetID(0), 0,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE|#SWP_NOZORDER|#SWP_FRAMECHANGED)
Repeat
e = WaitWindowEvent(50)
select e
case 13116 : End
Case 513
While WindowEvent() <> 514
SetGadgetAttribute(0, #PB_ScrollArea_X, WindowMouseX(0))
SetGadgetAttribute(0, #PB_ScrollArea_Y, WindowMouseY(0))
Wend
EndSelect
ForEver
Re: ScrollArea - Can it be butchered?
Spy++ tells me that the ScrollAreaGadget gets the usual selection of WM_ messages.
A search for 'subclass scrollarea' found (amongst others):-
viewtopic.php?f=13&t=42202
viewtopic.php?f=13&t=39845
viewtopic.php?f=7&t=30143
A search for 'subclass scrollarea' found (amongst others):-
viewtopic.php?f=13&t=42202
viewtopic.php?f=13&t=39845
viewtopic.php?f=7&t=30143
Re: ScrollArea - Can it be butchered?
Hi IdeasVacuum
I did the next snippet long time back perhaps it could be of some use
I did the next snippet long time back perhaps it could be of some use
Code: Select all
Global imgw,imgh,Down,oldx,oldy,m.TRACKMOUSEEVENT
m\cbSize = SizeOf(m)
m\dwFlags = #TME_LEAVE
Procedure IsMouseOver(hWnd)
GetWindowRect_(hWnd,mr.RECT)
GetCursorPos_(mp.POINT)
Result = PtInRect_(mr,mp\y << 32 + mp\x)
ProcedureReturn Result
EndProcedure
Procedure WndProc(hwnd, uMsg, wParam, lParam)
result = #PB_ProcessPureBasicEvents
Select uMsg
Case #WM_MOUSEMOVE
GetCursorPos_(p.POINT)
ScreenToClient_(WindowID(0),p)
m\hwndTrack =WindowID(0)
TrackMouseEvent_(@m)
If IsGadget(1) And IsMouseOver(GadgetID(1)) And Down = 1
SetCursor_(LoadCursor_(0, #IDC_SIZEALL))
MoveWindow_(GadgetID(1),GadgetX(1)+p\x-oldx,GadgetY(1)+p\y-oldy,imgw,imgh,1)
;If (GadgetX(1)+GadgetWidth(1)) > (GadgetX(0)+GadgetWidth(0))
; SetGadgetAttribute(0, #PB_ScrollArea_X,GadgetX(1)+p\x-oldx)
;EndIf
If (GadgetX(1)+p\x-oldx+12) <= GadgetX(0)
;SetGadgetAttribute(0, #PB_ScrollArea_X,0)
MoveWindow_(GadgetID(1),0,GadgetY(1)+p\y-oldy,imgw,imgh,1)
ElseIf (GadgetY(1)+p\y-oldy+12) <= GadgetY(0)
;SetGadgetAttribute(0, #PB_ScrollArea_Y,0)
MoveWindow_(GadgetID(1),GadgetX(1)+p\x-oldx,0,imgw,imgh,1)
EndIf
EndIf
oldx = p\x
oldy = p\y
Case #WM_MOUSELEAVE
Down = 0
Case #WM_MOUSEWHEEL
Case #WM_MOVE
Case #WM_MOVING
Case #WM_SIZE
MoveWindow_(GadgetID(10),10,10,WindowWidth(0)-20,WindowHeight(0)-20,1)
Case #WM_LBUTTONUP
Down = 0
EndSelect
ProcedureReturn result
EndProcedure
LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/Geebee2.bmp")
;ResizeImage(0, 500,500,#PB_Image_Smooth)
imgw = ImageWidth(0)
imgh = ImageHeight(0)
If OpenWindow(0, 0, 0, 800,600, "ScrollAreaGadget", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget| #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
ContainerGadget(10,10,10,780,580,#PB_Container_Flat)
ScrollAreaGadget(0, -2000, -2000, 4000,4000, 4000,4000,50)
ShowScrollBar_(GadgetID(0), #SB_BOTH, #False)
ImageGadget(1, 2000, 2000, imgw,imgh, ImageID(0))
CloseGadgetList()
CloseGadgetList()
DisableGadget(10,1)
SetWindowCallback(@WndProc())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #WM_LBUTTONDOWN
Down = 1
If IsMouseOver(GadgetID(1))
DisableGadget(10,1)
GetCursorPos_(p.POINT)
ScreenToClient_(WindowID(0),p)
oldx = p\x
oldy = p\y
ElseIf IsMouseOver(GadgetID(0))
DisableGadget(10,0)
SetCursor_(LoadCursor_(0, #IDC_SIZEALL))
SendMessage_(GadgetID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
EndIf
EndSelect
ForEver
EndIf
Egypt my love
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: ScrollArea - Can it be butchered?
Thanks Guys - all good stuff.
Rashad's method is absolutely beautiful! I'd like it to be an official, optional, setup for the gadget in PB
Rashad's method is absolutely beautiful! I'd like it to be an official, optional, setup for the gadget in PB

IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: ScrollArea - Can it be butchered?
Hi IdeasVacuum
Thanks for the nice compliment
Now for the recent time
Very simple and direct

Thanks for the nice compliment
Now for the recent time
Very simple and direct
Code: Select all
#SC_DragMove = $F012
LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/Geebee2.bmp")
imgw = ImageWidth(0)
imgh = ImageHeight(0)
If OpenWindow(0, 0, 0, 800,600, "ScrollAreaGadget", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget| #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
ContainerGadget(10,10,10,780,480,#PB_Container_Flat)
ScrollAreaGadget(0, -2000, -2000, 4000,4000, 4000,4000,50)
ShowScrollBar_(GadgetID(0), #SB_BOTH, #False)
ImageGadget(1, 2000, 2000, imgw,imgh, ImageID(0))
CloseGadgetList()
CloseGadgetList()
DisableGadget(10,1)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Quit = 1
Case #WM_LBUTTONDOWN
GetCursorPos_(p.POINT)
ScreenToClient_ (GadgetID(10), @p)
If ChildWindowFromPoint_(GadgetID(10),p\y << 32 + p\x) = GadgetID(0)
SetCursor_(LoadCursor_(0, #IDC_SIZEALL))
SendMessage_(GadgetID(0), #WM_SYSCOMMAND , #SC_DragMove,0)
EndIf
EndSelect
Until Quit = 1
EndIf
Egypt my love
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: ScrollArea - Can it be butchered?
Hi Rashad
Less code is nice to see..... but your first example using a call back gives a much smoother scroll.
Less code is nice to see..... but your first example using a call back gives a much smoother scroll.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: ScrollArea - Can it be butchered?
.... something I don't get: Why is the Scroll Area Gadget itself oversized and not just the Scroll Area inner client area, as it would be if scrollbars were used?
Edit: I see now, the whole Scroll Area Gadget is being moved, not the inner area. So it need not be a Scroll Area Gadget, it could perhaps be a plain old Container..... but my ideal world scenario is to scroll the inner area of a Scroll Gadget by dragging the mouse on it instead of using the scroll bars.
Edit: I see now, the whole Scroll Area Gadget is being moved, not the inner area. So it need not be a Scroll Area Gadget, it could perhaps be a plain old Container..... but my ideal world scenario is to scroll the inner area of a Scroll Gadget by dragging the mouse on it instead of using the scroll bars.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: ScrollArea - Can it be butchered?
Hi IV
I was thinking of using the ScrollArea with a huge MAP moving it in all directions and maybe zoom in or out after that

I was thinking of using the ScrollArea with a huge MAP moving it in all directions and maybe zoom in or out after that
Egypt my love
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: ScrollArea - Can it be butchered?
Geebee1000.jpg
Code: Select all
#SC_DragMove = $F012
UseJPEGImageDecoder()
LoadImage(0, "C:\MY_TEMP\Geebee1000.jpg")
imgw = ImageWidth(0)
imgh = ImageHeight(0)
If OpenWindow(0, 0, 0, 800,600, "ScrollAreaGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ContainerGadget(10,0,0,800,600,#PB_Container_BorderLess)
ContainerGadget(0, -1000, -1000, 4000,4000,#PB_Container_BorderLess)
ImageGadget(1, 1000, 1000, imgw,imgh, ImageID(0))
CloseGadgetList()
CloseGadgetList()
DisableGadget(10,1)
SetWindowColor(0,RGB(0,0,200))
SetGadgetColor(0,#PB_Gadget_BackColor,RGB(0,200,0))
SetGadgetColor(10,#PB_Gadget_BackColor,RGB(0,200,0))
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Quit = 1
Case #WM_LBUTTONDOWN
GetCursorPos_(p.POINT)
ScreenToClient_ (GadgetID(10), @p)
If ChildWindowFromPoint_(GadgetID(10),p\y << 32 + p\x) = GadgetID(0)
SetCursor_(LoadCursor_(0, #IDC_SIZEALL))
SendMessage_(GadgetID(0), #WM_SYSCOMMAND , #SC_DragMove,0)
EndIf
EndSelect
Until Quit = 1
EndIf
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: ScrollArea - Can it be butchered?
Hi Rashad
That's essentially my use (but not a map), see my variation of your code. I have used a colour background on the containers so I could see what was happening. It works, but not so slick.
That's essentially my use (but not a map), see my variation of your code. I have used a colour background on the containers so I could see what was happening. It works, but not so slick.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: ScrollArea - Can it be butchered?
Well, works OK with an Image Gadget but I'm trying to use an OpenGL Gadget - fails miserably 

IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: ScrollArea - Can it be butchered?
Hi IV
With OpenGL gadget
With OpenGL gadget
Code: Select all
#SC_DragMove = $F012
;UseJPEGImageDecoder()
;LoadImage(0, "Geebee1000.jpg")
;imgw = ImageWidth(0)
;imgh = ImageHeight(0)
Global RollAxisX.f
Global RollAxisY.f
Global RollAxisZ.f
Global RotateSpeedX.f = 1.0
Global RotateSpeedY.f
Global RotateSpeedZ.f = 1.0
Global ZoomFactor.f = 1.0 ; Distance of the camera. Negative value = zoom back
Procedure DrawCube(Gadget)
SetGadgetAttribute(Gadget, #PB_OpenGL_SetContext, #True)
glPushMatrix_() ; Save the original Matrix coordinates
glMatrixMode_(#GL_MODELVIEW)
glTranslatef_(0, 0, ZoomFactor) ; move it forward a bit
glRotatef_ (RollAxisX, 1.0, 0, 0) ; rotate around X axis
glRotatef_ (RollAxisY, 0, 1.0, 0) ; rotate around Y axis
glRotatef_ (RollAxisZ, 0, 0, 1.0) ; rotate around Z axis
RollAxisX + RotateSpeedX
RollAxisY + RotateSpeedY
RollAxisZ + RotateSpeedZ
; clear framebuffer And depth-buffer
glClear_ (#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
; draw the faces of a cube
; draw colored faces
glDisable_(#GL_LIGHTING)
glBegin_ (#GL_QUADS)
; Build a face, composed of 4 vertex !
; glBegin() specify how the vertexes are considered. Here a group of
; 4 vertexes (GL_QUADS) form a rectangular surface.
; Now, the color stuff: It's r,v,b but with float values which
; can go from 0.0 To 1.0 (0 is .. zero And 1.0 is full intensity)
glNormal3f_ (0,0,1.0)
glColor3f_ (0,0,1.0)
glVertex3f_ (0.5,0.5,0.5)
glColor3f_ (0,1.0,1.0)
glVertex3f_ (-0.5,0.5,0.5)
glColor3f_ (1.0,1.0,1.0)
glVertex3f_ (-0.5,-0.5,0.5)
glColor3f_ (0,0,0)
glVertex3f_ (0.5,-0.5,0.5)
; The other face is the same than the previous one
; except the colour which is nice blue To white gradiant
glNormal3f_ (0,0,-1.0)
glColor3f_ (0,0,1.0)
glVertex3f_ (-0.5,-0.5,-0.5)
glColor3f_ (0,0,1.0)
glVertex3f_ (-0.5,0.5,-0.5)
glColor3f_ (1.0,1.0,1.0)
glVertex3f_ (0.5,0.5,-0.5)
glColor3f_ (1.0,1.0,1.0)
glVertex3f_ (0.5,-0.5,-0.5)
glEnd_()
; draw shaded faces
glEnable_(#GL_LIGHTING)
glEnable_(#GL_LIGHT0)
glBegin_ (#GL_QUADS)
glNormal3f_ ( 0, 1.0, 0)
glVertex3f_ ( 0.5, 0.5, 0.5)
glVertex3f_ ( 0.5, 0.5,-0.5)
glVertex3f_ (-0.5, 0.5,-0.5)
glVertex3f_ (-0.5, 0.5, 0.5)
glNormal3f_ (0,-1.0,0)
glVertex3f_ (-0.5,-0.5,-0.5)
glVertex3f_ (0.5,-0.5,-0.5)
glVertex3f_ (0.5,-0.5,0.5)
glVertex3f_ (-0.5,-0.5,0.5)
glNormal3f_ (1.0,0,0)
glVertex3f_ (0.5,0.5,0.5)
glVertex3f_ (0.5,-0.5,0.5)
glVertex3f_ (0.5,-0.5,-0.5)
glVertex3f_ (0.5,0.5,-0.5)
glNormal3f_ (-1.0, 0, 0)
glVertex3f_ (-0.5,-0.5,-0.5)
glVertex3f_ (-0.5,-0.5, 0.5)
glVertex3f_ (-0.5, 0.5, 0.5)
glVertex3f_ (-0.5, 0.5,-0.5)
glEnd_()
glPopMatrix_()
glFinish_()
SetGadgetAttribute(Gadget, #PB_OpenGL_FlipBuffers, #True)
EndProcedure
Procedure SetupGL()
glMatrixMode_(#GL_PROJECTION)
gluPerspective_(30.0, 200/200, 1.0, 10.0)
; position viewer
glMatrixMode_(#GL_MODELVIEW)
glTranslatef_(0, 0, -5.0)
glEnable_(#GL_DEPTH_TEST) ; Enabled, it slowdown a lot the rendering. It's to be sure than the
; rendered objects are inside the z-buffer.
glEnable_(#GL_CULL_FACE) ; This will enhance the rendering speed as all the back face will be
; ignored. This works only with CLOSED objects like a cube... Singles
; planes surfaces will be visibles only on one side.
glShadeModel_(#GL_SMOOTH)
EndProcedure
Procedure HandleError (Result, Text$)
If Result = 0
MessageRequester("Error", Text$, 0)
End
EndIf
EndProcedure
If OpenWindow(0, 0, 0, 800,600, "ScrollAreaGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ContainerGadget(10,0,0,800,600,#PB_Container_BorderLess)
ContainerGadget(20, -1000, -1000, 4000,4000,#PB_Container_BorderLess)
OpenGLGadget(0, 1000, 1000, 200, 200)
SetupGL()
OpenGLGadget(1, 1500, 1000, 300, 300)
SetupGL()
CloseGadgetList()
CloseGadgetList()
DisableGadget(10,1)
;DisableGadget(20,1)
;SetWindowColor(0,RGB(0,0,200))
;SetGadgetColor(0,#PB_Gadget_BackColor,RGB(0,200,0))
;SetGadgetColor(10,#PB_Gadget_BackColor,RGB(0,200,0))
AddWindowTimer(0, 1, 16)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Quit = 1
Case #PB_Event_Timer
If EventTimer() = 1
DrawCube(0)
DrawCube(1)
EndIf
Case #WM_LBUTTONDOWN
GetCursorPos_(p.POINT)
ScreenToClient_ (GadgetID(20), @p)
If ChildWindowFromPoint_(GadgetID(20),p\y << 32 + p\x) = GadgetID(0)
RemoveWindowTimer(0,1)
SetCursor_(LoadCursor_(0, #IDC_SIZEALL))
SendMessage_(GadgetID(0), #WM_SYSCOMMAND , #SC_DragMove,0)
AddWindowTimer(0, 1, 16)
ElseIf ChildWindowFromPoint_(GadgetID(20),p\y << 32 + p\x) = GadgetID(1)
RemoveWindowTimer(0,1)
SetCursor_(LoadCursor_(0, #IDC_SIZEALL))
SendMessage_(GadgetID(1), #WM_SYSCOMMAND , #SC_DragMove,0)
AddWindowTimer(0, 1, 16)
EndIf
EndSelect
Until Quit = 1
EndIf
Egypt my love
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: ScrollArea - Can it be butchered?
Ahhhh! I spend half a day convincing myself that scrollbars are alright - and then you throw temptation in my path again 

IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: ScrollArea - Can it be butchered?
Your example works really well Rashad and I have made it maximum Window Size with an oversize OGL gadget, no problem.
Tried incorporating it into my project but currently it does not work, possibly because I'm using glOrtho_() to hold the proportional representation of the model, I'm not sure at the moment.
I'm going to set it aside for now as I have other issues to solve, but many many thanks for your help and I'm sure I will get my implementation right in the end.
Tried incorporating it into my project but currently it does not work, possibly because I'm using glOrtho_() to hold the proportional representation of the model, I'm not sure at the moment.
I'm going to set it aside for now as I have other issues to solve, but many many thanks for your help and I'm sure I will get my implementation right in the end.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.