Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 10:32 19 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : GUI controls

     Page 1 of 2    
Author Message
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1805
Posted: 01:47pm 27 Jan 2017
Copy link to clipboard 
Print this post

Hi All,
MM Ver 5.3 SSD1963
If I have a variable in a program and I want to enter a number into it from the screen, how do I do it. Do I use NUMBOX. Geoff has done an excellent job on the manuals
but, and I think it was mentioned before, Newbies and old dummies like myself need examples. For example I don't understand the significance of the #ref. I know it is giving the control a number but how is it used. Some of the commands have examples and some are self explanatory but examples for the GUI controls would be very helpful, to me at least. I had a look at Geoff's Boat Computer code to see how it enters values from the screen but did not understand.
Paul.

"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5923
Posted: 02:15pm 27 Jan 2017
Copy link to clipboard 
Print this post

This is a cut down version of the example code in the MM+ manual.
  Quote  
OPTION EXPLICIT

COLOUR RGB(WHITE), RGB(BLACK)
' reference numbers for the controls are defined as constants
CONST numEntry = 1
DIM x AS INTEGER
CLS
GUI INTERRUPT TouchDown, TouchUp

GUI NUMBERBOX numEntry, 50,40,90,40,RGB(YELLOW),RGB(64,64,64)

' All the controls have been defined and displayed. At this point
' the program could do some real work but because this is just a
' demo there is nothing to do. So it just sits in a loop.
DO : LOOP
' the interrupt routine for touch down
' using a select case command it has a different process for each
' control
SUB TouchDown
SELECT CASE TOUCH(REF) ' find out the control touched
CASE numEntry
PRINT "entering a number"

END SELECT
END SUB
' interrupt routine when the touch is removed
SUB TouchUp
SELECT CASE TOUCH(LASTREF) ' use the last reference
CASE numEntry ' was it the numEntry box
x = CTRLVAL(numEntry)
PRINT x
END SELECT
END SUB


I have avoided using the new command MM.KEYPRESS because it seems to have a problem.

#ref is a unique number for each control. I think you can have up to 99 controls so give them meaningful names.
With a numbox, the touchdown sub is run whenever you first press on the number box and the keypad appears. Not a lot of use normally.
The sub touchup is more usefull. It is run when you press the enter key on the keypad and the keypad closes.
The line x = CTRLVAL(numEntry) retrieves the value that the user has entered.

Jim

VK7JH
MMedit   MMBasic Help
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1805
Posted: 02:59pm 27 Jan 2017
Copy link to clipboard 
Print this post

Thanks Jim I will have a practice with that and see how I go.
Paul
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9082
Posted: 03:31pm 27 Jan 2017
Copy link to clipboard 
Print this post

From version 5.3 of MMBASIC, you can define as many GUI controls as you want, with the tradeoff being that each extra control takes up a little memory - even if you never end up using it. However, you can pick whatever number of controls suits your project.

Paul - I was totally lost with the GUI control use and syntax when Geoff first introduced it, but it DOES start to make good sense after you have played with them for a little while.

THERE IS AN EXCELLENT TUTORIAL ON GUI PROGRAMMING AND TECHNIQUE STARTING FROM PAGE 29 OF THE ADVANCED MANUAL. Anyone playing with GUI controls is advised to read this section as many times as you have to, till you understand it, cos it really is at the core of being able to create trouble-free GUI stuff. My 2c, anyway. I did try to do it "My way", and it was a disaster, so this section really is in the manual for a reason, and it will make your GUI programming experience much easier in the long run.Edited by Grogster 2017-01-29
Smoke makes things work. When the smoke gets out, it stops!
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1805
Posted: 04:50pm 27 Jan 2017
Copy link to clipboard 
Print this post

Thanks Grogster,
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1805
Posted: 09:54pm 27 Jan 2017
Copy link to clipboard 
Print this post

Got my head around NUMBERBOX, now another question
With the GUI controls is it possible to change the size of the text
for example :
  Quote  GUI BUTTON #ref, caption$, StartX, StartY, Width, Height, FColour, BColour

The size of the button can be defined but what about Caption$.
I tried with GUI FRAME, I drew a fairly large frame but the text was extremely small.
Or should I be using the BASIC DRAWING COMMANDS if I want a box with large text.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9082
Posted: 10:24pm 27 Jan 2017
Copy link to clipboard 
Print this post

Use FONT just before you create the control - it will use whatever is currently set.

