Did I just reinvent the wheel with my scroll bars?

Just starting out? Need help? Post your questions and find answers here.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Did I just reinvent the wheel with my scroll bars?

Post by Mistrel »

I wanted my scroll bar area gadget to look a certain way so I hacked this together. Before I started working on this maybe I should have asked if what I wanted could be done with a normal scrollarea gadget.

Can a scrollarea gadget be made to look and function like my hacked-up one?

http://www.purebasic.fr/english/viewtopic.php?t=28812
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Did I just reinvent the wheel with my scroll bars?

Post by srod »

Mistrel wrote:I wanted my scroll bar area gadget to look a certain way so I hacked this together. Before I started working on this maybe I should have asked if what I wanted could be done with a normal scrollarea gadget.

Can a scrollarea gadget be made to look and function like my hacked-up one?

http://www.purebasic.fr/english/viewtopic.php?t=28812
Hi,

some nice code, but it does seem like overkill in that your scroll bar area gadget is using quite a few gadgets - including a scroll area and scrollbar gadgets! There are a few problems as well in that you can, by resizing the window, make the scroll bar's temporarily detach themselves from the main gadget.

In short, whilst you've produced some good code, it seems to me that you can get exactly the same from a good old scroll area gadget. In fact, the scroll area is very very flexible if you dive down to the level of the api (much like you've done), particularly if you subclass the inner container of the ScrollArea.

I reckon you could indeed make a scroll area gadget look like your scroll bar area gadget, if it doesn't already!
I may look like a mule, but I'm not a complete ass.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

some nice code, but it does seem like overkill in that your scroll bar area gadget is using quite a few gadgets - including a scroll area and scrollbar gadgets! There are a few problems as well in that you can, by resizing the window, make the scroll bar's temporarily detach themselves from the main gadget.
Is this something my code is doing? I don't get that kind of a reaction when I resize the window.
In short, whilst you've produced some good code, it seems to me that you can get exactly the same from a good old scroll area gadget. In fact, the scroll area is very very flexible if you dive down to the level of the api (much like you've done), particularly if you subclass the inner container of the ScrollArea.
When I started working on this I believed that a scroll area was very inflexible. I'm still very new to working with the windows api and the hardest part it seems is finding information for the component I want to work on.

If you believe it can be done would you please point me in the right direction? Important elements are the ability to turn one or both scroll bars off, to disable one or both, and to keep the scrollbars visible when the gadget extends beyond the inner width/height.

You mentioned subclassing the inner container? What is that and why would it be useful?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Grab a hold of the bottom sizer and drag upwards to decrease the height of the window. As it nears a minimum keep an eye on the bottom left and right corners of the horizontal scroll bar.

Still it's only a minor deal really! :)

To display the scrollbars when the inner area is smaller than the client area of the scroll area, use something like : (vertical scrollbar)

Code: Select all

