Discussions related to Visual Prolog
kingchris
Active Member
Posts: 28
Joined: 26 Sep 2005 9:35

Getting data from a form

Unread post by kingchris »

Using the IDE I have created a form that has 7 text boxes to ask the user for 7 integers.

Using a single fact like numbers(integer,integer,integer,integer,integer,integer,integer) where do I place this fact in my GUI program so that my form on exit can set it and then I can read this numbers fact from many places in my program. Like a global fact/variable.

I have never quite grasped how say TaskWindow.pro can instance a Form/Dialog box which can call some global class to save the data obtained in the Form/Dialog.

In Visual Prolog you can inherit and open classes in the cl file type.
Perhaps there is an online article I could review.
User avatar
Thomas Linder Puls
VIP Member
Posts: 1428
Joined: 28 Feb 2000 0:01

Re: Getting data from a form

Unread post by Thomas Linder Puls »

There is no such thing as global facts.

But you can assert things in a class facts and provide predicates which can set/get the values from there.

Properties and facts implements that in a simple way:

Code: Select all

class globalStore   properties         v1 : integer.         ...         v7 : integer. ... end class globalStore   implement globalStore   class facts     v1 : integer := 0. % could be erroneous instead     ...     v7 : integer := erroneous. % could be a default value instead   end implement globalStore
In your form you will set the properties:

Code: Select all

clauses     save() :-         globalStore::v1 := % obtain v1         ...         globalStore::v7 := % obtain v7
Notice that opening two forms which both manipulates the same global data simultaneously is confusing and should be avoided (= made impossible by the program).
Regards Thomas Linder Puls
PDC
Harrison Pratt
VIP Member
Posts: 452
Joined: 5 Nov 2000 0:01

Re: Getting data from a form

Unread post by Harrison Pratt »

Sometimes it is preferable to use forms and dialog as "action items" that "do" things with their various values and other times you want to return a value.

When I want a dialog to return a value to be used in the predicate calling that dialog I modify the dialog creation to return that value (or values) like this:

Code: Select all

class returnIntegers : returnIntegers     open core predicates %    display : (window Parent) -> returnIntegers Dialog.     display : (window Parent) -> integer* determ. % FAIL if click [Cancel] in the dialog constructors     new : (window Parent). end class returnIntegers
You will need to modify the display/1 predicate and create a class fact in the dialog to hold the return value. There is no reason why you cannot return your 7 integers instead of the integer_list I used for this demonstration.

Code: Select all

class facts     intList : integer* := erroneous. % HOWTO   clauses %    display(Parent) = Dialog :- %        Dialog = new(Parent), %        Dialog:show().     display(Parent) = intList :-         % class facts persist after the dialog closes         % so you must reset them to 'erroneous' if you don't want them to persist         intList := erroneous,         %         Dialog = new(Parent),         Dialog:show(),         not(isErroneous(intList)). % FAILS here if onOkClick/1 has not asserted any values
When you click [OK] your code should put the values into the class fact. Closing the dialog any other way will leave intList as erroneous and the dialog will fail.

Code: Select all

predicates     onOkClick : button::clickResponder. clauses     onOkClick(_Source) = button::defaultAction :-         % HOWTO         A = integerControl_ctl_A:getInteger(),         B = integerControl_ctl_B:getInteger(),         intList := [A, B].
A demo project is attached.
Attachments
vipDialogReturnValues.zip
(21.33 KiB) Downloaded 340 times
User avatar
Thomas Linder Puls
VIP Member
Posts: 1428
Joined: 28 Feb 2000 0:01

Re: Getting data from a form

Unread post by Thomas Linder Puls »

I will recommend using an object fact for the "transfer".

We will need external access to the result (even though we will only access it internally):

Code: Select all

interface returnIntegers ... ... predicates     tryGetResult : () -> integer* Result determ. ... end interface returnIntegers
In the implementation we will change the fact to an object fact, implement the tryGetREsult predicate and use that in the display predicate:

Code: Select all

implement ...   facts     intList : integer* := erroneous.   clauses     tryGetResult() = notErroneous(intList).   clauses     display(Parent) = Dialog:tryGetResult() :-         Dialog = new(Parent),         Dialog:show()
Regards Thomas Linder Puls
PDC
Harrison Pratt
VIP Member
Posts: 452
Joined: 5 Nov 2000 0:01

Re: Getting data from a form

Unread post by Harrison Pratt »

Much tidier! :D
Thanks.
kingchris
Active Member
Posts: 28
Joined: 26 Sep 2005 9:35

Re: Getting data from a form

Unread post by kingchris »

Thank you both for your suggestions. I did build a class with class facts and predicates to hold the global integers then provide extra class predicates to set()/get() those globals for use in the program.

I like the Form/Dialog returing the values. This is a clean and an elegant solution. I will probably change
my little app to do that but then still send the results to the global class as there are too many places in my program that needs the results or bits of the results.

Again. Thank you.
User avatar
Thomas Linder Puls
VIP Member
Posts: 1428
Joined: 28 Feb 2000 0:01

Re: Getting data from a form

Unread post by Thomas Linder Puls »

I don't know what your 7 integers represents/are used for. But if we consider them to be "settings", then you could also consider to create a settings class with setting objects:

Code: Select all

interface settings properties     setting1 : integer.     ...     setting7 : integer. end interface settings
With a trivial corresponding class and implementation:

Code: Select all

class settings : settings end class settings   implement settings facts     setting1 : integer := 0. % could also be erroneous     ....     setting7 : integer := erroneous. % could also have a default value end implement settings
Your form could either create such an object (instead of the intList) and return it like above. Or you could create it before invoking the form and pass it as a input argument. Whether you will store the object somewhere globally or pass it around is up to you.

But when having it in an object you can also pass it to constructors of other objects and store it in an object fact there. And in such code you can access it everywhere even though it is not really global, it is kind of local-global.
Regards Thomas Linder Puls
PDC
User avatar
Gukalov
VIP Member
Posts: 68
Joined: 5 Oct 2011 15:16

Re: Getting data from a form

Unread post by Gukalov »

VarM sometimes is good to keep settings.
Pass it to the form as an input argument, as advised above.
The change (only the change) of VarM:value (setting/s) invokes modified listeners,
added by the necessity ( VarM:modified:addListener(doWhenSettingsChanged) )
Thank you VIP for the varM :-)
Harrison Pratt
VIP Member
Posts: 452
Joined: 5 Nov 2000 0:01

Re: Getting data from a form

Unread post by Harrison Pratt »

I find that inheritance is the easiest way to handle application settings.

Create a settings database class that creates objects then you can access any predicates (or properties) that you define in the interface (.i) file. It works best if you plan for settings of various types (e.g., strings, reals, integers) up front.

Here is a tiny demonstration project to show how simple that can be. In the projectSettingsDemo project you will see that it is actually unnecessary to use the appString/2 facts since strings can be easily handled with the appValue/2 facts.
Attachments
projecSettingsDemo.zip
(22.74 KiB) Downloaded 341 times
kingchris
Active Member
Posts: 28
Joined: 26 Sep 2005 9:35

Re: Getting data from a form

Unread post by kingchris »

I have downloaded your demo and will see if it is suitable.

Thank you.
Post Reply