1 # -*- coding: utf-8 -*-
10 from . import __progname__
as progname
11 from . import __version__
as version
13 class MainFrame(wx
.Frame
):
19 def __init__(self
, *args
, **kw
):
20 """add to the init process for the wx.Frame"""
21 super(MainFrame
, self
).__init
__(*args
, **kw
)
24 self
.SetTitle(progname
)
25 self
.SetSize(600, 400)
27 self
.props
= self
.init_props()
28 self
.pnl
= wx
.Panel(self
)
31 self
.wx_items
= dict()
32 self
.wx_items
['StaticText'] = dict()
33 self
.wx_items
['TextEntry'] = dict()
34 self
.wx_items
['RadioButton'] = dict()
35 self
.wx_items
['ComboBox'] = dict()
37 # setup the GUI itself
38 self
.create_wx_items()
39 self
.establish_wx_bindings()
45 """centralized place to initialize props var"""
48 props
['elevation'] = 0
49 props
['fitness'] = 'average'
50 props
['units'] = 'imperial'
51 props
['travel_mode'] = 'uphill'
54 def create_wx_items(self
):
55 """create wxPython items"""
56 # title bar / program name
57 self
.program_name
= wx
.StaticText(self
.pnl
, label
=progname
)
58 font
= self
.program_name
.GetFont()
62 self
.program_name
.SetFont(font
)
65 self
.wx_items
['StaticText']['distance'] = wx
.StaticText(self
.pnl
,
68 self
.wx_items
['TextEntry']['distance'] = wx
.TextCtrl(self
.pnl
,
72 self
.wx_items
['StaticText']['elevation'] = wx
.StaticText(self
.pnl
,
75 self
.wx_items
['TextEntry']['elevation'] = wx
.TextCtrl(self
.pnl
,
79 self
.wx_items
['StaticText']['fitness'] = wx
.StaticText(self
.pnl
,
82 rb_fitness_choices
= ['slow', 'average', 'fast']
83 rb_fitness_default
= 'average'
84 self
.wx_items
['RadioButton']['fitness'] = wx
.ComboBox(self
.pnl
,
85 choices
=rb_fitness_choices
,
86 value
=rb_fitness_default
,
89 self
.wx_items
['StaticText']['travel_mode'] = wx
.StaticText(self
.pnl
,
90 label
="Travel Mode: ",
92 rb_travel_mode_choices
= ['uphill', 'flat', 'downhill', 'bushwhacking']
93 rb_travel_mode_default
= 'uphill'
94 self
.wx_items
['RadioButton']['travel_mode'] = wx
.ComboBox(self
.pnl
,
95 choices
=rb_travel_mode_choices
,
96 value
=rb_travel_mode_default
,
99 self
.wx_items
['StaticText']['units'] = wx
.StaticText(self
.pnl
,
101 style
=wx
.ALIGN_RIGHT
)
102 rb_units_choices
= ['imperial', 'metric']
103 rb_units_default
= 'imperial'
105 self
.wx_items
['RadioButton']['units'] = []
106 for choice
in rb_units_choices
:
108 style
= wx
.RB_GROUP
if choice
== rb_units_default
else 0
109 self
.wx_items
['RadioButton']['units'].append(wx
.RadioButton(self
.pnl
,
114 self
.wx_items
['StaticText']['mtc'] = wx
.StaticText(self
.pnl
,
116 style
=wx
.ALIGN_CENTRE_HORIZONTAL
)
118 st_mtc_font
= self
.program_name
.GetFont()
119 st_mtc_font
.PointSize
+= 10
120 self
.wx_items
['StaticText']['mtc'].SetFont(st_mtc_font
)
123 self
.b_reset
= wx
.Button(self
.pnl
, wx
.NewId(), '&Reset', (-1, -1),
126 def establish_wx_bindings(self
):
127 """establish wxPython bindings"""
128 self
.pnl
.Bind(wx
.EVT_TEXT
, self
.update_distance
, self
.wx_items
['TextEntry']['distance'])
129 self
.pnl
.Bind(wx
.EVT_TEXT
, self
.update_elevation
, self
.wx_items
['TextEntry']['elevation'])
130 self
.wx_items
['RadioButton']['fitness'].Bind(wx
.EVT_COMBOBOX
, self
.update_fitness
)
131 self
.wx_items
['RadioButton']['travel_mode'].Bind(wx
.EVT_COMBOBOX
, self
.update_travel_mode
)
132 self
.b_reset
.Bind(wx
.EVT_BUTTON
, self
.reset
)
134 for rb_unit
in self
.wx_items
['RadioButton']['units']:
135 rb_unit
.Bind(wx
.EVT_RADIOBUTTON
, self
.update_units
)
137 def do_wx_layout(self
):
138 """layout the wxPython items"""
142 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
143 sizer
.Add(self
.program_name
, wx
.SizerFlags().Border(wx
.TOP|wx
.LEFT
, 0))
145 static_line
= wx
.StaticLine(self
.pnl
, wx
.NewId(), style
=wx
.LI_HORIZONTAL
)
147 hsizer_distance
= wx
.BoxSizer(wx
.HORIZONTAL
)
148 hsizer_distance
.Add(self
.wx_items
['StaticText']['distance'], 0, wx
.RIGHT
, border
)
149 hsizer_distance
.Add(self
.wx_items
['TextEntry']['distance'], 1, wx
.GROW
, border
)
150 hsizer_distance
.SetItemMinSize(self
.wx_items
['StaticText']['distance'], (width
, -1))
152 hsizer_elevation
= wx
.BoxSizer(wx
.HORIZONTAL
)
153 hsizer_elevation
.Add(self
.wx_items
['StaticText']['elevation'], 0, wx
.RIGHT
, border
)
154 hsizer_elevation
.Add(self
.wx_items
['TextEntry']['elevation'], 1, wx
.GROW
, border
)
155 hsizer_elevation
.SetItemMinSize(self
.wx_items
['StaticText']['elevation'], (width
, -1))
157 hsizer_fitness
= wx
.BoxSizer(wx
.HORIZONTAL
)
158 hsizer_fitness
.Add(self
.wx_items
['StaticText']['fitness'], 0, wx
.RIGHT
, border
)
159 hsizer_fitness
.Add(self
.wx_items
['RadioButton']['fitness'], 1, wx
.GROW
, border
)
160 hsizer_fitness
.SetItemMinSize(self
.wx_items
['StaticText']['fitness'], (width
, -1))
162 hsizer_travel_mode
= wx
.BoxSizer(wx
.HORIZONTAL
)
163 hsizer_travel_mode
.Add(self
.wx_items
['StaticText']['travel_mode'], 0, wx
.RIGHT
, border
)
164 hsizer_travel_mode
.Add(self
.wx_items
['RadioButton']['travel_mode'], 1, wx
.GROW
, border
)
165 hsizer_travel_mode
.SetItemMinSize(self
.wx_items
['StaticText']['travel_mode'], (width
, -1))
167 hsizer_units
= wx
.BoxSizer(wx
.HORIZONTAL
)
168 hsizer_units
.Add(self
.wx_items
['StaticText']['units'], 0, wx
.RIGHT
, border
)
169 for rb_unit
in range(len(self
.wx_items
['RadioButton']['units'])):
170 hsizer_units
.Add(self
.wx_items
['RadioButton']['units'][rb_unit
],
174 hsizer_units
.SetItemMinSize(self
.wx_items
['StaticText']['units'], (width
, -1))
176 hsizer_mtc
= wx
.BoxSizer(wx
.HORIZONTAL
)
177 hsizer_mtc
.Add(self
.wx_items
['StaticText']['mtc'], 1, wx
.GROW
, border
)
178 hsizer_mtc
.SetItemMinSize(self
.wx_items
['StaticText']['mtc'], (width
, -1))
180 hsizer5
= wx
.BoxSizer(wx
.HORIZONTAL
)
181 hsizer5
.Add(self
.b_reset
, 0)
183 vsizer1
= wx
.BoxSizer(wx
.VERTICAL
)
184 vsizer1
.Add(sizer
, 0, wx
.EXPAND | wx
.ALL
, border
*border
)
185 vsizer1
.Add(hsizer_distance
, 0, wx
.EXPAND | wx
.ALL
, border
)
186 vsizer1
.Add(hsizer_elevation
, 0, wx
.EXPAND | wx
.ALL
, border
)
187 vsizer1
.Add(hsizer_fitness
, 0, wx
.EXPAND | wx
.ALL
, border
)
188 vsizer1
.Add(hsizer_travel_mode
, 0, wx
.EXPAND | wx
.ALL
, border
)
189 vsizer1
.Add(hsizer_units
, 0, wx
.EXPAND | wx
.ALL
, border
)
190 vsizer1
.Add(hsizer_mtc
, 0, wx
.EXPAND | wx
.ALL
, border
)
191 vsizer1
.Add(static_line
, 0, wx
.GROW | wx
.ALL
, border
)
192 vsizer1
.Add(hsizer5
, 0, wx
.ALIGN_RIGHT | wx
.ALL
, border
)
194 self
.pnl
.SetSizerAndFit(vsizer1
)
195 self
.pnl
.SetClientSize(vsizer1
.GetSize())
198 def update_distance(self
, event
):
199 """updates distance prop"""
200 value
= event
.GetEventObject().GetValue()
203 new_val
= float(value
)
204 self
.props
['distance'] = new_val
206 # reset GUI to last-accepted val
207 self
.wx_items
['TextEntry']['distance'].SetValue(str(self
.props
['distance']))
210 def update_elevation(self
, event
):
211 """updates elevation prop"""
212 value
= event
.GetEventObject().GetValue()
216 self
.props
['elevation'] = new_val
218 # reset GUI to last-accepted val
219 self
.wx_items
['TextEntry']['elevation'].SetValue(str(self
.props
['elevation']))
222 def update_fitness(self
, event
):
223 """updates fitness prop"""
224 value
= event
.GetEventObject().GetValue()
226 self
.props
['fitness'] = value
229 def update_travel_mode(self
, event
):
230 """updates travel_mode prop"""
231 value
= event
.GetEventObject().GetValue()
233 self
.props
['travel_mode'] = value
236 def update_units(self
, event
):
237 """updates units prop"""
238 value
= event
.GetEventObject().GetLabel()
240 self
.props
['units'] = value
243 def reset(self
, event
):
244 """resets all values"""
246 self
.props
= self
.init_props()
247 self
.wx_items
['TextEntry']['distance'].SetValue(str(self
.props
['distance']))
248 self
.wx_items
['TextEntry']['elevation'].SetValue(str(self
.props
['elevation']))
249 self
.wx_items
['RadioButton']['fitness'].SetValue(str(self
.props
['fitness']))
250 self
.wx_items
['RadioButton']['travel_mode'].SetValue(str(self
.props
['travel_mode']))
251 # leave units as the user selected
255 def update_mtc(self
):
256 """updates mtc, the final result the user wants"""
257 if (self
.props
['distance'] is None) or (self
.props
['elevation'] is None):
260 est
= munter
.time_calc(self
.props
['distance'],
261 self
.props
['elevation'],
262 self
.props
['fitness'],
263 self
.props
['travel_mode'],
266 hours
= int(est
['time'])
267 minutes
= int((est
['time'] - hours
) * 60)
268 self
.wx_items
['StaticText']['mtc'].SetLabel("{human_time}".format(
269 human_time
="{hours} hours {minutes} minutes".format(
276 """kick off the GUI"""
278 frm
= MainFrame(None)