Two problems with a customised ScrollAreaGadget

Just starting out? Need help? Post your questions and find answers here.
Seymour Clufley
Addict
Addict
Posts: 1265
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Two problems with a customised ScrollAreaGadget

Post by Seymour Clufley »

Here is a screenshot of an ownerdrawn window, containing a ScrollAreaGadget which has a custom background and holds several ImageGadgets:

Image

That's what I've got so far. The trouble is, whenever you scroll the ScrollAreaGadget (hereafter known as SAG), it flickers!

The SAG's background image (the yellow grate pattern) is being applied using this procedure, originally by Eddy:

Code: Select all

Procedure SetGadgetBrush(gad,image.l)
  
  ;If OpenLibrary(10, "uxtheme.dll")
  ;    If CallFunction(10, "SetWindowTheme", GadgetID(gad), @null.w, @null.w) = 0
  ;        ;Debug "Theme turned off for ScrollAreaGadget"
  ;    EndIf
  ;    CloseLibrary(10)
  ;EndIf
  
  ScrollAreaChild = GetWindow_(GadgetID(gad),#GW_CHILD)
  brush = CreatePatternBrush_(ImageID(image))
  SetClassLong_(ScrollAreaChild, #GCL_HBRBACKGROUND,brush)
  InvalidateRect_(ScrollAreaChild, #Null, #True)
  
EndProcedure
The commented section doesn't help. It's included as a possible lead.


The second problem is this: ideally, I'd like to customise the scrollbars. I'd like them to be (or rather appear to be) ownerdrawn. I'm going for a completely custom GUI like Fruityloops.

Given that, would I be better abandoning the SAG and coding the whole thing from scratch? If so it seems a pity because the SAG is just so damned useful, but I really want this to look professional. With everything else being ownerdrawn, standard scrollbars stick out a mile.

If it's necessary to create this myself, can anyone recommend approaches? I did try to do this a few years ago and I remember it being very complicated. For example, are there any algorithms for calculating the appropriate width of a scrollbar from the scrollable area?

But the main problem would be the scrollable area itself. With a SAG, the areas off-screen are dealt with. I don't know how to create a "window" where the viewable area is smaller than the total area. Has anybody done that before with PB? Would a disabled imagegadget be the solution, with its image recalibrated whenever the "scrollbars" are used? Trouble is I read a post by Freak warning against having overlapping gadgets.

Any help would be gratefully appreciated.

Thanks for reading,
Seymour.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

Could you test this snippet? I have no flicker at all.

Code: Select all

Procedure SetGadgetBrush(gad,image.l)
  ScrollAreaChild = GetWindow_(GadgetID(gad),#GW_CHILD)
  brush = CreatePatternBrush_(ImageID(image))
  SetClassLong_(ScrollAreaChild, #GCL_HBRBACKGROUND,brush)
  InvalidateRect_(ScrollAreaChild, #Null, #True)
EndProcedure

CreateImage(0,640,480)
StartDrawing(ImageOutput(0))
For i=0 To 479
	Box(0,i,640,1,i*255/479)
Next
StopDrawing()

OpenWindow(0,0,0,320,240,"void",#WS_OVERLAPPEDWINDOW | 1)
CreateGadgetList(WindowID(0))
ScrollAreaGadget(0,0,0,0,0,640,480,10)

SetGadgetBrush(0,0)

Repeat
	EventID = WaitWindowEvent()

	If EventID = #PB_Event_SizeWindow
		ResizeGadget(0,5,5,WindowWidth(0)-10,WindowHeight(0)-10)
	EndIf
Until EventID = #PB_Event_CloseWindow
As for the scrollbars, you won't get far if you are looking for ownerdraw solution like for buttons. There don't exist any. You would have to code them entirely from scratch. Fl Studio is doing the same as you can see by right clicking a scrollbar. It doesn't include the Windowds system menu. I have various codes regarding the skinning of Windows and controls. Maybe I find somthing useful.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

Ah, now I see what you mean. There's a small flicker at the top and bottom of the gadget. I didn't consider that as a bad so I didn't bother.

You can avoid this by adding this line to your procedure:

Code: Select all

SetWindowLong_(GadgetID(gad),#GWL_STYLE,GetWindowLong_(GadgetID(gad),#GWL_STYLE) | #WS_CLIPCHILDREN)
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Yes, whenever I've done similar things with ScrollArea's and customised the 'inner area', then I've always had to take steps to prevent the main scroll area window from interfering with the inner area and causing the flicker. Usually I subclass the scroll area and then intercept the #WM_ERASEBKGND message and paint only those parts not occupied by the inner area (the inner area usually takes up the whole client area), although fluid's approach should work just as well. :)
I may look like a mule, but I'm not a complete ass.
Seymour Clufley
Addict
Addict
Posts: 1265
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Post by Seymour Clufley »

Thanks very much, Fluid Byte. That line of code solved the flickering!

The remaining issue is customising the scrollbars. I found this thread in which you hide the scrollbar of a ListViewGadget by placing it inside a ContainerGadget that is slightly too narrow. I've done that with the ScrollAreaGadget (using GetSystemMetrics for the correct scrollbar width) and it works perfectly.

Now to replace the scrollbars. I can make a custom scrollbar using imagegadgets. The buttons at either end will result in a SetScrollX/Y being sent to the ScrollAreaGadget - should be simple.

The trouble is the slider. It will have to be resized correctly. Does anyone know a formula for how long a slider should be based on the inner and outer scroll widths? I ask because this is the bit that stumped me when I tried this a few years ago. I just can't get my head around it.

Would it be...

Code: Select all

width = innerwidth/outerwidth
x = I have no idea
It's shocking, isn't it, but maths like this just blanks my mind...
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Your formula just needs completing! :)

Use something like (vertical scroll bar) :

thumb-size = scrollLength * heightOfClientArea/TotalHeightOfDocument

(assuming you are using pixels as your scrolling units.) This is essentially how Window's scroll-bars operate.

You'll then just have to take care with your min and max scroll positions etc.
I may look like a mule, but I'm not a complete ass.
Seymour Clufley
Addict
Addict
Posts: 1265
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Post by Seymour Clufley »

Thanks, Srod!

Here's what I've done. The only line you need to change is 587, where it asks for an image to use as the background for the ScrollAreaGadget. You should use a small image that can be tiled.

I'm pretty sure this code covers all the functionality of Windows scrollbars.

The only problem is dealing with clicking in the bar (not the slider, but on the bar itself). I decided that this should make the slider centre on the mouse position, but it doesn't work well at the extreme ends of the scrollbar.

Nonetheless, I hope people in the future find this code useful.

Any suggestions or improvements would be most welcome. :)

Code: Select all

Global exitbutton.l


;- COSMETIC FUNCTIONS

Procedure DrawBox(x.l,y.l,w.l,h.l,colour.l)
  
  LineXY(x,y,x+w,y,colour) ; top
  LineXY(x,y,x,y+h,colour) ; left
  LineXY(x,y+h,x+w,y+h,colour) ; bottom 
  LineXY(x+w,y,x+w,y+h,colour) ; right
  
EndProcedure

Procedure.l SetWindowBrush(window.l,image.l,free.b)
  
  brush = CreatePatternBrush_(ImageID(image))
  
  SetClassLong_(WindowID(window),#GCL_HBRBACKGROUND,brush)
  InvalidateRect_(WindowID(window),0,#True)
  
  If free
      FreeImage(image)
  EndIf
  
  ProcedureReturn brush
  
EndProcedure

Procedure Checkerize(xBase.l,yBase.l,w.l,h.l,level.l)
  
  colour = RGB(level,level,level)
  
  xStart = xBase-1
  switch.b = 0
  For y = yBase-1 To yBase+h
      For x = xStart To w Step 2
          If x>-1 And y>-1
              Plot(x,y,colour)
          EndIf
      Next
      If switch
          switch = 0
          xStart = xBase-1
      Else
          switch = 1
          xStart = xBase
      EndIf
  Next
  ProcedureReturn
  
EndProcedure

Procedure.f Beat(a.f,b.f)
  
  If a>b
      ProcedureReturn a
  Else
      ProcedureReturn b
  EndIf
  
EndProcedure

Procedure.f Defeat(a.f,b.f)
  
  If a<b
      ProcedureReturn a
  Else
      ProcedureReturn b
  EndIf
  
EndProcedure

Procedure SetGadgetBrush(gad,image.l,free.b)
  
  ;If OpenLibrary(10, "uxtheme.dll")
  ;    If CallFunction(10, "SetWindowTheme", GadgetID(gad), @null.w, @null.w) = 0
  ;        ;Debug "Theme turned off for ScrollAreaGadget"
  ;    EndIf
  ;    CloseLibrary(10)
  ;EndIf
  
  ScrollAreaChild = GetWindow_(GadgetID(gad),#GW_CHILD)
  
  SetWindowLong_(GadgetID(gad),#GWL_STYLE,GetWindowLong_(GadgetID(gad),#GWL_STYLE) | #WS_CLIPCHILDREN)
  
  brush = CreatePatternBrush_(ImageID(image))
  SetClassLong_(ScrollAreaChild, #GCL_HBRBACKGROUND,brush)
  InvalidateRect_(ScrollAreaChild, #Null, #True)
  
  
  If free
      FreeImage(image)
  EndIf
  
EndProcedure

Procedure.l RedBox(w.l,h.l)
  
  img = CreateImage(#PB_Any,w,h)
  StartDrawing(ImageOutput(img))
    Box(0,0,w,h,#Red)
  StopDrawing()
  
  ProcedureReturn img
  
EndProcedure

Procedure.b Tile(img.l,tile.l,alpha.b)
  
  If Not IsImage(img)
      ProcedureReturn #False
  EndIf
  
  If Not IsImage(tile)
      ProcedureReturn #False
  EndIf
  
  iw = ImageWidth(img)
  ih = ImageHeight(img)
  
  tw = ImageWidth(tile)
  th = ImageHeight(tile)
  
  Repeat
      Repeat
          If alpha
              DrawAlphaImage(ImageID(tile),x,y)
          Else
              DrawImage(ImageID(tile),x,y)
          EndIf
          x+tw
      Until x>iw
      y+th
      x=0
  Until y>ih
  
  ProcedureReturn #True
  
EndProcedure


;- SCROLLING FUNCTIONS

;{ STRUCTURE
Structure ODSAG
  sag.l ; gadgetnumber for actual ScrollAreaGadget
  
  container.l ; gadgetnumber (probably redundant)
  window.l
  
  x.f
  y.f
  w.f
  h.f
  
  sx.f ; innerscrollX
  sy.f ; innerscrollY
  sw.f ; innerscrollwidth
  sh.f ; innerscrollheight
  
  steps.w
  barT.w
  
  ; button nums
  xSlider.l
  lbutton.l
  rbutton.l
  
  ySlider.l
  ubutton.l
  dbutton.l
  
  xBar.l
  yBar.l
  xBarI.l
  yBarI.l
  
  ; image nums
  xSliderI.l
  ySliderI.l
  
  tile.l
  
EndStructure
;}




Procedure.l GadXFromScrollX(*SAG.ODSAG)
  
  x.f = GadgetWidth(*SAG\xBar) / *SAG\sw * *SAG\sx
  
  x = Beat(x,0)
  
  x+GadgetX(*SAG\xBar)
  
  xgmax = GadgetX(*SAG\rButton)-GadgetWidth(*SAG\xSlider)
  ProcedureReturn Defeat(x,xgmax)
  
EndProcedure

Procedure.l GadYFromScrollY(*SAG.ODSAG)
  
  y.f = GadgetHeight(*SAG\yBar) / *SAG\sh * *SAG\sy
  
  y = Beat(y,0)
  
  y+GadgetY(*SAG\yBar)
  
  ygmax = GadgetY(*SAG\dButton)-GadgetHeight(*SAG\ySlider)
  ProcedureReturn Defeat(y,ygmax)
  
EndProcedure


Procedure.l ScrollXFromGadX(*SAG.ODSAG,gx.f)
  
  sx.f = *SAG\sw / GadgetWidth(*SAG\xBar) * gx
  
  sx = Beat(sx,0)
  
  ProcedureReturn sx;Defeat(sx,*SAG\sw - *SAG\w)
  
EndProcedure

Procedure.l ScrollYFromGadY(*SAG.ODSAG,gy.f)
  
  sy.f = *SAG\sh / GadgetHeight(*SAG\yBar) * gy
  
  sy = Beat(sy,0)
  
  ProcedureReturn sy;Defeat(sy,*SAG\sh - *SAG\h)
  
EndProcedure


Procedure UpdateODSAG(*SAG.ODSAG)
  
  *SAG\sx = Beat(0,*SAG\sx)
  *SAG\sy = Beat(0,*SAG\sy)
  
  
  SetGadgetAttribute(*SAG\sag,#PB_ScrollArea_X,*SAG\sx)
  
  barw.f = *SAG\w - GadgetWidth(*SAG\lButton) - GadgetWidth(*SAG\rButton) - *SAG\barT
  
  
  If barw<>GadgetWidth(*SAG\xBar) Or Not IsImage(*SAG\xBarI)
      If IsImage(*SAG\xBarI)
          FreeImage(*SAG\xBarI)
      EndIf
      img = CreateImage(#PB_Any,barw,*SAG\barT)
      
      StartDrawing(ImageOutput(img))
          Box(0,0,barw,*SAG\barT,RGB(128,0,255))
      StopDrawing()
      
      SetGadgetState(*SAG\xBar,ImageID(img))
      SetWindowPos_(GadgetID(*SAG\xBar),#HWND_BOTTOM,0,0,0,0,#SWP_NOSIZE|#SWP_NOMOVE) 
      *SAG\xBarI = img
  EndIf
  
  
  w.f = barw * *SAG\w / *SAG\sw
  
  If w<>GadgetWidth(*SAG\xSlider)
      If IsImage(*SAG\xSliderI)
          FreeImage(*SAG\xSliderI)
      EndIf
      img = CreateImage(#PB_Any,w,*SAG\barT)
      StartDrawing(ImageOutput(img))
          Box(0,0,w,*SAG\barT,RGB(0,58,89))
          Checkerize(0,0,w,*SAG\barT,0)
      StopDrawing()
      
      SetGadgetState(*SAG\xSlider,ImageID(img))
      *SAG\xSliderI = img
  EndIf
  
  ResizeGadget(*SAG\xSlider,GadXFromScrollX(*SAG),#PB_Ignore,#PB_Ignore,#PB_Ignore)
  
  
  
  
  SetGadgetAttribute(*SAG\sag,#PB_ScrollArea_Y,*SAG\sy)
  
  barh.f = *SAG\h - GadgetHeight(*SAG\uButton) - GadgetHeight(*SAG\dButton) - *SAG\barT
  h.f = barh * *SAG\h / *SAG\sh
  
  
  If barh<>GadgetHeight(*SAG\yBar) Or Not IsImage(*SAG\yBarI)
      If IsImage(*SAG\yBarI)
          FreeImage(*SAG\yBarI)
      EndIf
      img = CreateImage(#PB_Any,*SAG\barT,barh)
      
      StartDrawing(ImageOutput(img))
          Box(0,0,*SAG\barT,barh,RGB(128,0,255))
      StopDrawing()
      
      SetGadgetState(*SAG\yBar,ImageID(img))
      SetWindowPos_(GadgetID(*SAG\yBar),#HWND_BOTTOM,0,0,0,0,#SWP_NOSIZE|#SWP_NOMOVE) 
      *SAG\yBarI = img
  EndIf
  
  If h<>GadgetHeight(*SAG\ySlider)
      If IsImage(*SAG\ySliderI)
          FreeImage(*SAG\ySliderI)
      EndIf
      img = CreateImage(#PB_Any,*SAG\barT,h)
      StartDrawing(ImageOutput(img))
          Box(0,0,*SAG\barT,h,RGB(0,58,89))
          Checkerize(0,0,*SAG\barT,h,0)
      StopDrawing()
      
      SetGadgetState(*SAG\ySlider,ImageID(img))
      *SAG\ySliderI = img
  EndIf
  
  gady=GadYFromScrollY(*SAG)
  ResizeGadget(*SAG\ySlider,#PB_Ignore,gady,#PB_Ignore,#PB_Ignore)
  
  
EndProcedure


Procedure CheckODSAG(*SAG.ODSAG,we,eg)
  
  If we<>#PB_Event_Gadget
      ProcedureReturn
  EndIf
  
  *SAG\sx = GetGadgetAttribute(*SAG\sag,#PB_ScrollArea_X)
  *SAG\sy = GetGadgetAttribute(*SAG\sag,#PB_ScrollArea_Y)
  xmax = *SAG\sw - *SAG\w + *SAG\barT
  ymax = *SAG\sh - *SAG\h + *SAG\barT
  Select eg
      ;Case *SAG\sag
          ;MessageRequester("report","background was pressed!",0)
      Case *SAG\lButton
          Repeat
              *SAG\sx-*SAG\steps
              If *SAG\sx<0
                  *SAG\sx = 0
                  update=#True
                  Break
              EndIf
              UpdateODSAG(*SAG)
              Delay(50)
          Until Not GetAsyncKeyState_(#VK_LBUTTON)
      Case *SAG\rButton
          Repeat
              *SAG\sx+*SAG\steps
              If *SAG\sx>xmax
                  *SAG\sx = xmax
                  update=#True
                  Break
              EndIf
              UpdateODSAG(*SAG)
              Delay(50)
          Until Not GetAsyncKeyState_(#VK_LBUTTON)
      Case *SAG\uButton
          Repeat
              *SAG\sy-*SAG\steps
              If *SAG\sy<0
                  *SAG\sy = 0
                  update=#True
                  Break
              EndIf
              UpdateODSAG(*SAG)
              Delay(50)
          Until Not GetAsyncKeyState_(#VK_LBUTTON)
      Case *SAG\dButton
          Repeat
              *SAG\sy+*SAG\steps
              If *SAG\sy>ymax
                  *SAG\sy = ymax
                  update=#True
                  Break
              EndIf
              UpdateODSAG(*SAG)
              Delay(50)
          Until Not GetAsyncKeyState_(#VK_LBUTTON)
      
      
      Case *SAG\xSlider
          MonitorXSlider:
          offset = WindowMouseX(*SAG\window)-GadgetX(*SAG\xSlider)+(GadgetWidth(*SAG\xSlider)/2)
          Repeat
              Repeat
                  we=WindowEvent()
                  If we=#WM_LBUTTONUP
                      update=#True
                      Break 2
                  EndIf
              Until we=#WM_MOUSEMOVE
              *SAG\sx = ScrollXFromGadX(*SAG,WindowMouseX(*SAG\window)-offset)
              UpdateODSAG(*SAG)
          Until Not GetAsyncKeyState_(#VK_LBUTTON)
      Case *SAG\ySlider
          MonitorYSlider:
          offset = WindowMouseY(*SAG\window)-GadgetY(*SAG\ySlider)+(GadgetHeight(*SAG\ySlider)/2)
          Repeat
              Repeat
                  we=WindowEvent()
                  If we=#WM_LBUTTONUP
                      update=#True
                      Break 2
                  EndIf
              Until we=#WM_MOUSEMOVE
              *SAG\sy = ScrollYFromGadY(*SAG,WindowMouseY(*SAG\window)-offset)
              UpdateODSAG(*SAG)
          Until Not GetAsyncKeyState_(#VK_LBUTTON)
      
      
      Case *SAG\xBar
          ; jump left or right
          mx.f = WindowMouseX(*SAG\window)-GadgetX(*SAG\xBar)
          mx-(GadgetWidth(*SAG\xSlider)/2)
          mx = beat(1,mx)
          *SAG\sx = ScrollXFromGadX(*SAG,mx)
          UpdateODSAG(*SAG)
          If GetAsyncKeyState_(#VK_LBUTTON)
              Goto MonitorXSlider
          EndIf
      Case *SAG\yBar
          ; jump up or down
          my.f = WindowMouseY(*SAG\window)-GadgetY(*SAG\yBar)
          my-(GadgetHeight(*SAG\ySlider)/2)
          my = beat(1,my)
          *SAG\sy = ScrollYFromGadY(*SAG,my)
          UpdateODSAG(*SAG)
          If GetAsyncKeyState_(#VK_LBUTTON)
              Goto MonitorYslider
          EndIf
      
  EndSelect
  
  If update
      UpdateODSAG(*SAG)
  EndIf
  
EndProcedure




Procedure ResizeODSAG(*SAG.ODSAG,w.l,h.l)
  
  If w<>#PB_Ignore
      *SAG\w = w
  EndIf
  If h<>#PB_Ignore
      *SAG\h = h
  EndIf
  
  
  nativewidth = GetSystemMetrics_(#SM_CYHSCROLL)
  major = Beat(*SAG\barT,nativewidth)
  minor = Defeat(*SAG\barT,nativewidth)
  
  If *SAG\barT<nativewidth
      sagw=*SAG\w+(nativewidth-*SAG\barT)
      sagh=*SAG\h+(nativewidth-*SAG\barT)
      cw=*SAG\w-*SAG\barT
      ch=*SAG\h-*SAG\barT
  Else
      sagw=*SAG\w-major+minor
      sagh=*SAG\h-major+minor
      cw=sagw-minor
      ch=sagh-minor
  EndIf
  
  ResizeGadget(*SAG\container,*SAG\x,*SAG\y,cw,ch)
  ResizeGadget(*SAG\sag,0,0,sagw,sagh)
  SetGadgetAttribute(*SAG\sag,#PB_ScrollArea_InnerWidth,*SAG\sw)
  SetGadgetAttribute(*SAG\sag,#PB_ScrollArea_InnerHeight,*SAG\sh)
  
  
  tiled = CreateImage(#PB_Any,*SAG\sw,*SAG\sh)
  StartDrawing(ImageOutput(tiled))
      Tile(tiled,*SAG\tile,#False)
  StopDrawing()
  SetGadgetBrush(*SAG\sag,*SAG\tile,#True)
  
  ResizeGadget(*SAG\lButton,*SAG\x,*SAG\y+*SAG\h-*SAG\barT,*SAG\barT,*SAG\barT)
  ResizeGadget(*SAG\rButton,*SAG\x+*SAG\w-*SAG\barT-*SAG\barT,*SAG\y+*SAG\h-*SAG\barT,*SAG\barT,*SAG\barT)
  ResizeGadget(*SAG\uButton,*SAG\x+*SAG\w-*SAG\barT,*SAG\y,*SAG\barT,*SAG\barT)
  ResizeGadget(*SAG\dButton,*SAG\x+*SAG\w-*SAG\barT,*SAG\y+*SAG\h-*SAG\barT-*SAG\barT,*SAG\barT,*SAG\barT)
  
  
  
  ResizeGadget(*SAG\xBar,GadgetX(*SAG\lButton)+GadgetWidth(*SAG\lButton),*SAG\y+*SAG\h-*SAG\barT,*SAG\w-GadgetWidth(*SAG\lButton)-GadgetWidth(*SAG\rButton)-*SAG\barT,*SAG\barT)
  ResizeGadget(*SAG\yBar,*SAG\x+*SAG\w-*SAG\barT,GadgetY(*SAG\uButton)+GadgetHeight(*SAG\uButton),*SAG\barT,*SAG\y-GadgetHeight(*SAG\uButton)-GadgetHeight(*SAG\dButton))
  
  ResizeGadget(*SAG\xSlider,*SAG\x,*SAG\y+*SAG\h-*SAG\barT,100,*SAG\barT)
  ResizeGadget(*SAG\ySlider,*SAG\x+*SAG\w-*SAG\barT,*SAG\y+*SAG\h-*SAG\barT,*SAG\barT,100)
  
  
  UpdateODSAG(*SAG)
  
EndProcedure


Procedure ODSAG(*SAG.ODSAG,x,y,w,h,innerwidth.l,innerheight.l,steps.l,scrollbarwidth.w,tile.l,window.l)
  
  *SAG\x = x
  *SAG\y = y
  *SAG\w = w
  *SAG\h = h
  *SAG\sw = innerwidth
  *SAG\sh = innerheight
  *SAG\steps = steps
  *SAG\barT = scrollbarwidth
  *SAG\tile = tile
  *SAG\window = window
  
  *SAG\container = ContainerGadget(#PB_Any,0,0,1,1,#PB_Container_BorderLess)
  *SAG\sag = ScrollAreaGadget(#PB_Any,0,0,1,1,*SAG\sw,*SAG\sh,*SAG\steps,#PB_ScrollArea_BorderLess)
  
  exitbutton = ButtonGadget(#PB_Any,100,100,200,150,"Close")
  CloseGadgetList()
  CloseGadgetList()
  
  
  
  ; create LEFT arrow button
  ;scrollLimg = LoadImage(#PB_Any,ImageFol+"ScrollL.png")
  scrollLimg = RedBox(*SAG\barT,*SAG\barT)
  *SAG\lButton = ImageGadget(#PB_Any,*SAG\x,*SAG\y+*SAG\h-*SAG\barT,*SAG\barT,*SAG\barT,ImageID(scrollLimg))
  
  ; create RIGHT arrow button
  ;scrollRimg = LoadImage(#PB_Any,ImageFol+"ScrollR.png")
  scrollRimg = RedBox(*SAG\barT,*SAG\barT)
  *SAG\rButton = ImageGadget(#PB_Any,*SAG\x+*SAG\w-*SAG\barT-*SAG\barT,*SAG\y+*SAG\h-*SAG\barT,*SAG\barT,*SAG\barT,ImageID(scrollRimg))
  
  ; create UP arrow button
  ;scrollUimg = LoadImage(#PB_Any,ImageFol+"ScrollU.png")
  scrollUimg = RedBox(*SAG\barT,*SAG\barT)
  *SAG\uButton = ImageGadget(#PB_Any,*SAG\x+*SAG\w-*SAG\barT,*SAG\y,*SAG\barT,*SAG\barT,ImageID(scrollUimg))
    
  ; create DOWN arrow button
  ; scrollDimg = LoadImage(#PB_Any,ImageFol+"ScrollD.png")
  scrollDimg = RedBox(*SAG\barT,*SAG\barT)
  *SAG\dButton = ImageGadget(#PB_Any,*SAG\x+*SAG\w-*SAG\barT,*SAG\y+*SAG\h-*SAG\barT-*SAG\barT,*SAG\barT,*SAG\barT,ImageID(scrollDimg))
  
  
  
  *SAG\xBar = ImageGadget(#PB_Any,GadgetX(*SAG\lButton)+GadgetWidth(*SAG\lButton),*SAG\y+*SAG\h-*SAG\barT,*SAG\w-GadgetWidth(*SAG\lButton)-GadgetWidth(*SAG\rButton)-*SAG\barT,*SAG\barT,0)
  ; allow bg imagegadget to be z-ordered in "UpdateODSAG" procedure
  SetWindowLong_(GadgetID(*SAG\xBar),#GWL_STYLE,GetWindowLong_(GadgetID(*SAG\xBar),#GWL_STYLE)|#WS_CLIPSIBLINGS) 
  
  *SAG\yBar = ImageGadget(#PB_Any,*SAG\x+*SAG\w-*SAG\barT,GadgetY(*SAG\uButton)+GadgetHeight(*SAG\uButton),*SAG\barT,*SAG\y-GadgetHeight(*SAG\uButton)-GadgetHeight(*SAG\dButton),0)
  ; allow bg imagegadget to be z-ordered in "UpdateODSAG" procedure
  SetWindowLong_(GadgetID(*SAG\yBar),#GWL_STYLE,GetWindowLong_(GadgetID(*SAG\yBar),#GWL_STYLE)|#WS_CLIPSIBLINGS) 
  
  ; X slider
  *SAG\xSlider = ImageGadget(#PB_Any,*SAG\x,*SAG\y+*SAG\h-*SAG\barT,100,*SAG\barT,0)
  ; Y slider
  *SAG\ySlider = ImageGadget(#PB_Any,*SAG\x+*SAG\w-*SAG\barT,*SAG\y+*SAG\h-*SAG\barT,*SAG\barT,100,0)
  
  ResizeODSAG(*SAG,*SAG\w,*SAG\h)
  
EndProcedure


ExamineDesktops()
ww.f = DesktopWidth(0)-50
wh.f = DesktopHeight(0)-100

win = OpenWindow(#PB_Any,0,0,ww,wh,"test",#PB_Window_ScreenCentered)
If CreateGadgetList(WindowID(win))
    brush = CreateImage(#PB_Any,ww,wh)
    StartDrawing(ImageOutput(brush))
      Box(0,0,ww,wh,#Gray)
      x=Random(100)
      y=Random(100)
      w=ww-x-Random(100)
      h=wh-y-Random(100)
      DrawBox(x-1,y-1,w+1,h+1,#Green)
    StopDrawing()
    SetWindowBrush(win,brush,#True)
    
    
    tile = LoadImage(#PB_Any,"C:\inner-pattern.bmp") ; this is the background tile for the inner area.
    ODSAG(@SAG.ODSAG,x,y,w,h,ww+5000,wh+2000,10,Random(50)+8,tile,win)
EndIf

Repeat
    we = WindowEvent()
    
    eg = EventGadget()
    If we=#PB_Event_Gadget
        If eg=exitbutton
            End
        EndIf
    EndIf
    
    CheckODSAG(@SAG,we,eg)
    
    Delay(10)
    
Until GetAsyncKeyState_(#VK_ESCAPE)
End
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

Just for info, i have changed the path of picture in line 587.
And i have an error in line 483 "Image object mot initialized" :cry:
ImageThe happiness is a road...
Not a destination
Post Reply