Re: v15R5 bug?

2019-07-31 Thread Kirk Brooks via 4D_Tech
Jeremy,
Not a boring response at all and gives a good description of what you're
doing.

My first thought is that if you want to support both "classic 4D" listboxes
and modern, Form based listboxes from the same component you are going to
want to branch the code. As you are discovering attempting to use both
"modern" and "classic" 4D tools at the same time leads to various problems
with complicated workarounds. Especially in a situation like this where the
approach to managing what appears on the screen as a 'listbox' is a
completely different data structure depending on the way it's constructed.

Personally I've found the modern approach so. much. easier. I use a
fraction of the code I would have before. But I also commit to the listbox
(based on entity selection or collection) being "modern".

Working with classic listboxes is where I pull out pointer arrays,
selection sets, current row numbers, and all that jazz.

I have not had good results attempting to combine the two. Choose one or
the other: you're working on a Camero or you're working on a Tesla. Parts
for one just don't fit the other even when they are called the same thing.

Or perhaps a more germane quip would be a long time ago when I discovered
the very expensive Laserwriter I purchased couldn't be "upgraded" to the
new generation. "The only thing the two can both use is the power cord," my
rep explained.


On Wed, Jul 31, 2019 at 8:31 AM Jeremy Roussak via 4D_Tech <
4d_tech@lists.4d.com> wrote:

> Kirk,
>
> Thanks for your reply, which is interesting. This is what I’m doing. I
> wrote most of the code quite a while ago, before objects and before dynamic
> variables.
>
> I have a component to handle listboxes. Its methods can be used in three
> ways.
>
> 1. The box is fully set up in the Form editor. The component’s routines
> are used mainly to record, without any more code, changes in sort order,
> column width and column order.
>
> 2. The box is designed in the component’s designer but lives in one of the
> host’s forms. A single call sets up all the columns and deals also with
> everything in option 1.
>
> 3. The box is designed as in (2), but lives in a subform containing a form
> in the component. At the host level, all that’s necessary to set up the box
> is to assign the box’s name (set in the designer) to the subform’s variable.
>
> In the component, there’s a global array of objects in the form I
> described: {pointer to listbox; info object}. The info object holds column
> order, column widths, table/field IDs, column expressions and so on.
>
> When the host calls the component’s methods (which include querying,
> sorting, handling clicks and double-clicks and so on), it identifies the
> relevant box by passing a pointer as a parameter. The component can then
> locate the info object for that box by searching on the pointer. Using Find
> in array with matched arrays (one of pointers and one of info objects), it
> works very nicely, but of course the arrays need to be kept in sync. The
> advantage to the host programmer is that listbox pointers can be used to
> call the component’s methods in the same way as 4D’s listbox methods.
>
> Using the listbox variable name doesn’t work well when the box is on a
> host form because the component can’t see objects in the form; and it
> doesn’t work well when the box is in a subform, because they all have the
> same name. The advantage of pointers is that they are truly universal,
> usable in exactly the same way in host and component.
>
> I bore you with the details only because I feel your detailed post merited
> a detailed response.
>
> Jeremy
> **
> 4D Internet Users Group (4D iNUG)
> Archive:  http://lists.4d.com/archives.html
> Options: https://lists.4d.com/mailman/options/4d_tech
> Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
> **



-- 
Kirk Brooks
San Francisco, CA
===

What can be said, can be said clearly,
and what you can’t say, you should shut up about

*Wittgenstein and the Computer *
**
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**

Re: v15R5 bug?

2019-07-31 Thread Jeremy Roussak via 4D_Tech
Kirk,

Thanks for your reply, which is interesting. This is what I’m doing. I wrote 
most of the code quite a while ago, before objects and before dynamic variables.

I have a component to handle listboxes. Its methods can be used in three ways.

1. The box is fully set up in the Form editor. The component’s routines are 
used mainly to record, without any more code, changes in sort order, column 
width and column order.

2. The box is designed in the component’s designer but lives in one of the 
host’s forms. A single call sets up all the columns and deals also with 
everything in option 1.

3. The box is designed as in (2), but lives in a subform containing a form in 
the component. At the host level, all that’s necessary to set up the box is to 
assign the box’s name (set in the designer) to the subform’s variable.

In the component, there’s a global array of objects in the form I described: 
{pointer to listbox; info object}. The info object holds column order, column 
widths, table/field IDs, column expressions and so on.

When the host calls the component’s methods (which include querying, sorting, 
handling clicks and double-clicks and so on), it identifies the relevant box by 
passing a pointer as a parameter. The component can then locate the info object 
for that box by searching on the pointer. Using Find in array with matched 
arrays (one of pointers and one of info objects), it works very nicely, but of 
course the arrays need to be kept in sync. The advantage to the host programmer 
is that listbox pointers can be used to call the component’s methods in the 
same way as 4D’s listbox methods.

Using the listbox variable name doesn’t work well when the box is on a host 
form because the component can’t see objects in the form; and it doesn’t work 
well when the box is in a subform, because they all have the same name. The 
advantage of pointers is that they are truly universal, usable in exactly the 
same way in host and component.

I bore you with the details only because I feel your detailed post merited a 
detailed response. 

Jeremy
**
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**

Re: v15R5 bug?

2019-07-28 Thread Kirk Brooks via 4D_Tech
Hey Jeremy,
A couple of thoughts:

On Sun, Jul 28, 2019 at 9:20 AM Jeremy Roussak via 4D_Tech <
4d_tech@lists.4d.com> wrote:

