Page 1 of 2

Create User Control

Posted: 31 Mar 2014 15:18
by Eftychios
Hello,

I'm trying to make a minesweeper and i would like to ask you if I can create a new user control (Button in my case) with specific properties.

So on load form i'll be able to use a recursive function to print 81 buttons instead of add 81 buttons.

Is there a way to make this ??

Kind regards

Posted: 2 Apr 2014 8:01
by Thomas Linder Puls
I am not quite sure what it is you want (in several ways).

1.
  • Should the control act as 1 button?
  • Or should it be a 81 button control?
2.
  • Do you want to rely on the standard button?
  • Or do you want to do the drawing and mouse handling yourself?

Posted: 3 Apr 2014 0:48
by Eftychios
Hello, thank you for the response.

Actually i'm working on it in other way, what i want to make is a form with 81 buttons in a form (9 rows and 9 columns).
What i want to do is:

1) To give to each button coordinates, for example 1.1, 1.2, 1.3 ... 2.1, 2.2, 2.3
so when i want to get the value of button in position 1.1 to have a function like value(X,Y)
The question here is how can i add that kind of label(cooordinates(X,Y)) for a button ???

What i want to achieve with this is that when i press a button with coordinates 3.3 to check all it's neighbours.

For example, neigbours of 3.3 = 2.2, 2.3, 2.4, 3.2, 3.4, 4.2, 4.3, 4.4.

2) The second question is if there is any random function in Visual Prolog ?? Because i want everytime to have random position for the mines (which will be in the buttons propably as a label)

Thank you in advance for your help

Posted: 3 Apr 2014 9:28
by Thomas Linder Puls
OK, now it is getting clearer.

I think you could make a faily good minesweeper look and feel if you draw the board with all the numbers and mines, and then place buttons on the top.

When the user presses a button you will simply destroy the button and do the relevant action (which may include updating the board drawing to indicate a lost game).

Alternatively, you can replace pressed buttons with an image (of fields with nothing/a number/a mine/...), using image control.

Anyways, to place the buttons you can use code like this (in a form):

Code: Select all

constants     columns = 9.     rows = 9.     size = 10. clauses     new(Parent):-         formWindow::new(Parent),         generatedInitialize(),         foreach Row = std::cIterate(rows), Column = std::cIterate(columns) do             Button = button::new(This),             placeInGrid(Button, Row, Column),             Button:setClickResponder({ = button::noAction :- onClick(Button, Row, Column) })         end foreach.   predicates     onClick : (button Button, positive Row, positive Column). clauses     onClick(Button, Row, Column) :-         Button:destroy(),         Text = textControl::new(This),         placeInGrid(Text, Row, Column),         Text:setAlignment(vpiDomains::alignCenter),         Text:setText("x"),         Text:show(),         stdio::writef("(%, %)\n", Row, Column).   predicates     placeInGrid : (control Control, positive Row, positive Column). clauses     placeInGrid(Control, Row, Column) :-         Control:setPosition(Column*size, Row*size),         Control:setSize(size, size).

Posted: 3 Apr 2014 9:51
by Thomas Linder Puls
Here is a slightly updated version, that stores the buttons in a map, so that they can also be removed without being clicked (for example to reveal the solution in the end):

Code: Select all

facts     buttons : mapM{tuple{positive Row, positive Column}, button Button} := mapM_redBlack::new().   constants     columns = 9.     rows = 9.     size = 10. clauses     new(Parent):-         formWindow::new(Parent),         generatedInitialize(),         foreach Row = std::cIterate(rows), Column = std::cIterate(columns) do             Button = button::new(This),             placeInGrid(Button, Row, Column),             Button:setClickResponder({ = button::noAction :- onClick(Row, Column) }),             buttons:set(tuple(Row, Column), Button)         end foreach.   predicates     onClick : (positive Row, positive Column). clauses     onClick(Row, Column) :-         Field = tuple(Row, Column),         Button = buttons:get(Field),         buttons:removeKey(Field),         Button:destroy(),         Text = textControl::new(This),         placeInGrid(Text, Row, Column),         Text:setAlignment(vpiDomains::alignCenter),         Text:setText("x"),         Text:show(),         stdio::writef("(%, %)\n", Row, Column).   predicates     placeInGrid : (control Control, positive Row, positive Column). clauses     placeInGrid(Control, Row, Column) :-         Control:setPosition(Column*size, Row*size),         Control:setSize(size, size).

Posted: 3 Apr 2014 14:34
by Eftychios
Thank you very much for your help, your time and the great communication.

I'll try the solutions you proposed.

Again cheers.

Posted: 5 Apr 2014 8:33
by Eftychios
Hello again,

I have tried this with the followin way but seems that i miss something.

1) I have created a new project. I have added a new in package -> Form

2) then task menu -> unchecked F7 disabled

3) then id_file_new -> onFileNew add

4) clauses
onFileNew(_Source, _MenuTag):-
_= mines::display(This).
so i can displa the form

and then I inserted the proposed code in my project and i get the following error:
"undeclared predicate, propert or fact 'new/1'"

Till step 4 this is the right way to follow ??? I have to make new window form and then insert the code for the button creation?

Posted: 5 Apr 2014 12:51
by Thomas Linder Puls
It sounds correct a form should have a constructor, new, with a Parent argument.

ignore

Posted: 5 Apr 2014 16:02
by Eftychios
'
l

Posted: 5 Apr 2014 22:23
by Thomas Linder Puls
The code should go into your form not into the taskWindow.

Posted: 6 Apr 2014 7:57
by Eftychios
Thank you very much ...

Works like a charm now.

Thanks also for the imediate replies.

You were very helpful.

Kind Regards

Posted: 8 Apr 2014 11:51
by Eftychios
Dear Thomas i have made a very nice program with your help.

At clause new(Parent) i have placed the for each loop to create buttons at rows and columns.

I have added to my window form 2 textboxes (for rows and col) and 1 button.

1) i want when i press the button to clear the form from the existing buttons

2) and then call the new(Parent) where i have the for each loop that creates the buttons

I have copied the for each loop into the onclick clause but nothing happened when i pressed the button

Posted: 14 May 2014 10:21
by Snejanna
Hello!
I want to create the same game on prolog and have faced a problem.
In your code there is:

Code: Select all

Button:setClickResponder({ = button::noAction :- onClick(Row, Column) }),
but how can I make a responder for right mouse click?
Thank you.

Posted: 14 May 2014 14:54
by Thomas Linder Puls
Standard buttons does not have a behavior on right-mouse clicks.

But you can add mouse a mouse listener:

Code: Select all

        Button:addMouseDownListener(onButtonMouseDown),
Simple code looks like this:

Code: Select all

predicates     onButtonMouseDown : window::mouseDownListener. clauses     onButtonMouseDown(_Source, Point, ShiftControlAlt, Button) :-         stdio::writef("Point = %, ShiftControlAlt = %, Button = %\n", Point, ShiftControlAlt, Button).

Posted: 21 May 2014 8:12
by Snejanna
Thank you very much!