EuGTK Convert Units
- Posted by Senator Aug 01, 2018
- 1638 views
Hello All,
I have been trying to write a EuGTK interface for Jim Roberts unit conversion library:
-- -- Measurement Conversion function (second update) -- (c2001) Jim Roberts sequence Unit integer l Unit = { -- Length {"m",1,"cm",100,"mm",1e3,"um",1e6,"km",1e-3,"in",1/.0254,"ft",1/.3048, "yd",1/.9144,"mi",1/1609.344,"fl",4.973e-3,"lg",2.071237307e-4, "au",6.684587154e-12,"ly",1.056980777e-16,"ps",3.24254e-17,"nmi",1/1852}, -- Time {"s",1,"min",1/60,"hr",1/3600,"dy",1/86400,"wk",1/604800,"yr",1/31557600}, -- Velocity {"m/s",1,"cm/s",100,"mm/s",1e3,"km/s",1e-3,"in/s",1/.0254,"ft/s",1/.3048, "mi/s",1/1609.344,"km/hr",3.6,"mi/hr",1/.44704,"kn",3.6/1.852}, -- Angles {"rad",1,"deg",57.29577951,"arcs",2.062648063e5,"arcmin",3437.746771, "gra",63.66197724}, -- Angular velocity {"rad/s",1,"deg/s",57.29577951,"deg/min",3437.746771,"rev/s",.1591549431, "rev/min",9.549296586,"rev/hr",572.9577952}, -- Area {"m2",1,"cm2",1e4,"mm2",1e6,"km2",1e-6,"in2",1550.0031,"ft2",10.76390841, "yd2",1.195990046,"mi2",3.861021585e-7,"acr",2.471053354e-04,"ha",.0001}, -- Volume {"m3",1,"cm3",1e6,"ft3",35.31466672,"in3",61023.74409,"yd3",1.307950618, "gal",264.1721,"lt",1e3,"pt",2113.3768,"qt",1056.6884,"mm3",1e9}, -- Weight {"kg",1,"g",1000,"lbs",2.205,"tn",1.1025e-3,"oz",35.28,"mtn",1e-3}, -- Pressure {"Pa",1,"N/m2",1,"bar",1e-5,"mbar",1e-2,"N/cm2",1e-4,"dn/cm2",10, "g/cm2",1/98.0665,"kg/cm2",1/98066.5,"atm",1/101325,"lbs/in2",1/6894.8, "lbs/ft2",1/47.88055555,"kg/m2",1/9.80665}, -- Energy {"j",1, "kj", 1000,"mj", 1000000, "erg",1e7,"btu",9.48e-04,"ft*lbs",.7376, "w*hr",2.778e-4,"kw*hr",2.778e-7, "kcal", 0.000239006} } l = length(Unit) global function convert_unit(atom val, sequence from, sequence To ) integer f, t, i1, i2 f = 0 t = 0 for a = 1 to l do -- indexes from and To units if not f then f = find(from, Unit[a]) i1=a end if if not t then t = find( To, Unit[a]) i2=a end if end for if not f or not t then return {not f, not t, 0} -- Error for unsupported units end if if i1 != i2 then return {-1, -1, 0} -- Error for mis-matched units end if val /= Unit[i1][f+1] -- converts val to base unit val *= Unit[i1][t+1] -- converts val to To unit return {0, 0, val} -- return no error and converted value end function -- additional routines added by Kenneth Rhodes -- index of categories global constant index = {"Length", "Time", "Velocity", "Angles", "Angular Velocity","Area", "Volume", "Weight", "Pressure", "Energy"} global object ul = { -- unit labels {}, -- sequence of "from" unit labels {} -- sequence of "to" unit labels } global constant Fr =1, To=2 -- sequence ul (unit labels) subsequence index -- used to select "from" and "to" unit labels --obtain sequence of category unit labels from index sequence global function SelectUnit(sequence category) integer i object cs ={} i = find(category, index) for a = 1 to length(Unit[i]) by 2 do cs = append(cs, Unit[i][a]) end for return cs end function -- test --sequence s = select_unit("Length") --for x = 1 to length(s) do -- printf(1, "%s\n", {s[x]}) --end for
I have encountered a number of problems. My plan was/is to use a ComboBox to display the sequence of unit categories from which I could select a specific category to use such as "length" or "area".
I envisioned a simple horizontal window layout with six "fields":
Category[index] [v1] [unit label 1] to [unit label 2] [v2]
"Category" is a label, [index] is a GtkComboBoxText displaying an index sequence of unit categories from which a specific category can be selected such as "length" or "area". The selected category then becomes "current" and is used as an index to select a sequence of unit labels pertinent to the current category from the master Unit sequence.
[v1] is a GtkEntry field where the user enters the value to be converted.
[unit label 1] is a GtkComboBoxText displaying the sequence list of unit labels pertinent to the selected category. From this list the unit label/type for the value v1 is selected.
"To" is a label
[unit label 2] is a GtkComboBox displaying the same list of unit labels, perhaps with label previously selected for unit label 1 removed. From this list The target "To" unit label/type is selected
[v2] is a calculated field displays the new value converted from v1.
Well, I can display and select from the index sequence and pass the selection to the two unit label combo boxes. I also can enter and retrieve a numeric value for V1. I cannot obtain a calculated converted value for V2.
My update routine does not work. I can select a new index category but it seems that my unit labels are stuck listing the unit labels for the initial listed category in the index sequence, "length".
- -- ConvertUnits.exw -- -- adapted from Irv's GtkComboBoxText Demo -- ----------------------------------------------------------------------------------- --# GtkComboBoxText selects from a limited set of choices. -- This is fine for most purposes, and easy to set up. See the GTk docs on how to -- use a GtkComboBox with a model for more complex uses. ----------------------------------------------------------------------------------- include GtkEngine.e include convert.e --constant docs = "<b><u>Convert Units</u></b>" constant docs = "Unit Catgory" constant win = create(GtkWindow,"border_width=10,position=1,$destroy=Quit"), panel = create(GtkBox,"orientation=HORIZONTAL,spacing=10"), lbl = create(GtkLabel), cb1 = create(GtkComboBoxText), -- index V1 = create(GtkEntry,"width-chars=8"), -- value to convert cb2 = create(GtkComboBoxText), -- "From" unit labels cb3 = create(GtkComboBoxText), -- "To" unit labels V2 = create(GtkEntry,"width-chars=8, %activate=ConvertUnit"), btnbox = create(GtkButtonBox,"spacing=5"), btn1 = create(GtkButton,"gtk-ok","Selection"), btn2 = create(GtkButton,"gtk-quit","Quit") ------------------------------------------------------------------ object ToV set(lbl,"text",docs) add(cb1,index) set(cb1,"active",1) -- see Note below add(V1, "text") ul[Fr] = SelectUnit(get(cb1, "active text")) add(cb2, ul[Fr]) ul[To] = SelectUnit(get(cb1, "active text")) add(cb3, ul[To]) add(V2, "text") add(win,panel) add(panel,lbl) add(panel,cb1) add(panel, V1) add(panel,cb2) add(panel,cb3) add(panel, V2) pack_end(panel,btnbox) add(btnbox,{btn1,btn2}) show_all(win) main() global function UpDate() atom x get(cb1, "text") get(V1, "text") set(V1, "active", 1) ul[Fr] = SelectUnit(get(cb1, "active text")) set(cb2, ul[Fr], "active", 1) ul[To] = SelectUnit(get(cb1, "active text")) set(cb3, ul[To], "active", 1) x = Convert_Unit() set(V2, x, 0) return 1 end function UpDate() global function Convert_Unit() UpDate() atom x x = get(V1, "text") x= to_number(x) ToV = convert_unit( x, sprintf("%s", {get(cb2, "active text")}), sprintf("%s", {get(cb3, "active text")})) -- convert_unit(x, get(cb2, "active text"), get(cb3, "active text")) x = ToV[3] set(V2, x) return x end function ------------------------------------------------------------- global function Selection() ------------------------------------------------------------- --UpDate() return Info(win,"Unit Conversion",{ get(cb1,"active text"), to_number(get(V1,"text")),get(cb2,"active text"), " to ", get(cb3,"active text"), " = ", get(V2, "text")}) end function -- Note: -- We set the first item to be 'active', which means it will -- be the one initially shown. Otherwise, nothing will be shown -- until the user clicks to drop down the list of items.