Page 1 of 1
Position of scrolled image[solution]
Posted: Fri Nov 05, 2010 4:34 pm
by WilliamL
I use ListViewGadets most of the time but sometimes, since color doesn't work on ListViewGadgets on the Mac, I want to have a color background and various colors of text so I use an image for the list with all the color commands. One of the advantages of the ListViewGadget is scrolling long lists. Below is a list of lines in an image and the lines can be identified by clicking on them even though the image is scrolled.
This code uses the built-in abilities of PureBasic and is cross-platform.
Code: Select all
Enumeration
#wndw
#imageid
#gadgetid
#gadgetct
EndEnumeration
lh=19 : bw=19
lnes=15
imageh=lnes*lh
w=200
h=200+bw
If OpenWindow(#wndw,0,0,w,h, "Which line?", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If CreateImage(#imageid,w-bw,imageh)
If StartDrawing(ImageOutput(#imageid))
DrawingMode(#PB_2DDrawing_Transparent)
For lne=0 To lnes-1
If lne % 2
Box(0,lne*lh,w,lh,$99FF99)
Else
Box(0,lne*lh,w,lh,$FFFFFF)
EndIf
DrawText(xtab,(lne*lh)+yoffset,"Line "+Str(lne+1),0)
Next
StopDrawing()
EndIf
EndIf
ScrollAreaGadget(#gadgetct,0,0,w,h,w-bw,imageh,1)
ImageGadget(#gadgetid,0,0,w,imageh,ImageID(#imageid))
CloseGadgetList()
SetGadgetData(#gadgetid,lh) ; to carry over to event loop
EndIf
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case #gadgetid,#gadgetct ; ScrollAreaGadget scrollbar doesn't give an event
id=((WindowMouseY(#wndw)+GetGadgetAttribute(#gadgetct,#PB_ScrollArea_Y ))/GetGadgetData(#gadgetid))
Debug "Line "+Str(id+1)
; Debug GetGadgetAttribute(#gadgetct,#PB_ScrollArea_Y )
; Debug GetGadgetAttribute(#gadgetct,#PB_ScrollArea_X )
; Debug GetGadgetAttribute(#gadgetct,#PB_ScrollArea_InnerHeight)
; Debug GetGadgetAttribute(#gadgetct,#PB_ScrollArea_InnerWidth)
EndSelect
Case #PB_Event_CloseWindow
Break ; End
EndSelect
ForEver
Re: Position of scrolled image[solution]
Posted: Sat Nov 06, 2010 1:23 pm
by IdeasVacuum
Now that is clever!

Re: Position of scrolled image[solution]
Posted: Wed Feb 02, 2011 10:48 pm
by Shardik
William,
thank you for your clever example that doesn't need any API calls. Although you
are right that ListViewGadget and ListIconGadget (because of the underlying
DataBrowser API) don't support colors, they nevertheless support the alternating
coloring of rows. But it isn't possible to change the predefined colors. So if you
can live with the predefined alternating row background colors white and light
blue, the detection of the clicked item becomes quite easy:
Code: Select all
ImportC ""
DataBrowserChangeAttributes(ControlRef, AttributesToSet, AttributesToClear)
EndImport
#kDataBrowserAttributeListViewAlternatingRowColors = (1 << 1)
OpenWindow(0, 0, 0, 270, 140, "ListViewGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListViewGadget(0, 10, 10, 250, 120)
DataBrowserChangeAttributes(GadgetID(0), #kDataBrowserAttributeListViewAlternatingRowColors, 0)
For i = 1 To 12
AddGadgetItem (0, -1, "Item " + Str(i) + " of the ListView")
Next
SetGadgetState(0, 9)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
If EventGadget() = 0
If EventType() = #PB_EventType_LeftClick
Debug GetGadgetText(0)
EndIf
EndIf
EndSelect
ForEver
Re: Position of scrolled image[solution]
Posted: Wed Feb 02, 2011 11:10 pm
by WilliamL
Shardik,
That is quite interesting and another nice feature of this API is that it is quite short and simple. With a long list this will be useful.
Thanks for the info.

Re: Position of scrolled image[solution]
Posted: Sat Sep 17, 2011 10:13 am
by jesperbrannmark
An update of the first example using
canvasgadget instead of imagegadget and a image.
Canvasgadget is relly awsome here, it can use mousewheel etc as events and I will probably trim this into a listicongadget alternative.
Anyone know how effective it is with memory? (ie very large areas)
Code: Select all
Enumeration
#wndw
#gadgetid
#gadgetct
EndEnumeration
lh=19 : bw=19
lnes=15
imageh=lnes*lh
w=200
h=200+bw
If OpenWindow(#wndw,0,0,w,h, "Which line?", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ScrollAreaGadget(#gadgetct,0,0,w,h,w-bw,imageh,1)
CanvasGadget(#gadgetid,0,0,w,imageh,#PB_Canvas_Keyboard)
If StartDrawing(CanvasOutput(#gadgetid))
DrawingMode(#PB_2DDrawing_Transparent)
For lne=0 To lnes-1
If lne % 2
Box(0,lne*lh,w,lh,$99FF99)
Else
Box(0,lne*lh,w,lh,$FFFFFF)
EndIf
DrawText(xtab,(lne*lh)+yoffset,"Line "+Str(lne+1),0)
Next
StopDrawing()
EndIf
EndIf
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
If EventGadget()=#gadgetid And EventType()=#PB_EventType_LeftClick
id=GetGadgetAttribute(#gadgetid, #PB_Canvas_MouseY)/lh
Debug "Line "+Str(id+1)
ElseIf EventGadget()=#gadgetid And EventType()=#PB_EventType_MouseWheel
SetGadgetAttribute(#gadgetct,#PB_ScrollArea_Y,GetGadgetAttribute(#gadgetct,#PB_ScrollArea_Y)-(GetGadgetAttribute(#gadgetid,#PB_Canvas_WheelDelta)*lh))
Debug "scroll"+Str(GetGadgetAttribute(#gadgetid,#PB_Canvas_WheelDelta))
EndIf
Case #PB_Event_CloseWindow
Break ; End
EndSelect
ForEver
Re: Position of scrolled image[solution]
Posted: Sat Sep 17, 2011 11:26 am
by Polo
You should use a scrollareagadget, I'd rather use a canvas gadget with scrollbars as it'd be more efficient when dealing with large images

Re: Position of scrolled image[solution]
Posted: Sat Sep 17, 2011 12:11 pm
by jesperbrannmark
What do you mean? That your canvasgadget always is the same size (say 400 px x 400 px) and once you move the scrollbargadget() you repaint the entire thing?
Re: Position of scrolled image[solution]
Posted: Sat Sep 17, 2011 12:25 pm
by Polo
Yes, that's how I'd do it anyway, to avoid having a gadget sized 7000x7000 if you have a very large image

Re: Position of scrolled image[solution]
Posted: Sat Sep 17, 2011 12:44 pm
by jesperbrannmark
So, more like this?
(i would exect the drawing functions to first see if we are painting on a visible area and if not just ignore it, but the line
If (lne*lh)-GetGadgetState(#gadgetct)+lh>0 And (lne*lh)-GetGadgetState(#gadgetct)<h ;dont paint if its outside was very much needed)
Code: Select all
Enumeration
#wndw
#gadgetid
#gadgetct
EndEnumeration
Global lh=19
Global bw=19
Global lnes=1500
Global imageh=lnes*lh
Global w=200
Global h=200+bw
Procedure repaint()
If StartDrawing(CanvasOutput(#gadgetid))
DrawingMode(#PB_2DDrawing_Transparent)
For lne=0 To lnes-1
If (lne*lh)-GetGadgetState(#gadgetct)+lh>0 And (lne*lh)-GetGadgetState(#gadgetct)<h ;dont paint if its outside
If lne % 2
Box(0,(lne*lh)-GetGadgetState(#gadgetct),w,lh,$99FF99)
Else
Box(0,(lne*lh)-GetGadgetState(#gadgetct),w,lh,$FFFFFF)
EndIf
DrawText(xtab,((lne*lh))-GetGadgetState(#gadgetct),"Line "+Str(lne+1),0)
EndIf
Next
StopDrawing()
EndIf
EndProcedure
If OpenWindow(#wndw,0,0,w,h, "Which line?", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ScrollBarGadget(#gadgetct,WindowWidth(#wndw)-15,0,15,h,0,imageh-h,lh, #PB_ScrollBar_Vertical )
CanvasGadget(#gadgetid,0,0,w-20,h,#PB_Canvas_Keyboard)
EndIf
repaint()
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
If EventGadget()=#gadgetid And EventType()=#PB_EventType_LeftClick
id=GetGadgetAttribute(#gadgetid, #PB_Canvas_MouseY)/lh
Debug "Line "+Str(id+1)
ElseIf EventGadget()=#gadgetct
repaint()
ElseIf EventGadget()=#gadgetid And EventType()=#PB_EventType_MouseWheel
SetGadgetState(#gadgetct,GetGadgetState(#gadgetct)-(GetGadgetAttribute(#gadgetid,#PB_Canvas_WheelDelta)*lh)) ;scroll one line at a tmie
repaint()
Debug "scroll"+Str(GetGadgetAttribute(#gadgetid,#PB_Canvas_WheelDelta))
EndIf
Case #PB_Event_CloseWindow
Break ; End
EndSelect
ForEver
Re: Position of scrolled image[solution]
Posted: Sat Sep 17, 2011 12:59 pm
by Polo
Works nicely on Mac, and yes, like this

Although you'd rather want the pagelength param of the scrollbar to be the height of the canvas, not the height of the line, and adapt the rest to that
(scrolling in general is always a pain to handle

)