Crossplatform scrollable Canvas Gadget (Win + OSX done)

Everything else that doesn't fall into one of the other PB categories.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Crossplatform scrollable Canvas Gadget (Win + OSX done)

Post by srod »

Hi,

I am looking for someone with Mac OSX experience to convert some Windows code of mine to run on a Mac OSX (Linux will follow later). I am happy to do it myself, but have no access to a Mac just yet (am planning on buying one asap). Even when I have purchased one then it will take time for me to learn the Carbon API's etc.

This way, we don't have to wait around! :)

I am looking to use the nice new canvas gadget to create cross-platform controls. The biggest hurdle to this though (at least with the kind of controls I like to build) is the lack of a scrolling facility. PB simply does not give us the commands to do this in a nice way. We cannot really use separate scrollbar controls because our PB event loops are not provided with all the necessary scrolling events (and I think this would be an un-elegant and messy solution anyhow!) A ScrollArea gadget is not appropriate because we would then need to use a canvas gadget which is physically the size of the scrollable area and Windows, for one, places limits on this size. There are presumably also limits on the size of a canvas gadget due to image size restrictions etc.

For me, there is only one satisfactory and viable solution considering that I wish to use the existing canvas gadget and not roll my own; namely to build a cross-platform container into which we can embed a PB canvas gadget. The container would handle all of the scrolling messages and notifications etc. and the canvas gadget would be exactly as PB intended. No matter how large the 'scrollable area' (and this, unlike a ScrollArea gadget, can be as large as we like), the embedded canvas gadget would remain the size of the control's client area. We have access to all of the canvas gadget's events (such as #PB_EventType_MouseEnter) and the container will provide us with all the necessary scrolling events.

Now, by pure coincidence, such a control already exists... I have just finished it, and it works great (if I say so myself!) :)

The problem... Window's only at this time!

Now the code has been split into a couple of source files with all the Windows specific code thrown into one file containing 600 lines of source. Much of this is OOP 'overhead' however. A Mac OSX version is a 'simple' matter of converting this one file to run on a Mac! Quite a lot of the source comprising the 600 lines of code can be carried straight across and so really we're looking at perhaps a hundred lines of code requiring some kind of conversion. Course I am aware that Mac OSX probably handles scrolling completely different to Windows and so the Mac version might need a completely different approach in order to offer the same facilities as my Windows version, thus necessitating a complete rewrite of the 600 aforementioned lines. I may even have to rewrite my version to fit in with the Mac one!

Whatever the case, I am thus seeking an experienced Mac OSX / Carbon developer to work on the conversion. I would have to work closely with that person to ensure that our 2 versions operate in exactly the same way; offering the same facilities etc.

I am happy to pay for this, although I could only countenance a flat-fee as opposed to an hourly rate etc. In this case I would of course keep the resulting code myself and not make it publicly available to others except through any cross-platform controls I subsequently develop and release. Otherwise, with the other person's permission, I would be happy for the code to be made available to all.

Please contact me through pm if interested. I shall endeavour to reply asap.

Regards.

Stephen.
Last edited by srod on Sun Jan 01, 2012 9:00 pm, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Crossplatform scrollable Canvas Gadget

Post by wilbert »

Have you considered drawing scrollbars yourself inside the canvas gadget itself and limit the content to the remaining area.
The advantage would be cross platform without api. The disadvantage of course that the scrollbars wouldn't look the same compared to those the OS creates.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Crossplatform scrollable Canvas Gadget

Post by srod »

wilbert wrote:Have you considered drawing scrollbars yourself inside the canvas gadget itself and limit the content to the remaining area.
The advantage would be cross platform without api. The disadvantage of course that the scrollbars wouldn't look the same compared to those the OS creates.
Yes I have even written about 50% of the code for that, built upon a switchable theme etc. However, half way through the whole deal just didn't sit right with me for some reason (for the reason you outline for one). There was always a nagging little voice at the back of my head saying that this wasn't the right approach and, well, I just became uncomfortable with it all. Hence I stopped work and switched to the native OS way of doing it which just feels right somehow. On Windows it works really well. I have the canvas gadget doing what it is supposed to, the way Fred and Freak designed it; my code hasn't altered that at all. I haven't even had to subclass the gadget. The container is based upon a custom Window class and then I have only had to process a few messages, and superficially at that.

