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! :wink:

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 :wink: )