SetWindowLong_(GadgetID(#ScrA), #GWL_STYLE, GetWindowLong_(GadgetID(#ScrA),#GWL_STYLE)|#WS_VSCROLL)
SetWindowPos_(GadgetID(#ScrA), 0,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE|#SWP_NOZORDER|#SWP_DRAWFRAME)
You'll have to reissue this command periodically if you use SetGadgetAttribute() to resize the inner area etc.

By inner container; you must understand that a ScrollArea gadet is actually two controls; one (the visible one) which acts as a parent (and displays the scrollbars etc.) and the other (a child of the parent) acts as a container for all of the gadets you place in the ScrollArea.

Whenever you move one of the scrollbars, this inner container is simply moved around so giving the impression of 'scrolling'. It's a bit of a cheat, but it is very effective. A Windows header control (such as those attached to ListIcon gadgets) works in the same way.

I've very recently created several custom controls which are based upon ScrollArea gadgets. Amongst other things I subclass this container and handle all the #WM_PAINT and #WM_ERASEBKGND messages in order to fully customise the control etc. You can produce some very powerful controls this way.

There's no doubt that you could get the effect you desire with a ScrollArea. One thing is clear, such a control should not really use separate scrollbar gadgets - that's asking for trouble! :wink: Use a window/gadget with scrollbars added as a window style. Before I go any further I will just say that creating a custom control is a very technical business; one which is not easy to detail through a couple of forum posts! :wink: Still, you're definitely on the right tracks.
I may look like a mule, but I'm not a complete ass.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

How about something like this Mistrel. It's not perfect but maybe it's less code with the same results :?:

Code: Select all

UseJPEGImageDecoder()
If OpenWindow(0, 0, 0, 400, 400, "ScrollArea Test", #PB_Window_SizeGadget | #PB_Window_ScreenCentered | #PB_Window_SystemMenu) And CreateGadgetList(WindowID(0)) 
  ;CreateImage(0, 80, 80) 
  ScrollAreaGadget(0, 10, 10, 380, 380, 450, 450, 10);, #PB_ScrollArea_BorderLess) 
  ImageGadget(1, 10, 10, 80, 80, CatchImage(0, ?myImage))
  CloseGadgetList()
  
  ;... Disable XP Theme for the ScrollAreaGadget
  ;... The result should be flat scroll bars
  If OSVersion() >= #PB_OS_Windows_XP 
    If OpenLibrary(0, "uxtheme.dll") 
      If CallFunction(0, "SetWindowTheme", GadgetID(0), @null.w, @null.w) = 0
        Debug "Theme turned off for ScrollAreaGadget"
      EndIf
      CloseLibrary(0) 
    EndIf
  EndIf 
  Repeat 
    event = WaitWindowEvent()
    If event = #PB_Event_SizeWindow
      ResizeGadget(0, 10, 10, WindowWidth(0)-20, WindowHeight(0)-20)
      
      ;... The ScrollAreaGadget removes the #WS_HSCROLL / #WS_VSCROLL
      ;... as they become un-necessary. We will make sure they stay visible at all times
      ;... I tried using #SIF_DISABLENOSCROLL but it was a no-go for me
      style = GetWindowLong_(GadgetID(0), #GWL_STYLE)
      If Not style & #WS_HSCROLL
        SetWindowLong_(GadgetID(0), #GWL_STYLE, style | #WS_HSCROLL)
        EnableScrollBar_(GadgetID(0), #SB_HORZ, #ESB_DISABLE_BOTH)
        sbHorz = 0
      EndIf
      If GadgetWidth(0) <= GetGadgetAttribute(0, #PB_ScrollArea_InnerWidth) And sb = 0
        sbHorz = 1
        EnableScrollBar_(GadgetID(0), #SB_HORZ, #ESB_ENABLE_BOTH)
      EndIf
      If Not style & #WS_VSCROLL
        SetWindowLong_(GadgetID(0), #GWL_STYLE, style | #WS_VSCROLL)
        EnableScrollBar_(GadgetID(0), #SB_VERT, #ESB_DISABLE_BOTH)
        sbVert = 0
      EndIf
      If GadgetHeight(0) <= GetGadgetAttribute(0, #PB_ScrollArea_InnerHeight) And sbVert = 0
        sbVert = 1
        EnableScrollBar_(GadgetID(0), #SB_VERT, #ESB_ENABLE_BOTH)
      EndIf
    EndIf
  Until event = #PB_Event_CloseWindow 
EndIf
End
DataSection
myImage:
Data.b $FF,$D8,$FF,$E0,$00,$10,$4A,$46,$49,$46,$00,$01,$01,$01,$00,$48
Data.b $00,$48,$00,$00,$FF,$DB,$00,$43,$00,$72,$4F,$56,$64,$56,$47,$72
Data.b $64,$5D,$64,$81,$79,$72,$88,$AB,$FF,$BA,$AB,$9D,$9D,$AB,$FF,$FA
Data.b $FF,$CF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
Data.b $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
Data.b $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$C0,$00,$0B,$08,$00,$4D
Data.b $00,$46,$01,$01,$11,$00,$FF,$C4,$00,$18,$00,$00,$03,$01,$01,$00
Data.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$02,$03,$04
Data.b $FF,$C4,$00,$22,$10,$00,$02,$02,$02,$03,$00,$01,$05,$00,$00,$00
Data.b $00,$00,$00,$00,$00,$00,$01,$02,$11,$21,$31,$03,$12,$41,$04,$13
Data.b $22,$32,$51,$61,$FF,$DA,$00,$08,$01,$01,$00,$00,$3F,$00,$88,$FD
Data.b $AE,$D3,$2A,$52,$C6,$3D,$33,$6F,$16,$18,$A1,$00,$50,$50,$51,$52
Data.b $95,$2A,$44,$5E,$47,$B0,$AA,$0A,$C8,$68,$02,$E8,$2C,$92,$A1,$1E
Data.b $C5,$F5,$0E,$A5,$52,$48,$96,$AD,$19,$0D,$30,$6C,$46,$BC,$5F,$8B
Data.b $29,$80,$9B,$15,$D1,$93,$D8,$00,$17,$C6,$E9,$9A,$36,$2B,$44,$B9
Data.b $50,$94,$B2,$29,$EC,$90,$02,$A0,$E9,$95,$3D,$10,$AD,$B2,$A5,$1C
Data.b $09,$2A,$09,$BC,$92,$03,$A0,$5B,$35,$AC,$53,$D8,$A8,$1B,$11,$12
Data.b $D8,$50,$8D,$23,$C7,$37,$E1,$A7,$1F,$0F,$57,$72,$79,$1F,$22,$A9
Data.b $59,$0C,$96,$09,$1A,$CB,$8B,$BC,$6D,$6C,$CF,$E8,$CE,$E8,$6F,$E3
Data.b $CB,$C6,$74,$12,$4C,$BF,$A4,$75,$FD,$10,$ED,$78,$5F,$1C,$3D,$66
Data.b $CA,$69,$22,$EF,$02,$B2,$44,$02,$A1,$49,$24,$AE,$81,$2B,$F4,$B4
Data.b $87,$E1,$36,$7F,$FF,$D9
EndDataSection
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

Your example is great, Sparkie! I can definately make that work the same way with a few tweaks. :)

Any chance the scrollbar width can be changed as well? Maybe with a clever theme hack?
Post Reply