I have buttons setup with different size captions, and I do it just by selecting the font and size you want as the line BEFORE you issue the command for the GUI control.

Such as:




Smoke makes things work. When the smoke gets out, it stops!
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1805
Posted: 12:39am 28 Jan 2017
Copy link to clipboard 
Print this post

Thanks again Grogster, what would we do without TBS.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1805
Posted: 11:57am 28 Jan 2017
Copy link to clipboard 
Print this post

ME again,
Using a DISPLAYBOX and CtrVal(r) to enter text into the box.
It seems there is a limit to the number of characters you can display.
Depending on the number of lines I can only get 16 or 17 characters in the box.
Is this correct.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1805
Posted: 12:06pm 05 Feb 2017
Copy link to clipboard 
Print this post

Still having trouble with GUI NUMBERBOX. I have used the code supplied by Jim (above). If I use the code stand alone it works OK but when I include it in my code I get an error
  Quote  GUI NUMBERBOX AFLscore, 50,40,90,40,RGB(YELLOW),RGB(64,64,64)

  Quote  GUI reference number #1 is in use

I have used the GUI NUMBERBOX control twice both with different ref. nos. and I get the error with both. I tried changing the reference no. to no avail.
Paul.

Edit.
I am also using GUI BUTTONS could they be interferring with the Interrupt Touch.Edited by palcal 2017-02-06
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5923
Posted: 01:23pm 05 Feb 2017
Copy link to clipboard 
Print this post

Each GUI elememt must have a unique reference number.
Somewhere in your code you have AFLscore = 1
Another GUI element was also given the reference number 1, either by using AFLscore or by defining another constant with a value of one.

You would also get the error if you defined the element in a sub and called the sub more than once.

Not easy without the full code to look at.

Jim


VK7JH
MMedit   MMBasic Help
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1805
Posted: 01:53pm 05 Feb 2017
Copy link to clipboard 
Print this post

All elements defined at the start of the code with unique numbers.
The only place in the code where AFLscore = 1 is in the CONST at the begining of the code where the reference number is defined.
I will keep looking.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1805
Posted: 04:03pm 05 Feb 2017
Copy link to clipboard 
Print this post

I think I may be getting somewhere. All my GUI controls are doing the same thing.
If I have used GUI BUTTON 5 and then later on return to use it again I get the same error that it is already in use.
I'm obviously doing something wrong.
Paul.

Edit.
I notice that in the MM Plus manual on the bottom of page 40 Geoff has used the Command GUI Restore but I can find no reference to it anywhere.
Paul.Edited by palcal 2017-02-07
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5923
Posted: 05:38pm 05 Feb 2017
Copy link to clipboard 
Print this post

In the MM+ manual

Advanced graphics/interacting with controls.
The ones you need to study are
  Quote   GUI DISABLE #ref1 [, #ref2, #ref3, etc]
This will disable the controls in the list. Disabled controls do not respond to touch and will be displayed
dimmed. The keyword ALL can be used as the argument and that will disable all controls. For example:
GUI DISABLE ALL
 GUI ENABLE #ref1 [, #ref2, #ref3, etc]
This will undo the effects of GUI DISABLE and restore the controls in the list to normal operation. The
keyword ALL can be used as the argument for all controls.
Micromite Plus Addendum Page 28
 GUI HIDE #ref1 [, #ref2, #ref3, etc]
This will hide the controls in the list. Hidden controls will not respond to touch and will be replaced on the
screen with the current background colour. The keyword ALL can be used as the argument.
 GUI SHOW #ref1 [, #ref2, #ref3, etc]
This will undo the effects of GUI HIDE and restore the controls in the list to being visible and capable of
normal operation. The keyword ALL can be used as the argument for all controls.
 GUI DELETE #ref1 [, #ref2, #ref3, etc]
This will delete the controls in the list. This includes removing the image of the control from the screen
using the current background colour and freeing the memory used by the control. The keyword ALL can
be used as the argument and that will cause all controls to be deleted.


Jim
VK7JH
MMedit   MMBasic Help
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9082
Posted: 08:45am 06 Feb 2017
Copy link to clipboard 
Print this post

  palcal said  If I have used GUI BUTTON 5 and then later on return to use it again I get the same error that it is already in use.
I'm obviously doing something wrong.
Paul.


Once you define your GUI controls(usually at the start of your program), you only ever need to refer to it's CTRLVAL again in the rest of your code.

If you are getting a message like that(Control already in use), then you are trying to re-define the same control somewhere else in your program, having already defined it once somewhere else.

As Jim says, you need to look at the GUI SHOW/GUI HIDE commands, which will show and hide your button depending on when you want it. The other useful thing, is to have the button as part of a GUI page, and then you just show ALL controls you want on any one screen via the PAGE command - see page 33 of the advanced manual under 'Multiple Screens'.
Smoke makes things work. When the smoke gets out, it stops!
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1805
Posted: 10:21am 06 Feb 2017
Copy link to clipboard 
Print this post

Thanks Jim and Grogster.
My buttons are only defined once at the start of the program.
They only appear on screen when needed.
I am re writing the code to use SELECT CASE for all controls.
I will let you know what happens.
Paul.Edited by palcal 2017-02-07
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9082
Posted: 05:00pm 06 Feb 2017
Copy link to clipboard 
Print this post

Hang in there, Paul.

GUI programming can be a rather different kettle of fish to that of non-GUI stuff.
Interrupts are your friends, but you do have to get your head around using them right, but once you have that sorted, you will start to develop code in your head.

SELECT CASE really is the best way to deal with buttons, I would have to say.
Just SELECT CASE, and set flags, then exit the interrupt - don't hang around in the interrupt doing things. When the interrupt returns to the main code, IT can examine the flags and decide what to do at that point.
Smoke makes things work. When the smoke gets out, it stops!
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1805
Posted: 06:41pm 06 Feb 2017
Copy link to clipboard 
Print this post

Hi Grogs,
Ok I don't seem to have the previous error. I am using GUI INTERRUPT to branch to a Defined SUB and set a DO-LOOP with a flag to wait until it returns. The first button touched works OK then the screen clears and another button appears on the bottom of the next screen but this button won't do anything. I have used the trace function and absolutely nothing happens when I touch the button. It seems as though the INTERRUPT is not there.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 844
Posted: 07:53pm 06 Feb 2017
Copy link to clipboard 
Print this post

Hi Paul,
I think you might be still in the interrupt routine. Until you return (END SUB) from the TouchDown SUB, no other interrupt can be serviced. The main loop also cannot run. This is why everyone is saying keep them short. Its not necessarily the number of instructions, but the time they take. I have updated Jims's example to show the PRINT statements moved back to the main loop and triggered by flags that are set in the TouchDown SUB. PRINT statements in the TouchDown are normally OK because they run in the background anyway and don't hold up the TouchDown SUB.
Hopefully this shows how to set flags in the TouchDown SUB and action them in the main DO ....LOOP and then clear the flags for next time.

Regards
Gerry



  Quote  
OPTION EXPLICIT

COLOUR RGB(WHITE), RGB(BLACK)
' reference numbers for the controls are defined as constants
CONST numEntry = 1
DIM x AS INTEGER
' setup our flags that are set in interupts
DIM INTEGER printmessage1=0,printmessage2=0
CLS
GUI INTERRUPT TouchDown, TouchUp

GUI NUMBERBOX numEntry, 50,40,90,40,RGB(YELLOW),RGB(64,64,64)

' All the controls have been defined and displayed. At this point
' the program could do some real work'
' This is the main loop where all work will be done.
' It will do any work flagged to be done in the interupts
''''''''''''''''''''''''' MAIN LOOP '''''''''''''''''''''''''''''''''''''''''''''''''''''''
DO
IF printmessage1=1 THEN
PRINT "entering a number"
printmessage1=
0
end IF
IF printmessage2=1 THEN
PRINT x
printmessage2=
0
end IF

LOOP
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

' the interrupt routine for touch down
' using a select case command it has a different process for each
' control
SUB TouchDown
SELECT CASE TOUCH(REF) ' find out the control touched
'Do not do too much here! No other interupts will be serviced until
'this sub is ended. So just set a flag and get out ASAP
CASE numEntry
printmessage1=
1

end SELECT
end SUB
' interrupt routine when the touch is removed
SUB TouchUp
SELECT CASE TOUCH(LASTREF) ' use the last reference
'Do not do too much here! No other interupts will be serviced until
'this sub is ended. So just set a flag and get out ASAP
CASE numEntry ' was it the numEntry box
x = CTRLVAL(numEntry)
printmessage2=
1
end SELECT
end SUB

Edited by disco4now 2017-02-08
Latest F4 Latest H7
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9082
Posted: 08:24pm 06 Feb 2017
Copy link to clipboard 
Print this post

