Position of scrolled image[solution]

Mac OSX specific forum
WilliamL
Addict
Addict
Posts: 1252
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Position of scrolled image[solution]

Post 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
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Position of scrolled image[solution]

Post by IdeasVacuum »

Now that is clever! :wink:
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Position of scrolled image[solution]

Post 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
WilliamL
Addict
Addict
Posts: 1252
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: Position of scrolled image[solution]

Post 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. :)
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: Position of scrolled image[solution]

Post 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
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Re: Position of scrolled image[solution]

Post 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 :)
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: Position of scrolled image[solution]

Post 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?
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Re: Position of scrolled image[solution]

Post 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 :)
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: Position of scrolled image[solution]

Post 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
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Re: Position of scrolled image[solution]

Post 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: )
Post Reply