Pastey Working listview filter and sort demo
- Posted by irv
Sep 03, 2019
--# ListView filter and sort
include GtkEngine.e
include std/sort.e
enum NAME,CLASS,AGE
object students = { --name, class, age
{"Fred", "Senior", 18},
{"Sue", "Junior", 16},
{"Kathleen","Freshman", 14},
{"Arnold", "Freshman", 14},
{"Xavier", "Junior", 18},
{"Kathy", "Teacher", 33},
{"Thelma", "Sophmore", 15},
{"Ralph", "Junior", 17},
{"Bill", "Junior", 17},
{"Kate", "Senior", 18},
{"Jane", "Senior", 17},
{"Mo", "Freshman", 13},
{"Charlie", "Teacher", 40},
{"Louise", "Sophmore", 16},
{"Alice", "Junior", 17},
{"George", "Freshman", 13},
{"Chris", "Senior", 19},
{"Frank", "Freshman", 15},
$}
integer name_sort_dir = 0, class_sort_dir = 0, age_sort_dir = 0
constant
win = create(GtkWindow,"size=300x300,border=10,$destroy=Quit"),
pan = create(GtkBox,"orientation=horizontal,spacing=10"),
scr = create(GtkScrolledWindow),
tv = create(GtkTreeView),
sel = get(tv,"selection"),
col1 = create(GtkColumn,"title=Name,type=text,text=1,sort=1"),
col2 = create(GtkColumn,"title=Class,type=text,text=2,sort=2"),
col3 = create(GtkColumn,"title=Age,type=text,text=3,sort=3"),
box = create(GtkButtonBox,"orientation=vertical"),
btn1 = create(GtkButton,"Frosh","select_by_class","Freshman"),
btn2 = create(GtkButton,"Soph.","select_by_class","Sophmore"),
btn3 = create(GtkButton,"Juniors","select_by_class","Junior"),
btn4 = create(GtkButton,"Seniors","select_by_class","Senior"),
btn5 = create(GtkButton,"All","select_by_class",0),
btn6 = create(GtkButton,"gtk-about","Help"),
btn7 = create(GtkButton,"gtk-quit","Quit")
object selected_class = 0 -- set by btn1..5
add(win,pan)
pack(pan,scr,1,1)
add(scr,tv)
add(tv,{col1,col2,col3})
add(box,{btn1,btn2,btn3,btn4,btn5,btn6,btn7})
pack(pan,-box)
constant stored = create(GtkListStore,{gSTR,gSTR,gINT})
set(stored,"data",students)
constant filtered = create(GtkTreeModelFilter,stored)
set(filtered,"visible func",_("Filter"))
constant sorted = create(GtkTreeModelSort,filtered)
set(tv,"model",sorted)
set(tv,"headers clickable",TRUE)
set(col1,"sort indicator",TRUE)
set(col2,"sort indicator",TRUE)
set(col3,"sort indicator",TRUE)
connect(tv,"row-activated","ShowStudentInfo") -- on dbl click;
-- we have to manually connect sorting functions
-- to the header clicks here, since we're also
-- using a filter (they don't work well together)
connect(col1,"clicked","SetSortCol",NAME)
connect(col2,"clicked","SetSortCol",CLASS)
connect(col3,"clicked","SetSortCol",AGE)
show_all(win)
main()
------------------------------------------------------------------
global function ShowStudentInfo(atom view, atom path, atom col)
------------------------------------------------------------------
object model = get(view,"model")
atom iter = allocate(32)
atom fn1 = define_proc("gtk_tree_model_get_iter",{P,P,P})
c_proc(fn1,{model,iter,path})
if get(model,"iter is valid",iter) then
object name = get(model,"value",iter,1)
object class = get(model,"value",iter,2)
object age = get(model,"value",iter,3)
Info(,,name,format("Age [] Class []",{age,class}))
else display("Invalid iterator!")
end if
return 1
end function
---------------------------------------------------
global function SetSortCol(atom btn, integer col)
---------------------------------------------------
switch col do
case NAME then
name_sort_dir = not(name_sort_dir) -- toggle
set(sorted,"sort column id",col,name_sort_dir+1)
case CLASS then
class_sort_dir = not(class_sort_dir)
set(sorted,"sort column id",col,class_sort_dir+1)
case AGE then
age_sort_dir = not(age_sort_dir)
set(sorted,"sort column id",col,age_sort_dir+1)
end switch
return 1
end function
----------------------------------------------------------
global function select_by_class(atom ctl, object pattern)
----------------------------------------------[-----------
-- when filter selection changes, must re-filter
selected_class = unpack(pattern) -- grab the pattern (Junior,Senior..)
set(filtered,"refilter")
return 1
end function
-----------------------------------------------
global function Filter(atom model, atom iter)
-----------------------------------------------
-- if "all" are selected, no need for further work
if atom(selected_class) then return 1 end if
-- otherwise, check each item against the selected class;
object val = get(model,"value",iter,2) -- col 2 contains the student's class;
return equal(val,selected_class)
end function
------------------------
global function Help()
------------------------
return Info(win,"About","Tree Model Fiters",
"""
A tree model filter hides parts of an underlying tree model.
It requires a custom Filter routine which returns 1 if the
row should be shown, 0 otherwise.
You must write a custom filter function, but it's easy,
usually only a few lines of code.
Implementing a custom filter also requires manually connecting
a custom sort routine, if you want the filtered results sorted.
This too, is relatively simple.
Examine the source code for this program.
<i>Hint: try ctl-f to open a search entry, then typing ka, for
example, to find Kate, Kathleen, etc... Use the up/dn arrow keys
to select prev/next match on list.</i>
""",
,"thumbnails/gtk-logo-rgb.gif")
end function