Painting a Point // Declare Problem

I am think I am doing something pretty basic - but I am missing something. Within iOS, I want to the user to click anywhere on the screen and then a little disk (filled oval) appears at that position.

So I created a module, with a property “Clicked” (boolean). When the Pointer is down, this is changed to true, and when it the Pointer is up, this is false.

Within the Paint method for the canvas, I have something like
if modClick.Clicked
i = Xojo.Math.Round( ClickPoint.X ) //****
j = Xojo.Math.Round( ClickPoint.Y )
g.FillOval( i, j, 100, 100 )

Then in the OPEN method of the canvas I put
Dim ClickPoint As New Xojo.Core.Point( 0, 0)

However, when I run my program, the statement above //**** gets a nil object exception. And in fact, it gets this if I comment out that Dim statement too.

So apparently I am missing something basic and fundamental. Any ideas?

Clickpoint has a scope limited to the OPEN event. ie. once the Open Event is completed, ClickPoint is no longer valid
it needs to be defined at a higher scope… relative to the Canvas, not to a specific event of the canvas

I forgot to mention, that in the PointerDown action, I also store the point
modClick.ClickPoint = pos
So that I have global access to that clicked point

Thanks. I put the DIM statement in the APP OPEN and I get the same error

are you sure you do not have more than ONE DIM for a variable with that name…
otherwise you are creating multiple instances in different scopes

I did a search, and ClickPoint is only defined in the App open - although its listed as a property in a module. But I seem to recall that it has to be explicitly dimensioned, even when listed as a property.

Maybe the problem is with how I am using a point. This seems to fly :

dim XXX as point
XXX = Clickpoint

but then if I do
i = Clickpoint.X

I get an exception on that.

I made sure that the scope of Clickpoint is Global. I keep getting a "nil object’ exception on the line i = clickpoint.x

I also tried : i = Xojo.Math.Round( ClickPoint.X )
and still get this error.

If the object is NIL then it was never instantiated (ie… the NEW statement was never applied to it)

I went into the debugger, and it does create the point (“click point”) in the app’s OPEN method, but within the object it remains nil.

Where can I or should I create this point? It doesn’t get created in the open for the canvas either. If I instead write

Dim ClickMod.ClickPoint As New Xojo.Core.Point(0, 0)

then I get compiler errors right off the bat.

So I am hopelessly confused as to how this is supposed to work, despite it being a simple and fundamental thing.

The REFERENCE to the object must NOT be inside any method or event… (ie. the command the creates or DIM’s it)
otherwise the Scope is limited to that location

Is it possible that you have a ClickPoint property in your object, but in the open event you do something like Dim C as new Clickpoint(0,0)?
In that case you would have created a temporary variable only instead of initializing the object’s property.
Another chance would be that the object you are referring to gets out of scope.

It would otherwise help to see more of your code. Currently it is very unclear what properties and variables exist – and where.

This is exactly what I suspect, I guess I did a lousy job of trying to explain the fundementals of scope :frowning:

Well how should this be done? I just want to capture the “mouse click” point which is delivered to the PointerUp action, so that when the PAINT event fires, it knows that point. The way I thought to do it was to create a global static point variable within a module, which would hold the point information. But then I need to DIM it somewhere - either in a method or an action - and it does not make sense to dimension it every time the PAINT event fires, nor should it be local to PointerUp. So this seems pretty basic.

Should I make a special Canvas with a point property or something?

No, if you have an object as a module property, you don’t need to Dim it. Reserving memory space ( = Dim) is done by the existence of the property in the module implicitly.

You have to initialize it anyway. That’s why the code should be like

(ModuleName).ClickPoint = New Xojo.Core.Point(0,0)

Dimming in this case would mean you created a local temporary variable with the same name as the module’s property like Dave and I suspected.

Thanks. But where does that code go (your dimension)? I tried exactly what you did in the App>Open, and in a module method called by the Canvas>Open. In both cases I got compiler errors that I was trying to declare a local variable in some other way.

In this case I would recommend to put the code like above into the Canvas’ Open event. This way you can be sure the property will be initialized before the first draw event.

You could also avoid the clicked property if you change your drawing code and include it in a

If (ModuleName).ClickPoint <> Nil then // your drawing code here End If

Then in PointerDown

(ModuleName).ClickPoint = New Xojo.Core.Point(x,y)

and in PointerUp

(ModuleName).ClickPoint = Nil

The reason you are having problems with the compiler could be the scope of ClickPoint in your module.
If it happens to be Global, it acts as a Global Property and is available anywhere in you project by just its name.
With a scope set to protected, you have to qualify its namespace fully (include the module name).
If it should be private, you cannot change the property from outside the module.

Thank you. I need to digest this a bit.