> I have a collection objects, each of which has a pointer to a variable and
> an associated object:
>
You don't need to use a pointer in the collection. It sounds like what you
want is for that value, in the collection, to be dynamic and to be able to
query on it and find different results as other things have changed. So
what you need to do is design things so that whatever is now a pointer is
itself a reference.

"list" could be any number of things but I bet it could be represented as a
collection. At which point it becomes much easier for you to work with
directly rather than having to dereference what ever that is.


> I want to find the item in the collection from the pointer, which is in
> $ptr
> $boxes:=<>boxes.query(“lb = :1”;$ptr)
>
This might work if $ptr is pointing to a var and you dereference $ptr. But
it's not clear if $ptr is an actual pointer or not.


> Is searching for pointers not allowed?
>
Using ORDA I don't think so.
Using these new data structures, collections, objects, entities and such,
works most effectively when you work with them using references. Within
that context a reference is similar to a pointer but more powerful and
easier to use. Pointers are for working with variables, fields and tables.
It's a different structure from ORDA. You have to rethink how you go about
doing some things. Especially when working with forms and familiar objects
like listboxes. But it's what we have to do. I can tell you from personal
experience over the past year or so the payoff is pretty good. These new
abilities are great.

If you find yourself trying to figure out how to use pointers when you're
doing something with an object, collection or entity you are on the wrong
path. Take a step back and figure out how to accomplish your goals using
references.

You know since Form I rarely use pointers for anything except buttons. Why?
Because it's easier to simply put those objects in the Form object and
reference them.
Input fields: you need to recognize the On data change event but from there
I just work with whatever the value in Form.thisField is.
Listboxes: the only place I've made a listbox with an array is in v15
projects I'm still working on. Otherwise they are either collections or
entity selections. Once more there is nothing I need a pointer to - the
components of them are referenced in Form and easy to work with from there.

Speaking of them, your example suggests to me you are working out a way to
have several different 'boxes' in an array, perhaps with the intent of
making it easy for the user to switch between them? Great idea. I might do
something like:

$lb_obj:=New object("name";"my name";"data"; )

as the object. And instead of an IP var consider using a process variable.
To accommodate multiple windows you use DIALOG(*). You can have many
independent windows in a single method. I'm starting to have a single UI
process where all the windows the user interacts with exist. Coupled with
CALL FORM it's very easy to support this.

Finally, keep in mind that when we create a reference to something we
aren't duplicating it. This is where the similarity to pointers is similar.

$obj:=new object(with a bunch of data)

And then I include this in a collection:

processColl.push($obj)


There is still only 1 instance of $obj. If I then do

$otherColl.push(processColl[0])

$myColl.push(processColl[0])

it's the same thing. There's only one instance of $obj and now 3 references
to it, one in a process variable and 2 in locals (these could be on forms).
So thinking about a form for a moment let's say I put $myColl into
Form.myColl. Now I can reference the values of $obj on my form with

Form.myColl[0].someProperty

which in this example is equivalent to

processColl[0].someProperty

And if the user makes some change on the form those changes are reflected
in all the instances. This is a pretty simple example and you could pretty
easily accomplish the same functionality using pointers. You would need a
lot more code to do it but really I just wanted to try to highlight the
differences in the way you think about the data.



-- 
Kirk Brooks
San Francisco, CA
===

What can be said, can be said clearly,
and what you can’t say, you should shut up about

*Wittgenstein and the Computer *
**
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**

Re: v15R5 bug?

2019-07-28 Thread Jeremy Roussak via 4D_Tech
Typo: the .push line should push “info”; $info, of course.

And I’ve no idea where the > came from - 
it’s not in the message I sent.

Jeremy

> On 28 Jul 2019, at 17:20, Jeremy Roussak  wrote:
> 
> I hope this is a more sensible query than my last one!
> 
> I have a collection objects, each of which has a pointer to a variable and an 
> associated object:
> 
>   <>boxes.push(new object(“lb”; ->list; “box”; $info))
> 
> I want to find the item in the collection from the pointer, which is in $ptr
> 
>   $boxes:=<>boxes.query(“lb = :1”;$ptr)
> 
> When I run this, 4d crashes instantly on the query line. If I put a trace 
> just before that line, I can see that <>boxes contains only one item, which 
> is an object whose lb is the same as $ptr (it’s given in the debugger as 
> “->form_9_1C”). 
> 
> If I code it as
> 
>   for each ($box; <>boxes)
>   if ($box.lb = $ptr)
>   $result:=$box.info 
>   end if
>   end for each
> 
> It works fine.
> 
> Is searching for pointers not allowed?
> 
> Jeremy

**
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**

v15R5 bug?

2019-07-28 Thread Jeremy Roussak via 4D_Tech
I hope this is a more sensible query than my last one!

I have a collection objects, each of which has a pointer to a variable and an 
associated object:

<>boxes.push(new object(“lb”; ->list; “box”; $info))

I want to find the item in the collection from the pointer, which is in $ptr

$boxes:=<>boxes.query(“lb = :1”;$ptr)

When I run this, 4d crashes instantly on the query line. If I put a trace just 
before that line, I can see that <>boxes contains only one item, which is an 
object whose lb is the same as $ptr (it’s given in the debugger as 
“->form_9_1C”). 

If I code it as

for each ($box; <>boxes)
if ($box.lb = $ptr)
$result:=$box.info 
end if
end for each

It works fine.

Is searching for pointers not allowed?

Jeremy
**
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**