Page 1 of 1
Getting data from a form
Posted: 19 Feb 2022 17:05
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.
Re: Getting data from a form
Posted: 24 Feb 2022 13:06
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).
Re: Getting data from a form
Posted: 24 Feb 2022 14:10
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.
Re: Getting data from a form
Posted: 24 Feb 2022 14:35
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()
Re: Getting data from a form
Posted: 24 Feb 2022 15:43
by Harrison Pratt
Much tidier!
Thanks.
Re: Getting data from a form
Posted: 24 Feb 2022 16:09
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.
Re: Getting data from a form
Posted: 24 Feb 2022 16:24
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.
Re: Getting data from a form
Posted: 25 Feb 2022 20:19
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
Re: Getting data from a form
Posted: 26 Feb 2022 16:14
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.
Re: Getting data from a form
Posted: 27 Feb 2022 4:54
by kingchris
I have downloaded your demo and will see if it is suitable.
Thank you.