------------------------------------------------------------------------
--# Worldflags - match the flags and name the country
------------------------------------------------------------------------
include GtkEngine.e
include std/filesys.e
include std/sequence.e
integer prev = 0, guesses = 0, correct = 0, misses = 0
atom score = 0
constant flagdir = canonical_path("~/demos/resources/flags/")
----------------------------
-- get list of flag names
----------------------------
object flaglist = dir(flagdir & "flags-*.png")
if atom(flaglist) then
Error(0,"Worldflags Error","Cannot find flags",flagdir,,GTK_BUTTONS_CLOSE)
abort(1)
end if
flaglist = vslice(flaglist,D_NAME)
--------------------------------
-- select 8 at random, no dupes
--------------------------------
object flagarray = {}
while length(flagarray) < 8 do
flagarray = add_item(flaglist[rand(length(flaglist))],flagarray)
end while
---------------------------------------------
-- shuffle the 8 and add them to list again
-- so every flag has a twin somewhere
---------------------------------------------
flagarray &= shuffle(flagarray)
enum HANDLE, FLAG, TUX, NAME, CAPTION, SIGID, HASH, MATCHED
-------------------------------------------
-- create buttons from the selected flags
-------------------------------------------
object btn = {HANDLE,FLAG,TUX,NAME,CAPTION,SIGID,HASH,MATCHED}
object btns = repeat(btn,16)
object ctl, name, flag, tux, box, lbl, sigid, id
for i = 1 to 16 do
-- get rid of the file extension, and change country name to nice format;
name = proper(join(split(flagarray[i][7..$-4],'_'),' '))
-- match flag with its twin by means of a hash on the file name;
id = hash(name,0)
-- make a button to hold the flag;
ctl = create(GtkToolButton)
flag = create(GtkImage,flagdir & flagarray[i])
tux = create(GtkImage,"~/demos/thumbnails/BabyTux.png")
sigid = connect(ctl,"clicked",call_back(routine_id("onClick")),i)
box = create(GtkBox,1)
lbl = create(GtkLabel,{
{"text",name},
{"font","8"},
{"max width chars",10},
{"ellipsize",PANGO_ELLIPSIZE_END}})
add(box,{tux,flag,lbl})
set(ctl,{
{"label widget",box},
{"size request",80,80}})
show({ctl,box,flag,lbl})
btns[i] = {ctl,flag,tux,name,lbl,sigid,id,FALSE}
ifdef CHEAT then
set(ctl,"tooltip text",name)
end ifdef
end for
----------------------
-- make a main window
----------------------
constant win = create(GtkWindow,{
{"border width",10},
{"default size",120,120},
{"position",GTK_WIN_POS_CENTER},
{"icon","thumbnails/preferences-desktop-locale.svg"}})
connect(win,"destroy","Quit")
show(win)
constant panel = create(GtkBox,1)
add(win,panel)
show(panel)
---------------------
-- make a grid
---------------------
constant grid = create(GtkGrid,{
{"row homogeneous",TRUE},
{"column homogeneous",TRUE}})
add(panel,grid)
show(grid)
-------------------------------
-- attach flag buttons to grid
-------------------------------
integer i = 1
for x = 1 to 4 do
for y = 1 to 4 do
set(grid,"attach",btns[i][HANDLE],x,y,1,1)
i += 1
end for
end for
constant helptxt = create(GtkLabel,{
{"markup","Perfect score is 100"},
{"font","8"},
{"foreground","red"}})
add(panel,helptxt)
show(helptxt)
------------------------------------------
-- show flags for 5 seconds, then hide 'em
------------------------------------------
constant delay = create(GTimeout,5000,call_back(routine_id("hide_flags")))
main()
------------------------------------------------------------------------
function hide_flags() -- called once at start of pgm. after a delay
------------------------------------------------------------------------
for x = 1 to 16 do
set(btns[x][FLAG],"hide")
set(btns[x][CAPTION],"hide")
set(btns[x][TUX],"show")
btns[x][MATCHED] = FALSE
end for
return 0 -- 0 kills the timer, otherwise it would fire again every 5 sec.
end function
---------------------------------------------------------------
function onClick(atom ctl, integer this)
---------------------------------------------------------------
set(btns[this][TUX],"hide")
set(btns[this][FLAG],"show")
if btns[this][MATCHED] then return 1 end if
if prev > 0 then
if this = prev then return 1 end if -- same one clicked again, forgettaboutit!
if btns[this][HASH] != btns[prev][HASH] then -- not a match
set(btns[prev][FLAG],"hide")
set(btns[prev][CAPTION],"hide")
set(btns[prev][TUX],"show")
misses += 1
prev = this
guesses += 1
score -= 1
else -- matched!
btns[prev][MATCHED] = TRUE
btns[this][MATCHED] = TRUE
guesses += 1
correct += 1
prev = 0
popup_extra_credit(this)
end if
else
prev = this
end if
set(win,"title", -- update score;
sprintf("Score: %2.1f",score))
return 1
end function
-------------------------------------------------------------
function popup_extra_credit(integer x)
-------------------------------------------------------------
object dlg = create(GtkDialog,{
{"default size",200,200},
{"border width",10},
{"add button","gtk-ok",1}})
object ca = get(dlg,"content area")
display(flagarray[x])
object img = create(GtkImage,sprintf("~/demos/resources/flags/%s",{flagarray[x]}))
object lbl = create(GtkLabel,{
{"font","8"},
{"markup",
"You get 5 points for correctly matching the flags.\n" &
"For more points, please identify the country that\nflies this flag."}})
object sep = create(GtkSeparator)
add(ca,{img,lbl,sep})
object choices = {btns[x][NAME]}
while length(choices) < 3 do
choices = add_item(btns[rand(16)][NAME],choices)
end while
choices = shuffle(choices)
object btn = repeat(0,3)
btn[1] = create(GtkRadioButton,0,choices[1])
btn[2] = create(GtkRadioButton,btn[1],choices[2])
btn[3] = create(GtkRadioButton,btn[2],choices[3])
add(ca,btn)
show_all(ca)
object choice
integer i = get(dlg,"run")
for j = 1 to 3 do
if get(btn[j],"active") then choice = choices[j] end if
end for
if equal(choice,btns[x][NAME]) then
score += 100/8
show_matched_captions(0)
else
score += 5
show_matched_captions(x)
set(helptxt,"text","Incorrect guesses are shown in red")
end if
set(dlg,"destroy")
show_matched_captions(0)
return 1
end function
------------------------------------------------------------------------
procedure show_matched_captions(integer x)
------------------------------------------------------------------------
for i = 1 to 16 do
if btns[i][MATCHED] then show(btns[i][CAPTION]) end if
if x > 0 then -- set miss-identified captions to red
if equal(btns[i][NAME],btns[x][NAME]) then
set(btns[i][CAPTION],"color","red")
end if
end if
end for
end procedure