Further to Disco4now's example, here is my current MAIN LOOP - note that it is very short, and just checks flags and the serial port buffer, nothing else:


'==========
'MAIN LOOP:
'==========
START:
DO
If DEBUG then PRINT "Main menu."
CHECK_SETTINGS 'Check if any checkbox values have been changed
KEY=0:LCD_EXIT=0:LCD_OK=0:TEST_PASSWORD=0 'Clear flags
BUILD_DATE 'Construct the current date string
DATE_REF=VAL(MID$(DATE$,1,2)) 'Current date and time reference for main DO/LOOP
PAGE 1,6 'Main menu and buttons
GUI INTERRUPT MENU 'This interrupt will be called when there is an LCD touch
DO 'This loop detects any activity or other events while waiting for an LCD touch
If Val(MID$(DATE$,1,2))>DATE_REF then goto START 'If new day, then update the clock
If LOC(#2)<>0 then goto MSG_RXD 'Some kind of message was received.
LOOP until KEY<>0
Select Case KEY
CASE 1 'DATABASE - Get password before access
Goto GET_PASSWORD
Case 2
Goto OTHER_OPTIONS
Case 3
Goto MESSAGING
End Select
Loop


...and teh GUI interrupt for the above:


SUB MENU 'Main menu GUI interrupt
KEY=0 'Clear flag
Select Case Touch(REF)
Case BU_MENU1 'Button "1" touched
KEY=1
Case BU_MENU2 'Button "2" touched
KEY=2
Case BU_MENU3 'Button "3" touched
KEY=3
End Select
End SUB


In the first code-box, we setup the display of the controls, and then enter a loop that waits until a button is pressed, or something arrived on the serial port.

Assuming a button press, and assuming that is button "1", then the MENU interrupt is called, it is discovered that GUI button "1" is being touched, and so KEY is set to 1, and then the interrupt immediately exits back to the main loop.

At that point in time, the main loop sees that KEY is no longer zero, so it hops out of the loop, and is directed to another area of code based on the value of KEY - in this case, it will loop to the GET_PASSWORD chunk of code, and go about asking the user for the password.

The point I am trying to hammer-home here(as is disco4now and others), is that you only set a flag in the interrupt, and let the main code actually work out what has happened by checking the flags.

Another example is my EXIT/OK buttons I use on many pages of the system I am working on now. ALL those pages call the same interrupt, that being:


SUB EXIT_OK 'Touch interrupt for EXIT and OK buttons on any page
LCD_EXIT=0:LCD_OK=0 'Clear flags
Select Case Touch(REF)
Case BU_EXIT 'EXIT button touched
LCD_EXIT=1
Case BU_OK 'OK button touched
LCD_OK=1
End Select
End SUb


...and the main code for that page checks which button has been touched by:


KEY=0:LCD_EXIT=0:LCD_OK=0 'Clear flags
If DEBUG then Print "Get Password."
PAGE 2,4
CtrlVal(PASSWORD)="##PASSWORD"
GUI Interrupt EXIT_OK
Do
If LCD_EXIT then
LCD_EXIT=0 'Clear flag
If DEBUG then print "EXIT button touched.(get password)"
Goto START
ENDIF
IF LCD_OK then
LCD_OK=0 'Clear flag
IF DEBUG Then print "OK button touched.(get password)"
If CtrlVal(PASSWORD)=STDPWD$ then
IF DEBUG then print "Password correct."
Goto DATABASE_EDITOR
ELSE
SYSMSG$="Password incorrect.(database access)"
IF DEBUG then print SYSMSG$
If SYSLOG Then WRITE_SYSLOG(SYSMSG$)
CtrlVal(ADWI)="ACCESS DENIED."
PAGE 3 'Access denied
GUI Beep 1000
Pause 2500
Goto START
ENDIF
ENDIF
LOOP


Note that the main code asking for the password in this case, just sits in a loop waiting for the value of the FLAGS to change, then it knows it needs to do something. The value of these flags will change via the interrupt whenever a button is touched, so it kinda looks confusing, as you are in a loop waiting for a flag to change, but you are not actually coding that change directly - the interrupt will change it for you when the button is touched - it seems strange for a start, till you get you heard around what is actually happening.
Smoke makes things work. When the smoke gets out, it stops!
 
     Page 1 of 2    
Print this page
© JAQ Software 2024