No, for me, this is the best solution (short of Freak adding this natively to PB of course! :wink: )
I may look like a mule, but I'm not a complete ass.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Crossplatform scrollable Canvas Gadget

Post by Trond »

Actually, you can use the scrollarea gadget without an insanely big canvas, but, you'd be left with the same problem as the scrollbar: lack of continous events.

Example:

Code: Select all

Procedure RedrawCanvas(G, X, Y, W, H)
  LoadFont(0, "Tahoma", 8)
  StartDrawing(CanvasOutput(G))
    DrawingFont(FontID(0))
    Box(0, 0, W, H, #White)
    Grid = 50
    StartX = X % Grid
    StartY = Y % Grid
    For cx = -StartX To W Step 50
      Line(cx, 0, 1, H, #Gray)
    Next
    For cy = -StartY To H Step 50
      Line(0, cy, W, 1, #Gray)
    Next
  StopDrawing()
EndProcedure


W = 512
H = 384
OpenWindow(0, 0, 0, W, H, "", #PB_Window_ScreenCentered | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget)
ScrollAreaGadget(0, 10, 10, 500, 350, 2000, 2000, 10)
SetGadgetColor(0, #PB_Gadget_BackColor, #White)
CanvasGadget(1, 0, 0, 500, 350)
RedrawCanvas(1, 0, 0, 500, 350)

Repeat
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          X = GetGadgetAttribute(0, #PB_ScrollArea_X)
          Y = GetGadgetAttribute(0, #PB_ScrollArea_Y)
          ResizeGadget(1, X, Y, #PB_Ignore, #PB_Ignore)
          RedrawCanvas(1, X, Y, 500, 350)
      EndSelect
    Case #PB_Event_CloseWindow
      CloseWindow(0)
      Break
  EndSelect
ForEver
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Crossplatform scrollable Canvas Gadget

Post by srod »

The only way I can see of using a ScrollArea gadget without an insanely big canvas would be to use API. The thing is even without an insanely large canvas, the ScrollArea gadget would be using an insanely large inner container (such is the way with the ScrollArea) and Windows would then step up with some restrictions on the size of that inner container. It may also effect the possible scroll ranges, though this would be a problem due to PB's implementation of the ScrollArea and not Windows. I cannot recall if this is the case? Not that it would impact on a canvas gadget as such, but, as you say, without the continuous scrolling messages...

Besides, this solution also wouldn't sit right with me. A canvas gadget inside the inner container which itself is inside the ScrollArea! API would be needed to ensure that the canvas gadget did not scroll with the inner-area and that would be messy. The whole point of this scrollable canvas is that the canvas does not physically move when a scroll is in effect; only it's contents scroll.

No it's pretty much incompatible with the way a ScrollArea functions. The ScrollArea is great at what it does, but it does not lend itself to insanely large 'documents' which is what I am after. :)
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Crossplatform scrollable Canvas Gadget

Post by srod »

Okay, I thought that approach would lead to too much flicker... I was wrong it seems! :)

However, that just switches an insanely large canvas for an insanely large inner container of the Scroll Area and that, under Windows, does not work. The limit is 32767 pixels width and height.

No, a ScrollArea is not suitable for insanely large documents and believe me, I've tried! Been there. :)
I may look like a mule, but I'm not a complete ass.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Crossplatform scrollable Canvas Gadget

Post by Trond »

I couldn't resist posting this:
Image
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Crossplatform scrollable Canvas Gadget

Post by srod »

:D
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Crossplatform scrollable Canvas Gadget (Win + OSX done)

Post by srod »

Update : 01/01/2012

Have completed the Windows and Mac OSX/Carbon versions and so I now have a fully functioning Scrollable Canvas gadget on these two platforms. I can thus create fully cross-platform (Linux excluded for the time being) custom controls built atop the canvas gadget with full scrolling etc. :)

Now, I am just wondering if anyone is interested in doing a Linux port? I did the OSX/Carbon one myself (with assistance from Freak and Shardik in getting started with the relevant Carbon api's etc.) but do not have the time to look into Linux. Truth be told, I have little interest in Linux; Windows and Mac OSX are my main concerns, but Linux would make the whole thing complete.

I cannot pay for a Linux port (because I do not deem it essential) but I can give the Windows / OSX versions to the author of a Linux port who can then subsequently create their own cross-platform custom controls etc.

To give interested parties some idea of what the work will involve, both Windows and OSX versions number some 700 or so lines of code. I myself started with absolutely no knowledge/experience of OSX/Carbon and, well, I only had to learn a few API's. I now have a basic understanding of the Carbon event manager etc, but that is all I needed and I have no reason to think that Linux will be any different in this regard. Some Linux/GTK guru could probably knock out a port within a few hours. :)

Any interested party is invited to contact me through pm or e-mail or through this thread etc.

Regards.

Stephen.
I may look like a mule, but I'm not a complete ass.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Crossplatform scrollable Canvas Gadget (Win + OSX done)

Post by Trond »

What is the reason it doesn't work without API on Linux? I thought scrolling events worked continously there.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Crossplatform scrollable Canvas Gadget (Win + OSX done)

Post by srod »

Trond wrote:What is the reason it doesn't work without API on Linux? I thought scrolling events worked continously there.
I have not really used PB on Linux and so cannot really commment. Can a PB event loop on Linux differentiate between the different scrolling actions such as line up, page up, scrollbox being dragged, scrollbox released and so on? If not, then it isn't really of much use to me and API will have to be used.

There is also the issue of embedding scrollbars in a 'container' control. Because of the way Windows operates as regards scrolling I decided against embedding scrollbar gadgets (for one thing, we cannot use a PB event loop anyhow to obtain the relevant scrolling notifications). On Windows, scrollbars are a simple matter of setting a couple of flags and that is the path I chose. I assumed it would be similar on OSX/Carbon, but I was wrong! On Carbon we have to embed scrollbar controls separately and so I had to take this path (NSViews might operate differently, but I didn't have time to delve into that). Again, PB scrollbar gadgets were of little use because they do not offer live-tracking and operate in a 'ghosting' mode instead. Hence rather more API was required on OSX than Windows because, for example, with embedded scrollbar controls (the ones which ghost anyhow) we have to perform all of the hit-testing and tracking manually which, is technically known, as a right royal pain in the arse! :wink: My scrolling canvas offers both live tracking and ghosting on both Windows and OSX.

If some Linux behemoth can port my code without using API then I will be very impressed. :) As I say though I know less about GTK than I do OSX/Carbon, and I know very little about OSX/Carbon!
I may look like a mule, but I'm not a complete ass.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Crossplatform scrollable Canvas Gadget (Win + OSX done)

Post by Trond »

Can a PB event loop on Linux differentiate between the different scrolling actions such as line up, page up, scrollbox being dragged, scrollbox released and so on?
I don't see why you need to know which is which, as long as you can set them to move the correct amount. The only part that I think requires API is to allow line scrolling by some X pixels when the arrow is clicked, while still allowing smooth scrolling 1 pixel at a time when dragging the thumb.

I'll reboot and check how the scrolling on Linux works in practice.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Crossplatform scrollable Canvas Gadget (Win + OSX done)

Post by srod »

Trond wrote:
Can a PB event loop on Linux differentiate between the different scrolling actions such as line up, page up, scrollbox being dragged, scrollbox released and so on?
I don't see why you need to know which is which, as long as you can set them to move the correct amount. The only part that I think requires API is to allow line scrolling by some X pixels when the arrow is clicked, while still allowing smooth scrolling 1 pixel at a time when dragging the thumb.

I'll reboot and check how the scrolling on Linux works in practice.
I have designed my scrolling canvas to provide notifications of line up/down, page up/down, live tracking and the rest. These are important for any serious use. Very few documents scroll by fixed amounts when say a scroll down button is clicked. Imagine a grid control for one; most grids will scroll by the exact amount required to bring the relevant row completely into view and this is dependent on the height of the row in question.

Both Windows and OSX/Carbon operate in the same way when a scroll down button is clicked in that they do nothing but provide a means of receiving the appropriate notifications. No attempt is made to actually perform any scrolling or to even move the scrollbar etc. This is down to the developer and rightly so because of the variable scroll amounts (mentioned above with the grid example) which most documents require. Windows and OSX differ in the ways they deal with live tracking however. My Scroller takes the Mac OSX/Carbon approach because it was simpler to get Windows to play ball than it was the other way around.

The point Trond is that my Scroller does not actually perform any scrolling itself. It provides all of the relevant notifications and exposes methods through which scrolling can be implemented, but it will not second guess the amounts by which the client app wishes to scroll. A fixed scroll amount is not appropriate for my uses because this is a completely different control than a ScrollArea for example. The uses to which a ScrollArea would typically be put make a fixed scroll amount ideal.

No, a full set of scroll notifications is a must. Anything else would be of little use to me. :)
I may look like a mule, but I'm not a complete ass.
freak
PureBasic Team
PureBasic Team
Posts: 5929
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Crossplatform scrollable Canvas Gadget (Win + OSX done)

Post by freak »

The following code shows the events you can get from a ScrollBar. You can stop the default handler from changing the value as a response to the event and move the bar yourself anyway you like.

Code: Select all

ProcedureC ChangeHandler(*Scrollbar, ScrollType, value.d, user_data)
  
  ; display the scroll event
  Select ScrollType
    Case #GTK_SCROLL_NONE: Debug "#GTK_SCROLL_NONE"
    Case #GTK_SCROLL_JUMP: Debug "#GTK_SCROLL_JUMP"
    Case #GTK_SCROLL_STEP_BACKWARD: Debug "#GTK_SCROLL_STEP_BACKWARD"
    Case #GTK_SCROLL_STEP_FORWARD: Debug "#GTK_SCROLL_STEP_FORWARD"
    Case #GTK_SCROLL_PAGE_BACKWARD: Debug "#GTK_SCROLL_PAGE_BACKWARD"
    Case #GTK_SCROLL_PAGE_FORWARD: Debug "#GTK_SCROLL_PAGE_FORWARD"
    Case #GTK_SCROLL_STEP_UP: Debug "#GTK_SCROLL_STEP_UP"
    Case #GTK_SCROLL_STEP_DOWN: Debug "#GTK_SCROLL_STEP_DOWN"
    Case #GTK_SCROLL_PAGE_UP: Debug "#GTK_SCROLL_PAGE_UP"
    Case #GTK_SCROLL_PAGE_DOWN: Debug "#GTK_SCROLL_PAGE_DOWN"
    Case #GTK_SCROLL_STEP_LEFT: Debug "#GTK_SCROLL_STEP_LEFT"
    Case #GTK_SCROLL_STEP_RIGHT: Debug "#GTK_SCROLL_STEP_RIGHT"
    Case #GTK_SCROLL_PAGE_LEFT: Debug "#GTK_SCROLL_PAGE_LEFT"
    Case #GTK_SCROLL_PAGE_RIGHT: Debug "#GTK_SCROLL_PAGE_RIGHT"
    Case #GTK_SCROLL_START: Debug "#GTK_SCROLL_START"
    Case #GTK_SCROLL_END: Debug "#GTK_SCROLL_END"
  EndSelect
  Debug value
  
  ; move scrollbar 1 step forward regardless of the event
  SetGadgetState(0, GetGadgetState(0)+1)
  
  ; return #true to stop default processing
  ProcedureReturn #True
EndProcedure
  
  
If OpenWindow(0, 0, 0, 305, 140, "ScrollBarGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ScrollBarGadget(0,  10, 42, 250,  20, 0, 100, 30)
  g_signal_connect_data_(GadgetID(0), @"change-value", @ChangeHandler(), 0, #Null, 0)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
quidquid Latine dictum sit altum videtur
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Crossplatform scrollable Canvas Gadget (Win + OSX done)

Post by srod »

Thanks Freak, could be very useful indeed. :)

Do GTK 'document' windows behave like OSX or Windows in terms of scrolling? What I mean is, is the business of adding scrollbars to a window/control as simple as setting a flag like #WS_HSCROLL (Windows) or do we need to embed separate scrollbar controls like OSX/Carbon?
I may look like a mule, but I'm not a complete ass.
Post Reply