Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
ackley_mc
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Torda, Prof. Dr. Andrew Ernest
ackley_mc
Commits
2ecb69d0
Commit
2ecb69d0
authored
3 years ago
by
Andrew E. Torda
Browse files
Options
Downloads
Patches
Plain Diff
Tidying.
parent
18a51fe0
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
ui/output_tab.go
+14
-29
14 additions, 29 deletions
ui/output_tab.go
ui/param_tab.go
+20
-16
20 additions, 16 deletions
ui/param_tab.go
ui/ui_run.go
+18
-15
18 additions, 15 deletions
ui/ui_run.go
with
52 additions
and
60 deletions
ui/output_tab.go
+
14
−
29
View file @
2ecb69d0
...
@@ -24,45 +24,32 @@ import (
...
@@ -24,45 +24,32 @@ import (
"fyne.io/fyne/v2/widget"
"fyne.io/fyne/v2/widget"
)
)
//
A message is sent to the output tab, telling us the curren
t
s
ta
tus
//
We have a channel that sends the status to the outpu
t ta
b.
type
status
uint8
type
status
uint8
const
(
const
(
calculating
status
=
iota
calculating
status
=
iota
// currently running a simulation
resultsReady
resultsReady
// You should collect the results
errorCalc
errorCalc
// You should display an error message
)
)
type
workstatus
struct
{
type
workstatus
struct
{
fdata
,
xdata
[]
byte
fdata
,
xdata
[]
byte
// the data in a function or X value plot
err
error
err
error
status
status
status
status
// Tells us what we should do now
}
// showIniTab is a card to be shown before we have any calculations.
func
showIniTab
(
cntr
*
fyne
.
Container
)
{
cntr
.
Add
(
widget
.
NewCard
(
"No results yet"
,
"go back to the input"
,
nil
))
}
}
// If we get a message with an error, display it
// If we get a message with an error, display it
func
showErrTab
(
cntr
*
fyne
.
Container
,
err
error
)
{
func
showErrTab
(
cntr
*
fyne
.
Container
,
err
error
)
{
cntr
.
Objects
=
nil
cntr
.
Add
(
widget
.
NewCard
(
"ERROR in MC"
,
err
.
Error
(),
nil
))
cntr
.
Add
(
widget
.
NewCard
(
"ERROR in MC"
,
err
.
Error
(),
nil
))
}
}
// emptyContainer gets rid of any old contents. Could I just say,
// cntr.Objects = nil ?
func
emptyContainer
(
cntr
*
fyne
.
Container
)
{
for
_
,
o
:=
range
cntr
.
Objects
{
cntr
.
Remove
(
o
)
}
}
// showCalcTab is shown while calculating. Have to check if the refresh()
// showCalcTab is shown while calculating. Have to check if the refresh()
// is actually necessary.
// is actually necessary.
func
showCalcTab
(
cntr
*
fyne
.
Container
)
{
func
showCalcTab
(
cntr
*
fyne
.
Container
)
{
emptyContainer
(
cntr
)
cntr
.
Objects
=
nil
cntr
.
Add
(
widget
.
NewCard
(
"calculating"
,
"busy"
,
nil
))
cntr
.
Add
(
widget
.
NewCard
(
"calculating"
,
"busy"
,
nil
))
cntr
.
Refresh
()
}
}
// fwrt writes the file. It will be called by the filesave dialog
// fwrt writes the file. It will be called by the filesave dialog
...
@@ -115,29 +102,27 @@ func png2image(d []byte, fname string) *canvas.Image {
...
@@ -115,29 +102,27 @@ func png2image(d []byte, fname string) *canvas.Image {
// showResultsTab show the two plots
// showResultsTab show the two plots
func
showResultsTab
(
cntr
*
fyne
.
Container
,
win
fyne
.
Window
,
fdata
,
xdata
[]
byte
)
{
func
showResultsTab
(
cntr
*
fyne
.
Container
,
win
fyne
.
Window
,
fdata
,
xdata
[]
byte
)
{
emptyContainer
(
cntr
)
cntr
.
Objects
=
nil
fImage
:=
png2image
(
fdata
,
"function.png"
)
fImage
:=
png2image
(
fdata
,
"function.png"
)
xImage
:=
png2image
(
xdata
,
"xdata.png"
)
xImage
:=
png2image
(
xdata
,
"xdata.png"
)
right
:=
container
.
NewGridWithRows
(
2
,
fImage
,
xImage
)
right
:=
container
.
NewGridWithRows
(
2
,
fImage
,
xImage
)
left
:=
leftbar
(
win
,
fdata
,
xdata
)
left
:=
leftbar
(
win
,
fdata
,
xdata
)
box
:=
container
.
NewHBox
(
left
,
right
)
box
:=
container
.
NewHBox
(
left
,
widget
.
NewSeparator
(),
right
)
cntr
.
Add
(
box
)
cntr
.
Add
(
box
)
}
}
// outputTab is run as a background process. After showing the initial
// outputTab is run as a background process. After showing the initial
// screen, it sits and waits on notifications. When it gets one,
// screen, it sits and waits on notifications. When it gets one,
// it redraws its tab.
// it redraws its tab.
func
outputTab
(
chn
chan
workstatus
,
cntr
*
fyne
.
Container
,
form
*
widget
.
Form
,
win
fyne
.
Window
)
{
func
outputTab
(
genParams
genParams
,
cntr
*
fyne
.
Container
,
form
*
widget
.
Form
)
{
showIniTab
(
cntr
)
cntr
.
Add
(
widget
.
NewCard
(
"No results yet"
,
"go back to the input"
,
nil
))
breaker
()
for
s
:=
range
genParams
.
chn
{
for
s
:=
range
chn
{
switch
s
.
status
{
switch
s
.
status
{
case
calculating
:
case
calculating
:
showCalcTab
(
cntr
)
showCalcTab
(
cntr
)
case
resultsReady
:
case
resultsReady
:
showResultsTab
(
cntr
,
win
,
s
.
fdata
,
s
.
xdata
)
showResultsTab
(
cntr
,
genParams
.
win
,
s
.
fdata
,
s
.
xdata
)
breaker
()
form
.
Enable
()
form
.
Enable
()
form
.
Refresh
()
form
.
Refresh
()
case
errorCalc
:
case
errorCalc
:
...
...
This diff is collapsed.
Click to expand it.
ui/param_tab.go
+
20
−
16
View file @
2ecb69d0
...
@@ -21,6 +21,14 @@ import (
...
@@ -21,6 +21,14 @@ import (
"example.com/ackley_mc/mc_work"
"example.com/ackley_mc/mc_work"
)
)
// startrun is what happens when you click on the form's button to start
// a calculation.
func
startrun
(
genParams
genParams
,
form
*
widget
.
Form
,
mcPrm
*
mcwork
.
McPrm
)
{
form
.
Disable
()
go
mcWrap
(
genParams
)
}
// fslicestrng makes a nice string from a slice of float32's
// fslicestrng makes a nice string from a slice of float32's
func
fslicestrng
(
f
[]
float32
)
string
{
func
fslicestrng
(
f
[]
float32
)
string
{
if
len
(
f
)
==
0
{
if
len
(
f
)
==
0
{
...
@@ -33,6 +41,7 @@ func fslicestrng(f []float32) string {
...
@@ -33,6 +41,7 @@ func fslicestrng(f []float32) string {
return
s
return
s
}
}
// str2f32 takes a string and returns a slice of float32's
// str2f32 takes a string and returns a slice of float32's
func
s2f32
(
s
string
)
([]
float32
,
error
)
{
func
s2f32
(
s
string
)
([]
float32
,
error
)
{
y
:=
strings
.
Split
(
s
,
","
)
y
:=
strings
.
Split
(
s
,
","
)
...
@@ -62,7 +71,7 @@ func validateXini(s string) error {
...
@@ -62,7 +71,7 @@ func validateXini(s string) error {
// This gets put on the list of things to do from the reload function.
// This gets put on the list of things to do from the reload function.
func
floatItem
(
xAddr
*
float64
,
label
string
)
(
*
widget
.
FormItem
,
func
())
{
func
floatItem
(
xAddr
*
float64
,
label
string
)
(
*
widget
.
FormItem
,
func
())
{
bind
:=
binding
.
BindFloat
(
xAddr
)
bind
:=
binding
.
BindFloat
(
xAddr
)
entry
:=
widget
.
NewEntryWithData
(
binding
.
FloatToStringWithFormat
(
bind
,
"%
10
.2f"
))
entry
:=
widget
.
NewEntryWithData
(
binding
.
FloatToStringWithFormat
(
bind
,
"%.2f"
))
fitem
:=
widget
.
NewFormItem
(
label
,
entry
)
fitem
:=
widget
.
NewFormItem
(
label
,
entry
)
reloadfunc
:=
func
()
{
bind
.
Reload
()
}
reloadfunc
:=
func
()
{
bind
.
Reload
()
}
return
fitem
,
reloadfunc
return
fitem
,
reloadfunc
...
@@ -72,7 +81,8 @@ func floatItem(xAddr *float64, label string) (*widget.FormItem, func()) {
...
@@ -72,7 +81,8 @@ func floatItem(xAddr *float64, label string) (*widget.FormItem, func()) {
// It returns the screen and a function to be called to refresh it.
// It returns the screen and a function to be called to refresh it.
// This is necessary, since there is a button to read parameters from
// This is necessary, since there is a button to read parameters from
// a file, which means all the values should be updated.
// a file, which means all the values should be updated.
func
paramBox
(
mcPrm
*
mcwork
.
McPrm
,
parent
fyne
.
Window
,
chn
chan
workstatus
)
*
widget
.
Form
{
func
paramBox
(
genParams
genParams
)
*
widget
.
Form
{
mcPrm
:=
genParams
.
mcPrm
iniTmpItem
,
iniTmpReload
:=
floatItem
(
&
mcPrm
.
IniTmp
,
"initial temperature"
)
iniTmpItem
,
iniTmpReload
:=
floatItem
(
&
mcPrm
.
IniTmp
,
"initial temperature"
)
fnlTmpItem
,
fnlTmpReload
:=
floatItem
(
&
mcPrm
.
FnlTmp
,
"final temperature"
)
fnlTmpItem
,
fnlTmpReload
:=
floatItem
(
&
mcPrm
.
FnlTmp
,
"final temperature"
)
xDltaItem
,
xDltaReload
:=
floatItem
(
&
mcPrm
.
XDlta
,
"X delta"
)
xDltaItem
,
xDltaReload
:=
floatItem
(
&
mcPrm
.
XDlta
,
"X delta"
)
...
@@ -103,14 +113,14 @@ func paramBox(mcPrm *mcwork.McPrm, parent fyne.Window, chn chan workstatus) *wid
...
@@ -103,14 +113,14 @@ func paramBox(mcPrm *mcwork.McPrm, parent fyne.Window, chn chan workstatus) *wid
_
=
nStepBnd
.
Reload
()
_
=
nStepBnd
.
Reload
()
}
}
rdfile
:=
func
()
{
rdwork
(
mcPrm
,
parent
,
reloadPTab
)
}
rdfile
:=
func
()
{
rdwork
(
mcPrm
,
genParams
.
win
,
reloadPTab
)
}
rdfileBtn
:=
widget
.
NewButton
(
"get file "
,
rdfile
)
rdfileBtn
:=
widget
.
NewButton
(
"get file "
,
rdfile
)
rdFileItem
:=
widget
.
NewFormItem
(
"read from a file"
,
rdfileBtn
)
rdFileItem
:=
widget
.
NewFormItem
(
"read from a file"
,
rdfileBtn
)
r
:=
widget
.
NewForm
(
r
:=
widget
.
NewForm
(
iniTmpItem
,
fnlTmpItem
,
xDltaItem
,
xIniItem
,
nStepItem
,
rdFileItem
)
iniTmpItem
,
fnlTmpItem
,
xDltaItem
,
xIniItem
,
nStepItem
,
rdFileItem
)
r
.
SubmitText
=
"start calculation"
r
.
SubmitText
=
"start calculation"
r
.
OnSubmit
=
func
()
{
startrun
(
chn
,
parent
,
r
,
mcPrm
)
}
r
.
OnSubmit
=
func
()
{
startrun
(
genParams
,
r
,
mcPrm
)
}
return
r
return
r
}
}
...
@@ -149,24 +159,18 @@ func rdwork(mcPrm *mcwork.McPrm, parent fyne.Window, reloadPTab func()) {
...
@@ -149,24 +159,18 @@ func rdwork(mcPrm *mcwork.McPrm, parent fyne.Window, reloadPTab func()) {
// mcWrap is run in the background so the interface does not block.
// mcWrap is run in the background so the interface does not block.
// It runs the Monte Carlo, then when it is finished, sends a message
// It runs the Monte Carlo, then when it is finished, sends a message
// down the channel.
// down the channel.
func
mcWrap
(
chn
chan
workstatus
,
parent
fyne
.
Window
,
mcPrm
*
mcwork
.
McPrm
)
{
func
mcWrap
(
genParams
genParams
)
{
chn
:=
genParams
.
chn
chn
<-
workstatus
{
status
:
calculating
}
chn
<-
workstatus
{
status
:
calculating
}
if
fdata
,
xdata
,
err
:=
mcwork
.
DoRun
(
mcPrm
);
err
!=
nil
{
if
fdata
,
xdata
,
err
:=
mcwork
.
DoRun
(
genParams
.
mcPrm
);
err
!=
nil
{
dialog
.
NewError
(
err
,
parent
)
.
Show
()
dialog
.
NewError
(
err
,
genParams
.
win
)
.
Show
()
chn
<-
workstatus
{
status
:
errorCalc
,
err
:
err
}
chn
<-
workstatus
{
status
:
errorCalc
,
err
:
err
}
}
else
{
}
else
{
chn
<-
workstatus
{
fdata
:
fdata
,
xdata
:
xdata
,
status
:
resultsReady
}
chn
<-
workstatus
{
fdata
:
fdata
,
xdata
:
xdata
,
status
:
resultsReady
}
}
}
}
}
// startrun is what happens when you click on the button to start
// a calculation.
func
startrun
(
chn
chan
workstatus
,
parent
fyne
.
Window
,
form
*
widget
.
Form
,
mcPrm
*
mcwork
.
McPrm
)
{
form
.
Disable
()
go
mcWrap
(
chn
,
parent
,
mcPrm
)
}
// inputTab sets up the input page.
// inputTab sets up the input page.
func
inputTab
(
mcPrm
*
mcwork
.
McPrm
,
parent
fyne
.
Window
,
chn
chan
workstatu
s
)
*
widget
.
Form
{
func
inputTab
(
genParams
genParam
s
)
*
widget
.
Form
{
return
paramBox
(
mcPrm
,
parent
,
chn
)
return
paramBox
(
genParams
)
}
}
This diff is collapsed.
Click to expand it.
ui/ui_run.go
+
18
−
15
View file @
2ecb69d0
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
package
ui
package
ui
import
(
import
(
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget"
"fyne.io/fyne/v2/widget"
...
@@ -14,28 +15,30 @@ import (
...
@@ -14,28 +15,30 @@ import (
"example.com/ackley_mc/mc_work"
"example.com/ackley_mc/mc_work"
)
)
func
UiDoRun
(
mcPrm
*
mcwork
.
McPrm
)
error
{
// Convenience struct so we do not have perverse long parameter lists
type
genParams
struct
{
mcPrm
*
mcwork
.
McPrm
// The MC parameters shared with the main simulation
win
fyne
.
Window
// Parent window. Needed for all dialog boxes
chn
chan
workstatus
// To tell the output tab current status
}
// UiDoRun sets up the screen to do a run. It is effectively a big
// wrapper around the DoRun() function.
func
UiDoRun
(
mcPrm
*
mcwork
.
McPrm
)
error
{
a
:=
app
.
NewWithID
(
"Monte Carlo"
)
a
:=
app
.
NewWithID
(
"Monte Carlo"
)
w
:=
a
.
NewWindow
(
"Monte Carlo"
)
win
:=
a
.
NewWindow
(
"Monte Carlo"
)
quitbutton
:=
widget
.
NewButton
(
"click somewhere in here to exit"
,
a
.
Quit
)
chn
:=
make
(
chan
workstatus
)
chn
:=
make
(
chan
workstatus
)
// inputTabCallback := func() *widget.Form { return (inputTab(mcPrm, w, chn))}
var
genParams
=
genParams
{
mcPrm
,
win
,
chn
}
inputForm
:=
inputTab
(
mcPrm
,
w
,
chn
)
inputForm
:=
inputTab
(
genParams
)
quitbutton
:=
widget
.
NewButton
(
"click somewhere in here to confirm"
,
a
.
Quit
)
t1
:=
container
.
NewTabItem
(
"input tab"
,
inputForm
)
t1
:=
container
.
NewTabItem
(
"input tab"
,
inputForm
)
cntrOut
:=
container
.
NewWithoutLayout
()
cntrOut
:=
container
.
NewWithoutLayout
()
t2
:=
container
.
NewTabItem
(
"output tab"
,
cntrOut
)
t2
:=
container
.
NewTabItem
(
"output tab"
,
cntrOut
)
t3
:=
container
.
NewTabItem
(
"quit
me
"
,
quitbutton
)
t3
:=
container
.
NewTabItem
(
"quit"
,
quitbutton
)
appTab
:=
container
.
NewAppTabs
(
t1
,
t2
,
t3
)
appTab
:=
container
.
NewAppTabs
(
t1
,
t2
,
t3
)
w
.
SetContent
(
appTab
)
w
in
.
SetContent
(
appTab
)
go
outputTab
(
chn
,
cntrOut
,
inputForm
,
w
)
go
outputTab
(
genParams
,
cntrOut
,
inputForm
)
w
.
ShowAndRun
()
w
in
.
ShowAndRun
()
close
(
chn
)
close
(
chn
)
return
nil
return
nil
}
}
// nothing does nothing
func
nothing
(
...
interface
{})
{}
// and breaker does not do much more
func
breaker
(
...
interface
{})
{}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment