324 lines
10 KiB
Elixir
324 lines
10 KiB
Elixir
|
|
------------------------------------------------------------------------
|
|
--# GtkListView demo - gaudy, but shows most all functions
|
|
--
|
|
-- LOOKS COMPLICATED, but not really so bad, since I have used
|
|
-- a lot more features than would normally be used, just for
|
|
-- demo purposes.
|
|
--
|
|
-- Study it, you'll see how to accomplish almost anything with
|
|
-- simple functions which should be familiar to Euphorians.
|
|
------------------------------------------------------------------------
|
|
|
|
include GtkEngine.e
|
|
|
|
constant docs = `<u><b>GtkListView</b></u>
|
|
This demos creating and retrieving data from a listview.
|
|
The list can be rearranged by dragging a veggie up or down
|
|
the list. Double-click a row, or select one or more, then
|
|
click buttons at bottom.
|
|
`
|
|
enum NAME,PREP,MG,MDR,COLOR,NOTE
|
|
|
|
sequence veggies = { -- a totally bogus list of food values; last field is 'editable' flag;
|
|
{"Broccoli", "raw", 43, 64, "green", 0, 0},
|
|
{"Cabbage", "boiled", 103, 16, "cyan", 0, 1},
|
|
{"<b>Beet</b> greens", "steamed", 164, 72, "red", 0, 0},
|
|
{"<i>Swiss Chard</i>", "boiled", 102, 50, "green", 0, 1},
|
|
{"Collards", "boiled", 266, 10, "skyblue", 0, 0},
|
|
{"Asparagus", "", 23, 18, "yellow", 0, 1},
|
|
{"Onions", "raw", 10, 34, "white", 0, 0}
|
|
}
|
|
|
|
constant -- extra non-veggie selections (used later)
|
|
Steak = {"Steak", "Grilled", 2, 3, "#FEC277", "Yum!", 1},
|
|
Chicken = {"Chicken", "Grilled", 2, 3, "#FE4377", "Cluck!", 1},
|
|
Duck = {"Duck", "Roasted", 22, 4, "#FE4342", "Quack!", 1},
|
|
Pie = {"Apple Pie", "Baked", 0, 0, "pink", "One Pie", 0},
|
|
Pudding = {"Possum Pudding", "Baked", 155, 90, "limegreen","One Slice",0}
|
|
|
|
------------------------------------------------------------------------
|
|
-- Create a model and store the veggies in it;
|
|
------------------------------------------------------------------------
|
|
object store = create(GtkListStore,{gSTR,gSTR,gINT,gINT,gSTR,gSTR,gINT})
|
|
|
|
set(store,"data",veggies)
|
|
|
|
------------------------------------------------------------
|
|
-- Create the view, and set appearance
|
|
------------------------------------------------------------
|
|
constant tv = create(GtkTreeView,{
|
|
{"model",store},
|
|
{"reorderable",TRUE},
|
|
{"headers clickable",TRUE},
|
|
{"rules hint",TRUE},
|
|
{"grid lines",GTK_TREE_VIEW_GRID_LINES_BOTH},
|
|
{"margin left",10},
|
|
{"margin right",10},
|
|
{"margin bottom",10},
|
|
{"rubber banding",TRUE}})
|
|
|
|
constant -- columns (don't really need to set all these properties, this is gaudy!)
|
|
col1 = create(GtkColumn,"title=Name,type=text,markup=1,background=5,editable=7"),
|
|
col2 = create(GtkColumn,"title=Prep,type=text,text=2,editable=7,placeholder-text=6"),
|
|
col3 = create(GtkColumn,"title=Ounces,type=text,text=3,renderer.background=grey90"),
|
|
col4 = create(GtkColumn,"title=%MDR,type=progress,value=4,sort_column_id=4")
|
|
set(tv,"append columns",{col1,col2,col3,col4})
|
|
|
|
constant selection = get(tv,"selection")
|
|
set(selection,"mode",GTK_SELECTION_MULTIPLE)
|
|
|
|
-- to catch a double-click, uncomment the following line:
|
|
/*
|
|
connect(tv,"row-activated",call_back(routine_id("ShowSelected")))
|
|
*/
|
|
-- note that double-clicking is not completely compatible with editable rows,
|
|
-- as the same double click can either initiate editing or call the callback,
|
|
-- which can be confusing. A pop-up menu on right button click with an "edit"
|
|
-- option might be better in this case.
|
|
|
|
----------------------------------------------------------
|
|
-- Create main window and run the program;
|
|
----------------------------------------------------------
|
|
constant win = create(GtkWindow,
|
|
"title=`List View`,size=400x460,border_width=8,position=1")
|
|
connect(win,"destroy","Quit")
|
|
|
|
constant panel = add(win,create(GtkBox,VERTICAL))
|
|
constant lbl = add(panel,create(GtkLabel,{{"markup",docs}}))
|
|
|
|
constant scroller = create(GtkScrolledWindow)
|
|
pack(panel,scroller,TRUE,TRUE)
|
|
add(scroller,tv)
|
|
|
|
-- Enable the following if you want a permanently visible search box:
|
|
-- Otherwise, ctl-f will pop up a search box
|
|
/*
|
|
constant srch = create(GtkEntry)
|
|
pack(panel,srch)
|
|
*/
|
|
|
|
---------------------------------
|
|
function NewBtn(object params) -- helper function to build a bunch o'buttons
|
|
---------------------------------
|
|
atom btn = create(GtkButton,params[1],_(params[2]))
|
|
set(btn,"tooltip markup",params[3])
|
|
set(btn,"size request",120,30)
|
|
return btn
|
|
end function
|
|
|
|
object btns = { -- button image#caption, function, tooltip;
|
|
{"go-bottom#_Append","AppendRow","Click to append a dessert"},
|
|
{"go-top#_Prepend","PrependRow","Click to prepend a Steak"},
|
|
{"insert-object-symbolic#_Insert","InsertRow","Click to insert a Duck after selected item"},
|
|
{"gtk-delete","DeleteRow","Click to delete the selected row"},
|
|
{"emblem-synchronizing#_Replace","ReplaceRow","Replace the selected row(s) with a tasty treat"},
|
|
{"format-justify-fill#List","ShowAll","Click to show listing on terminal"},
|
|
{"starred#_Selected","ShowSelected","Click to show selected item(s)"},
|
|
{"gtk-info","ShowInfo","Click to show info about model"},
|
|
{"gtk-quit","Quit","Click to exit"},
|
|
{"media-playlist-shuffle#Swap","SwapItems","Click to swap two selected items"},
|
|
{"go-down#After","MoveAfter","Moves first selected item to a position immediately <i>after</i> the second"},
|
|
{"go-up#_Before","MoveBefore","Moves first selected item to a position immediately <i>before</i> the second"}
|
|
}
|
|
|
|
for i = 1 to length(btns) do
|
|
btns[i] = NewBtn(btns[i])
|
|
end for
|
|
|
|
ifdef WINDOWS then
|
|
set(btns[8],"sensitive",FALSE)
|
|
set(btns[8],"tooltip text","Broken on Windows")
|
|
end ifdef
|
|
|
|
constant box1 = create(GtkButtonBox) add(box1,btns[1..4])
|
|
constant box2 = create(GtkButtonBox) add(box2,btns[5..8])
|
|
constant box3 = create(GtkButtonBox) add(box3,btns[9..12])
|
|
pack(panel,{box1,box2,box3})
|
|
|
|
show_all(win)
|
|
main()
|
|
|
|
-- Edit function is not used here
|
|
---------------------------------------------------------
|
|
function EditName(atom rend, object path, object newtext)
|
|
---------------------------------------------------------
|
|
atom row = get(selection,"selected row")
|
|
set(store,"col data",row,1,peek_string(newtext))
|
|
return 1
|
|
end function
|
|
|
|
--------------------------
|
|
function ShowSelected() -- get one or more selected rows;
|
|
--------------------------
|
|
object rows = get(selection,"selected rows")
|
|
object results = {}
|
|
object names = {}
|
|
|
|
if length(rows) then
|
|
for i = 1 to length(rows) do
|
|
results = append(results, get(store,"col data",rows[i],1))
|
|
end for
|
|
results = join(demarkup(results),'\n')
|
|
Info(win,,"You chose",results)
|
|
end if
|
|
|
|
return 1
|
|
end function
|
|
|
|
---------------------
|
|
function ShowAll() -- get data back as a Eu sequence
|
|
---------------------
|
|
object x = get(store,"data") --update the original list
|
|
x = vslice(x,1)
|
|
x = demarkup(x)
|
|
display(x) -- and display on the terminal
|
|
return 1
|
|
end function
|
|
|
|
--------------------
|
|
function AppendRow()
|
|
--------------------
|
|
object data = set(store,"append row",Pie)
|
|
return 1
|
|
end function
|
|
|
|
---------------------
|
|
function PrependRow()
|
|
---------------------
|
|
object data = set(store,"prepend row",Steak)
|
|
return 1
|
|
end function
|
|
|
|
-----------------------------------------------------------------------------------------
|
|
-- note: nearly all the following calls require some testing to be sure
|
|
-- the user has selected the correct number of items from the list.
|
|
-- e.g: you cannot swap one item, nor is swapping 3 items logical.
|
|
------------------------------------------------------------------------------------------
|
|
|
|
--------------------
|
|
function InsertRow()
|
|
--------------------
|
|
object row = get(selection,"selected row")
|
|
|
|
if row > 0 then
|
|
set(store,"insert row",Duck,row+1)
|
|
else
|
|
Warn(,,"No row selected","Select a row first")
|
|
end if
|
|
|
|
return 1
|
|
end function
|
|
|
|
--------------------
|
|
function DeleteRow()
|
|
--------------------
|
|
object rows = get(selection,"selected rows")
|
|
|
|
if equal({},rows) then
|
|
Warn(,,"No row(s) selected to delete")
|
|
else
|
|
for i = length(rows) to 1 by -1 do
|
|
set(store,"remove row",rows[i])
|
|
end for
|
|
end if
|
|
|
|
return 1
|
|
end function
|
|
|
|
---------------------
|
|
function ReplaceRow()
|
|
---------------------
|
|
object rows = get(selection,"selected rows")
|
|
|
|
if length(rows) = 0 then
|
|
return Warn(win,"Too Bad",
|
|
"You didn't select anything!",
|
|
"Try clicking on one or more rows")
|
|
end if
|
|
for i = 1 to length(rows) do
|
|
set(store,"replace row",Pudding,rows[i])
|
|
end for
|
|
|
|
return 1
|
|
end function
|
|
|
|
--------------------
|
|
function SwapItems()
|
|
--------------------
|
|
object rows = get(selection,"selected rows")
|
|
|
|
if length(rows) = 2 then
|
|
set(store,"swap rows",rows[1],rows[2])
|
|
else
|
|
Error(win,,"Sorry",
|
|
"Must select exactly two rows to be swapped!")
|
|
end if
|
|
|
|
return 1
|
|
end function
|
|
|
|
---------------------
|
|
function MoveBefore()
|
|
---------------------
|
|
object rows = get(selection,"selected rows")
|
|
|
|
if length(rows) = 2 then
|
|
set(store,"move before",rows[1],rows[2])
|
|
else
|
|
Error(win,,"Sorry","Must select exactly two rows!")
|
|
end if
|
|
|
|
return 1
|
|
end function
|
|
|
|
--------------------
|
|
function MoveAfter()
|
|
--------------------
|
|
object rows = get(selection,"selected rows")
|
|
|
|
if length(rows) = 2 then
|
|
set(store,"move after",rows[2],rows[1])
|
|
else
|
|
Error(win,,"Sorry","Must select exactly two rows!")
|
|
end if
|
|
|
|
return 1
|
|
end function
|
|
|
|
----------------------
|
|
function ShowInfo() -- statistics;
|
|
----------------------
|
|
integer rows = get(store,"n rows")
|
|
integer cols = get(store,"n cols")
|
|
integer sortcol = get(store,"sort column id")
|
|
integer sortord = get(store,"sort order")
|
|
|
|
if get(store,"is sorted") then
|
|
Info(win,,"Model Contains",
|
|
sprintf("%d rows, %d columns\nSorted on col %d order %d",
|
|
{rows,cols,sortcol,sortord}))
|
|
else
|
|
Info(win,,"Model contains",
|
|
sprintf("%d rows, %d columns",{rows,cols}))
|
|
end if
|
|
|
|
return 1
|
|
end function
|
|
|
|
------------------------------
|
|
function demarkup(object x) -- remove markup
|
|
------------------------------
|
|
integer st,fi
|
|
|
|
for i = 1 to length(x) do -- need plain text when displaying on terminal;
|
|
while st > 0 and fi > st with entry do
|
|
x[i] = remove(x[i],st,fi)
|
|
entry
|
|
st = find('<',x[i]) fi = find('>',x[i])
|
|
end while
|
|
end for
|
|
|
|
return x
|
|
end function
|