From 4362afe83d6bb078358931e121c54102b77cfc70 Mon Sep 17 00:00:00 2001 From: Chris Kiehl Date: Mon, 20 Jan 2014 13:21:18 -0500 Subject: [PATCH] Added a bunch of stuff --- src/app/dialogs/advanced_config.py | 76 +++++++------- src/app/dialogs/advanced_config.pyc | Bin 4229 -> 4551 bytes .../advanced_config_integration_test.py | 18 ++++ src/app/dialogs/argparse_test_data.py | 1 - src/app/dialogs/base_window.py | 75 ++++++++++++++ src/app/dialogs/basic_config_panel.py | 60 +++++++++++ src/app/dialogs/body.py | 2 +- src/app/dialogs/component_factory.py | 31 ++---- src/app/dialogs/component_factory.pyc | Bin 3070 -> 2963 bytes src/app/dialogs/components.py | 2 +- src/app/dialogs/display_main.py | 95 +++++++++--------- src/app/dialogs/display_main.pyc | Bin 4468 -> 4994 bytes src/app/dialogs/footer.py | 36 +++++-- src/app/dialogs/footer.pyc | Bin 3779 -> 4125 bytes src/app/dialogs/header.py | 92 +++++++++++------ src/app/dialogs/header.pyc | Bin 2983 -> 4229 bytes src/app/dialogs/imageutil.py | 49 +++++++++ src/app/dialogs/option_reader.py | 25 +++++ src/app/dialogs/segoe_statictext.py | 28 ++++++ src/app/dialogs/window.py | 62 ++++++++++++ src/app/images/image_store.py | 12 ++- src/app/images/image_store.pyc | Bin 776 -> 976 bytes src/app/images/settings.png | Bin 0 -> 16453 bytes src/app/images/settings2.png | Bin 0 -> 18332 bytes src/model/gui.py | 4 +- 25 files changed, 517 insertions(+), 151 deletions(-) create mode 100644 src/app/dialogs/advanced_config_integration_test.py create mode 100644 src/app/dialogs/base_window.py create mode 100644 src/app/dialogs/basic_config_panel.py create mode 100644 src/app/dialogs/imageutil.py create mode 100644 src/app/dialogs/option_reader.py create mode 100644 src/app/dialogs/segoe_statictext.py create mode 100644 src/app/dialogs/window.py create mode 100644 src/app/images/settings.png create mode 100644 src/app/images/settings2.png diff --git a/src/app/dialogs/advanced_config.py b/src/app/dialogs/advanced_config.py index 9f5a130..3744dc9 100644 --- a/src/app/dialogs/advanced_config.py +++ b/src/app/dialogs/advanced_config.py @@ -10,11 +10,12 @@ from wx.lib import wordwrap from itertools import chain from component_factory import ComponentFactory from wx.lib.scrolledpanel import ScrolledPanel +from app.dialogs.option_reader import OptionReader PADDING = 10 -class AdvancedConfigPanel(ScrolledPanel): +class AdvancedConfigPanel(ScrolledPanel, OptionReader): ''' Abstract class for the Footer panels. ''' @@ -24,46 +25,46 @@ class AdvancedConfigPanel(ScrolledPanel): self.components = ComponentFactory(parser) - self.container = wx.BoxSizer(wx.VERTICAL) - self.container.AddSpacer(15) + self._msg_req_args = self.BuildHeaderMsg("Required Arguments") + self._msg_opt_args = self.BuildHeaderMsg("Optional Arguments") - self.AddHeaderMsg("Required Arguments") - self.container.AddSpacer(10) + self._do_layout() + self.Bind(wx.EVT_SIZE, self.OnResize) - box = wx.StaticBox(self, label="") - boxsizer = wx.StaticBoxSizer(box, wx.VERTICAL) - self.AddWidgets(self.container, self.components.positionals, add_space=True) + def _do_layout(self): + STD_LAYOUT = (0, wx.LEFT | wx.RIGHT | wx.EXPAND, PADDING) + container = wx.BoxSizer(wx.VERTICAL) + container.AddSpacer(15) - self.container.AddSpacer(10) - self.container.Add(self._draw_horizontal_line(), - 0, wx.LEFT | wx.RIGHT | wx.EXPAND, PADDING) + container.Add(self._msg_req_args, 0, wx.LEFT | wx.RIGHT, PADDING) + container.AddSpacer(5) + container.Add(self._draw_horizontal_line(), *STD_LAYOUT) + container.AddSpacer(20) - self.container.AddSpacer(10) - self.AddHeaderMsg("Optional Arguments") - self.container.AddSpacer(15) + self.AddWidgets(container, self.components.required_args, add_space=True) - flag_grids = self.CreateComponentGrid(self.components.flags, vgap=15) - opt_choice_counter_grid = self.CreateComponentGrid(c for c in self.components - if not isinstance(c, components.Flag) - and not isinstance(c, components.Positional)) - self.container.Add(opt_choice_counter_grid, 0, wx.LEFT | wx.RIGHT | wx.EXPAND, PADDING) - self.container.AddSpacer(30) - self.container.Add(flag_grids, 0, wx.LEFT | wx.RIGHT | wx.EXPAND, PADDING) + container.AddSpacer(10) -# sizer_params = [(grid, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, PADDING) -# for grid in component_grids] -# self.container.AddMany(sizer_params) - self.SetSizer(self.container) - self.Bind(wx.EVT_SIZE, self.OnResize) - + container.AddSpacer(10) + container.Add(self._msg_opt_args, 0, wx.LEFT | wx.RIGHT, PADDING) + container.AddSpacer(5) + container.Add(self._draw_horizontal_line(), *STD_LAYOUT) + container.AddSpacer(20) + + flag_grids = self.CreateComponentGrid(self.components.flags, cols=3, vgap=15) + general_opts_grid = self.CreateComponentGrid(self.components.general_options) + container.Add(general_opts_grid, *STD_LAYOUT) + container.AddSpacer(30) + container.Add(flag_grids, *STD_LAYOUT) + + self.SetSizer(container) - def AddHeaderMsg(self, label): - required_msg = wx.StaticText(self, label=label) - font_size = required_msg.GetFont().GetPointSize() + def BuildHeaderMsg(self, label): + _msg = wx.StaticText(self, label=label) + font_size = _msg.GetFont().GetPointSize() bold = wx.Font(font_size*1.2, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD) - required_msg.SetFont(bold) - self.container.Add(required_msg, 0, wx.LEFT | wx.RIGHT, PADDING) - + _msg.SetFont(bold) + return _msg def AddWidgets(self, sizer, components, add_space=False, padding=PADDING): for component in components: @@ -83,9 +84,16 @@ class AdvancedConfigPanel(ScrolledPanel): return line def OnResize(self, evt): - print evt.m_size + print 'SIZEEEE:', evt.m_size for component in self.components: component.Update(evt.m_size) + evt.Skip() + + def GetOptions(self): + ''' + returns the collective values from all of the + widgets contained in the panel''' + raise NotImplementedError diff --git a/src/app/dialogs/advanced_config.pyc b/src/app/dialogs/advanced_config.pyc index 81da9b857b5dee72e725476fb6be2ecaae1942cf..17ee5502fab7677e271bbaadd7243cf1f7e81ee8 100644 GIT binary patch literal 4551 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 M|J-Wn18>>+A4tdCmH+?% delta 1881 zcma)6-)|d55T3pBo$u^(Y^Sx;lF%dtkxN8FDt-wOHBG1jQq&|mL#qa=)8%gCp6l4o z-MU0of{_v=`T(d}frNPB4?z44JRtGdSDxS%o{M;9X3q&xB_y2e+|1t2%s1c6-Y+kF zHa)ICEfxOy`ByK5;ZMisbzJEekH@zc@~~Be$O2w~9R`sN#{fqFceWhhC5Q@eUxVZk zbO0g^8gB9NPmiR}USXT^D>nTaH-MWE>2R#URvw}pL!~76_3qc|E{}WE} zECTez?hQQ$|6R$2VX70(FRG)@soim6ltqBU;b1e@<1)2$6otq4`fV z#s%C)q5#^#Hg5}5K-egPDDn$wF9>-|d-91kHV`?~9yEhq$WYO6kz-2hZ4^kx-K%iO z0HYkBWYEH)(7;LbGg~+p*%ltT#rAYiKq=t5OYsFEiqp80il7s6Wrp3|Ubiz(fE9+- zcFr zhjzvB6cObA@xI(LCkJ7-BZ9cY6Gg{z6g7y9L=dHDy~l%yCpXikdfgC#h{Kicz8JyR zr&c3=h#nLfJ#NQQlVbrzG<&DGvx44F`drXw0MFsP;ysgJn>BgWoRhzqmuqx48(d`J zh@_Rc6Um4AIJ4w8`jsW+x{cZCAU@O6ygSI0-%R2t6=V3W+Y^3xuN#Nl54-)2;0e8y z*X;GtMUTIaXnFMumkZqd?>E4#oIX zj#zhB@fO?kZ8*^AgM?Fop8}E&UdocXl&bes(7H#y%~#d$>5`f`m$>w*@=NRZb?-ds z6C|i<-Xw`>6fXIBE(y|9dy?Up%a`oFQODgy`MoV~&7!6P$3&Bxr{m{XbER3@F`mcWO}ST^$}ONKzb(x! zkHT%mXm*<@o1kgm^$Bn`;bec%ivqzjG{l@5AO1ji*W^<5qq;XkXK<;j0?fiTyG8k9 z`Q=#}5|0>FG^_^gl&dbN3OvH;5iD;;mMYtCQO#6sN{uvili4%2RnC_U+fbA0`@49< td_QaS205w*6yy&T-^l_~4DTj}3*>jz(F-&NrsgmQF{wYz)az>w`v=j{PkaCX diff --git a/src/app/dialogs/advanced_config_integration_test.py b/src/app/dialogs/advanced_config_integration_test.py new file mode 100644 index 0000000..14c5af8 --- /dev/null +++ b/src/app/dialogs/advanced_config_integration_test.py @@ -0,0 +1,18 @@ +''' +Created on Jan 19, 2014 + +@author: Chris +''' + +import argparse_test_data + + +client_parser_obj = argparse_test_data.parser + +frame = MainWindow(client_parser_obj) + + + + +if __name__ == '__main__': + pass \ No newline at end of file diff --git a/src/app/dialogs/argparse_test_data.py b/src/app/dialogs/argparse_test_data.py index 032cc17..2b50c33 100644 --- a/src/app/dialogs/argparse_test_data.py +++ b/src/app/dialogs/argparse_test_data.py @@ -19,4 +19,3 @@ parser.add_argument('-c', '--constoption', action="store_const", const="myconsta parser.add_argument('-t', '--truify', action="store_true", help='Ensure the store_true actions are sorted') # Flag parser.add_argument('-f', '--falsificle', action="store_false", help='Ensure the store_false actions are sorted') # Flag - \ No newline at end of file diff --git a/src/app/dialogs/base_window.py b/src/app/dialogs/base_window.py new file mode 100644 index 0000000..f975cc9 --- /dev/null +++ b/src/app/dialogs/base_window.py @@ -0,0 +1,75 @@ +''' +Created on Jan 19, 2014 + +@author: Chris +''' + +import os +import wx +import header +import footer +from model.controller import Controller +from app.images import image_store + +class BaseWindow(wx.Frame): + + def __init__(self, BodyPanel, parser): + wx.Frame.__init__( + self, + parent=None, + id=-1, + title=os.path.basename(__file__), + size=(610,530) + ) + + self._parser = parser + self._controller = Controller() + + self._init_properties() + self._init_components(BodyPanel) + self._do_layout() + + def _init_properties(self): + self.SetMinSize((400,300)) + self.icon = wx.Icon(image_store.icon, wx.BITMAP_TYPE_ICO) + self.SetIcon(self.icon) + + def _init_components(self, BodyPanel): + # init components + self.head_panel = header.FrameHeader( + heading="Settings", + subheading = self._parser.description, + image_path=image_store.settings2, + parent=self, + size=(30,90)) + self.body_panel = BodyPanel(self, self._parser) + self.cfg_foot_panel = footer.ConfigFooter(self, self._controller) +# self.main_foot_panel = footer.MainFooter(self, self._controller) +# self.main_foot_panel.Hide() + + def _do_layout(self): + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(self.head_panel, 0, wx.EXPAND) + self._draw_horizontal_line(sizer) + sizer.Add(self.body_panel, 1, wx.EXPAND) + self._draw_horizontal_line(sizer) + sizer.Add(self.cfg_foot_panel, 0, wx.EXPAND) + self.SetSizer(sizer) + +# def _init_panels(self): +# self._frame_header = FrameHeader +# self._basic_config_body = None +# self._adv_config_body = None +# self._config_footer = None +# self._output_footer = None + + def _draw_horizontal_line(self, sizer): + line = wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL) + line.SetSize((10, 10)) + sizer.Add(line, 0, wx.EXPAND) + + + + +if __name__ == '__main__': + pass \ No newline at end of file diff --git a/src/app/dialogs/basic_config_panel.py b/src/app/dialogs/basic_config_panel.py new file mode 100644 index 0000000..d2535a1 --- /dev/null +++ b/src/app/dialogs/basic_config_panel.py @@ -0,0 +1,60 @@ +''' +Created on Dec 9, 2013 + +@author: Chris + + +''' + +import wx +import os +from app.dialogs.option_reader import OptionReader + +class BasicDisplayPanel(wx.Panel, OptionReader): + def __init__(self, parent, **kwargs): + wx.Panel.__init__(self, parent, **kwargs) + + self.SetBackgroundColour('#F0F0F0') + + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.AddSpacer(10) + +# about_header = wx.StaticText(self, label="About") +# about_header = self._bold_static_text("About") +# about_body = wx.StaticText(self, label="This program does bla. Enter the command line args of your choice to control bla and bla.") +# +# sizer.Add(about_header, 0, wx.LEFT | wx.RIGHT, 20) +# sizer.AddSpacer(5) +# sizer.Add(about_body, 0, wx.LEFT | wx.RIGHT, 20) + + sizer.AddSpacer(40) + + text = self._bold_static_text("Enter Command Line Arguments") +# + sizer.Add(text, 0, wx.LEFT, 20) + sizer.AddSpacer(10) + + h_sizer = wx.BoxSizer(wx.HORIZONTAL) + self.cmd_textbox = wx.TextCtrl(self, -1, "") + + h_sizer.Add(self.cmd_textbox, 1, wx.ALL | wx.EXPAND) + + sizer.Add(h_sizer, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, 20) + + self.SetSizer(sizer) + + def get_contents(self): + return self.cmd_textbox.GetValue() + + def _bold_static_text(self, text_label): + text = wx.StaticText(self, label=text_label) + font_size = text.GetFont().GetPointSize() + bold = wx.Font(font_size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD) + text.SetFont(bold) + return text + + def GetValues(self): + raise NotImplementedError + + + diff --git a/src/app/dialogs/body.py b/src/app/dialogs/body.py index c4e1a6c..55cc53e 100644 --- a/src/app/dialogs/body.py +++ b/src/app/dialogs/body.py @@ -6,7 +6,7 @@ Created on Dec 23, 2013 import wx -class BodyDisplayPanel(wx.Panel): +class BasicDisplayPanel(wx.Panel): def __init__(self, parent, **kwargs): wx.Panel.__init__(self, parent, **kwargs) diff --git a/src/app/dialogs/component_factory.py b/src/app/dialogs/component_factory.py index 5fbbd16..b00b672 100644 --- a/src/app/dialogs/component_factory.py +++ b/src/app/dialogs/component_factory.py @@ -12,27 +12,18 @@ import argparse_test_data class ComponentFactory(object): ''' - Aggregates all of the Widgets and dispatches - them to the caller. + Aggregates all of the actions and ''' def __init__(self, parser): self._actions = action_sorter.ActionSorter(parser._actions[:]) - self.positionals = self.BuildPositionals(self._actions) - self.choices = self.BuildChoices(self._actions) - self.optionals = self.BuildOptionals(self._actions) - self.flags = self.BuildFlags(self._actions) - self.counters = self.BuildCounters(self._actions) - - self._components = [ - self.positionals, - self.choices, - self.optionals, - self.flags, - self.counters - ] + self.required_args = self.BuildPositionals(self._actions) + self.flags = self.BuildFlags(self._actions) + self.general_options = (self.BuildChoices(self._actions) + + self.BuildOptionals(self._actions) + + self.BuildCounters(self._actions)) def BuildPositionals(self, actions): return self._AssembleWidgetsFromActions(actions, 'Positional', '_positionals') @@ -55,15 +46,13 @@ class ComponentFactory(object): return [cls(action) for action in actions_list] -# def __getitem__(self, slice): -# return self._components[slice] - def __iter__(self): ''' - return an iterator for all of the contained - components + return an iterator for all of the contained components ''' - return itertools.chain(*self._components) + return itertools.chain(self.required_args, + self.flags, + self.general_options) if __name__ == '__main__': a = ComponentFactory(argparse_test_data.parser) diff --git a/src/app/dialogs/component_factory.pyc b/src/app/dialogs/component_factory.pyc index d73e05acaffb590af7e5c7ce39ebf0f74f3c36f4..9d0665b965765dcb7ef9a120940a62d1f66719aa 100644 GIT binary patch delta 659 zcmZuu&r2IY6rS11?q((%Q-v7XrWk|bR!fbD7mHAuQd%e;Mm%_E$7QpIgt)7_n?s8y z6$G#EEO__Sf292fO88S>U?KIL@Oq%WGKa zM{$$}Ba@ua%CIBOXXmh-mC-S4-m3GufFI&B_u!zE@FuLf+aT;G4`#9N(@~n{=sD=v z#wON60r_e#PKQW@vdiIFg&SFgZR+;wa8DC8ck}oov=gS?!Xmpeuew zdwBLo=%{LK18bRsj+H#_aCobpKb^r$(|k?BXgXaJMAI3X*49htd`9BIy_#7UjwO{8 k|DKZ*)0pF65F6tcycOcL$u;3crQv zwYT{Lo&^v68Qwgp7Z3Ui1n=T|({4cskN5U_Z@!oJ@;-XR$w`!R(XkK!fMVY^pafTvOw zx{y^`D&2;BdtQ{;a4ZXvEA2x;nD^}5;{cGH*2J(TJ}A?X(zyF`i#qkgP|hoz&y;RL zMbrrntWGS_S{R0DY(vcpzJSt7Ia{{e|hVRp1F$$+A?$hjdwDYH9u_Q zD!0HD{x+dqFoz1fGdk{Qb?pJrAgNXIfRV#m4RzoAZr;2T2EplN6eO{O4S4qg4ymOC zf$-2`oEBBG1juTcbWOh{mN`cj=l7tla3*ohk6>`Q4=8D1z~dyiVuI==_*W8KJ-KQ& s!`WuTW5JogIkmtl$N2=NaUR>AYe?U~ux`GDH@p~O&v>nO&h0k+2THG)IsgCw diff --git a/src/app/dialogs/components.py b/src/app/dialogs/components.py index b3fc3eb..6ad1b2f 100644 --- a/src/app/dialogs/components.py +++ b/src/app/dialogs/components.py @@ -232,7 +232,7 @@ class Flag(AbstractComponent): return help_msg = self._msg width, height = size - content_area = int((width/2)*.70) + content_area = int((width/3)*.70) print 'wiget size', help_msg.Size[0] wiggle_room = range(int(content_area - content_area * .05), int(content_area + content_area * .05)) diff --git a/src/app/dialogs/display_main.py b/src/app/dialogs/display_main.py index 131abdf..35830b7 100644 --- a/src/app/dialogs/display_main.py +++ b/src/app/dialogs/display_main.py @@ -11,8 +11,9 @@ import threading from model.controller import Controller from app.images import image_store from app.dialogs.header import FrameHeader -from app.dialogs.body import BodyDisplayPanel +from app.dialogs.basic_config_panel import BasicDisplayPanel from app.dialogs.footer import ConfigFooter +from app.dialogs.advanced_config import AdvancedConfigPanel class MessagePump(object): def __init__(self, queue): @@ -25,22 +26,23 @@ class MessagePump(object): self.queue.put(text) +class Listener(threading.Thread): + def __init__(self, queue, textbox): + threading.Thread.__init__(self) + self.queue = queue + self.update_text = lambda x: textbox.AppendText(x) + + def run(self): + while True: + try: + stdout_msg = self.queue.get(timeout=1) + if stdout_msg != '': + self.update_text(stdout_msg) + except Exception as e: + pass # Timeout. Aint nobody care 'bout dat + + class MainWindow(wx.Frame): - - class Listener(threading.Thread): - def __init__(self, queue, textbox): - threading.Thread.__init__(self) - self.queue = queue - self.update_text = lambda x: textbox.AppendText(x) - - def run(self): - while True: - try: - stdout_msg = self.queue.get(timeout=1) - if stdout_msg != '': - self.update_text(stdout_msg) - except Exception as e: - pass # Timeout. Aint nobody care 'bout dat def __init__(self, queue, payload=None): wx.Frame.__init__( @@ -53,49 +55,52 @@ class MainWindow(wx.Frame): self._controller = Controller() - self._frame_header = FrameHeader - self._simple_config_body = None - self._adv_config_body = None - self._config_footer = None - self._output_footer = None + + self._init_properties() self._init_components() - - self.queue = queue - # the client's main function - self._payload = payload + self._do_layout() + + self.queue = queue + # the client's main function + self._payload = payload _stdout = sys.stdout sys.stdout = MessagePump(queue) - listener = MainWindow.Listener(queue, self.panel2.cmd_textbox) + listener = Listener(queue, self.body_panel.cmd_textbox) listener.start() - def _init_components(self): - # init components + def _init_properties(self): self.SetMinSize((400,300)) self.icon = wx.Icon(image_store.icon, wx.BITMAP_TYPE_ICO) self.SetIcon(self.icon) - panel1 = FrameHeader(image_path=image_store.computer3, parent=self, size=(30,90)) - - self.sizer = wx.BoxSizer(wx.VERTICAL) - self.sizer.Add(panel1, 0, wx.EXPAND) - - self._draw_horizontal_line() - - self.panel2 = BodyDisplayPanel(parent=self) - self.sizer.Add(self.panel2, 1, wx.EXPAND) - self.SetSizer(self.sizer) - - self._draw_horizontal_line() - - self.footer = ConfigFooter(self, self._controller) - self.sizer.Add(self.footer, 0, wx.EXPAND) + def _init_components(self): + # init components + self.head_panel = FrameHeader(image_path=image_store.computer3, parent=self, size=(30,90)) + self.body_panel = BasicDisplayPanel(parent=self) + self.foot_panel = ConfigFooter(self, self._controller) + + def _do_layout(self): + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(self.head_panel, 0, wx.EXPAND) + self._draw_horizontal_line(sizer) + sizer.Add(self.body_panel, 1, wx.EXPAND) + self._draw_horizontal_line(sizer) + sizer.Add(self.foot_panel, 0, wx.EXPAND) + self.SetSizer(sizer) + + def _init_panels(self): + self._frame_header = FrameHeader + self._basic_config_body = None + self._adv_config_body = None + self._config_footer = None + self._output_footer = None - def _draw_horizontal_line(self): + def _draw_horizontal_line(self, sizer): line = wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL) line.SetSize((10, 10)) - self.sizer.Add(line, 0, wx.EXPAND) + sizer.Add(line, 0, wx.EXPAND) diff --git a/src/app/dialogs/display_main.pyc b/src/app/dialogs/display_main.pyc index ed11322a694ba9b23449bc188cf10640dc8fcab8..cd670e224416484586c4251a5babaf2c7fd50c1d 100644 GIT binary patch literal 4994 zcmcIoTW=f36+X))DUrHZmMtfa+eB{Agb5P&;sgx>H;8VDRYG@SM4vojK<_mzDpoh31dj{|LG= z{`mO)6s`Oxx>%%x-jlc@sV5x}j;=_jGNFCx_!GJ+ovPBlq&4Z+rBfG=d#aMoNPkv3 zvyQJx+K_%zI!(vdC7qN0ymaOrKO^aa^cSVG==fPlZ%BVhI!oXiVs6SYq&DSyk#mu+ zI?EEziK$BOmQKuHOx%`uL5wH86`feTn7G4B?YD05t}S%Ujlx9M#H)F>x@o$rAHBEw z```ZVVYB&ZG_Xy$txyQ-LXL)WX>u+InE&evjx+ca`F{@iF zpSWwv63^Tl_6HZH&nkTZG3$AMQMui zP_=uwS>%JG{OoX07;8u2$uK$mJkQPOuq?WV(O_^GCsCT8l=xMph5abW9t=iy7P7)H z$r2leR8+}_ir4V|`(|%q0yhIJzxJhggV*Ze4|nzC+!HTT;5)svEyd_H^z?ei!T4eU z?XS19=FDEx#i-urMPkjXAjY?v_gcK(_|h406^07NFzn~?Fa;YB6#>ybJ(p5fsr7)C zUPjY%)xAbdkF=AN)?}vWVn#pz7ZQmgHlmTgqm2l1BZb$k+!!7FT_m51ogzMvtCr!x9by-qFaQp&k_FVzEMU)}PLy1>8W zlTW|#r3!ERx+%pzR#(Ks$TPI3YI1r++p0d2zCrLw^tOzpPLW)2Pz=q~kxz^b80S>S zTW4J}ut}b2SaZHj2X~Py?3X8qf(WEelc3}(m8gNG7-nx$?jof_i@vww&3m`K8_wSY zW{lt_JN52WP}9>~IVb~q_Ak+<-c5b%BH}(xvN(U<1*aeS*E(AH5jx{CO-+*xiUutX zzQ-V3v!dw-Q@#>)76zP}VICrSx)aRsf{L5JgShPdgbM;R@(=`98Gd^;>D2|6heOAZ zJqx1h!KKb!NNCWt85`!flf?XlSeOut6XJ&AZi#z6EbZOApq3rwQsOOn;qu{au`ANM zBQJfiuZ+=(k?@Y#SIJVwUFp3h=M{Nbl@~bfJr#tb?6>IKZT0CvRG7?KYBGtn#?ZuS z6Pp@MF=g_dN&bxa6QUBJZ2>mo@yy$8CSzH=?}0It5KDNM<{A6u^LA4w?7#q zuqOk@TH070g0~{6hT|dKs;PW{a=;WeF{P8IgWbG8z7an}Iw-s)0JW<_ZJ6CJwRTEs3Vjtr9yJ+Lowcy>GDvj7t zrR{(~2twp>+CuPwZlJ)p4p;W6EqK3%H_*sr9H|NX8U+4&2u)6@vkWu)Eo!N)ICO6c zbjRRV7z}=mE@3WB@ZvT0@+qr8rXM;jlBF{Y@rv+J#nC4ntOK9R{=kkV3*JYkOXy>6 z$+au@13nndDYtUpTXxFj4R|P3?hhbbd}m)F(p(|XL-NOnzE5%r$n;%IhF)Ezj-T{xMI<}?5)AA483A3W$A7sM9Bgl_?P%g&i{oGu zD>RgEJ=cX_zLNaaP&la!Li%RjPZ*;1gX4;*(n7uKr~y z_z+T`p^XcTW$&)HFmC#~L^WI#ZtGyEGtFhLSR)HdRak@}55fk>yD%Kfau^Il%*+>h zR@E}Qx2K7%w4>A{ysfI+M1XnsRj9s2X>5+6N#ek+_jal~RGF(xhQOw@^nGDny z`tOjjn1G;FAIy(>rfXf&=Zmvu{@`s=RL3={TYdVGdkz1D=h1(^K<%jH`CXcRD|hDZ GF8v1xt1EW^ delta 1795 zcmaJCO>Y}jaNe%H_ImC5Gqw{)Ar5h}RBc3?p16dzB%-J)^tq~9Uo6MFDPARB%lj53;tz1GdhZRyi32m^d^kch)|;L0H=i$`tp2rBGylw_ zHp@TDE*$@v_qSe(Q6sOHlFN6=?F~H91_B?Tg_$5?Kwxt4;xzaecyWsVnShoB zo=JjM0=yU_NsvvK0@WYHUQS0=*Pq7IVo84$Uu|%7oQ;E;qk-2^ep~tb%B3)*O~BGG z;?-#f7%thprr)!^E|Hx}(W@AOd&7~B27g=2!q&CK>(gfScgg2))L+I=L?r=X3scO9 zv?z(JaLIwp637wY*cK6cRplD8fEo*UA~Lsx9q-aL6cL4X6HoM;{xU*1Qe+bI(>ils-m#F zdmgu8JDgk)sm@SwnNND+I_uNLU39o!m(ey_(LXv1Zx}ZHu&!0n709M=>1M8ogB;2Z za53~h&YMRH=LQR5LXe~ZLK)4LgX?1+VqI``Y=$W+6V=gSdk2CvRmw}UGy`K31UbGy zizig}*x8u5?c9_RD&bmAyk?G04Y5Bc!HdN?M+IV&q)5#`1p72mqyUg#Iv;}vwAPsJ zo!%FiYwr>QMHAKA>pb$YAL>I{M^e%-_7<)ZY!Sc%JyZtX>oemCNrT3E?u@>hE{cZs z({F7^s;#1Bq2`a2KU`N->KoyHv-iXwGI4)X-n(`4`fVPVh}kr#*F8_apIy04xV(md zm7Bg|OUXNNiP$tDJ7I{xVT8l@LQoDsGnj;M(BWfaNEEqFl)<_uz zF^^OVsnZ#udFC0}L_}d_x!)f4*kIDY1_+!9>^iD8j7k>%znT1U;`nEj Goqqw6jUu)H diff --git a/src/app/dialogs/footer.py b/src/app/dialogs/footer.py index b1b85a8..da45240 100644 --- a/src/app/dialogs/footer.py +++ b/src/app/dialogs/footer.py @@ -12,22 +12,31 @@ class AbstractFooter(wx.Panel): ''' def __init__(self, parent, **kwargs): wx.Panel.__init__(self, parent, **kwargs) - self.SetMinSize((30, 50)) + self.SetMinSize((30, 53)) self.cancel_button = self._button('Cancel', wx.ID_CANCEL) self.next_button = self._button("Next", wx.ID_OK) - - sizer = wx.BoxSizer(wx.HORIZONTAL) - sizer.AddStretchSpacer(1) - sizer.Add(self.cancel_button, 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.TOP, 20) - sizer.Add(self.next_button, 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.TOP, 20) - self.SetSizer(sizer) + + self._do_layout() + + def _do_layout(self): + v_sizer = wx.BoxSizer(wx.VERTICAL) + h_sizer = wx.BoxSizer(wx.HORIZONTAL) + + h_sizer.AddStretchSpacer(1) + h_sizer.Add(self.cancel_button, 0, wx.ALIGN_RIGHT | wx.RIGHT, 20) + h_sizer.Add(self.next_button, 0, wx.ALIGN_RIGHT | wx.RIGHT, 20) + + v_sizer.AddStretchSpacer(1) + v_sizer.Add(h_sizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND) + v_sizer.AddStretchSpacer(1) + self.SetSizer(v_sizer) def _button(self,label=None, style=None): return wx.Button( parent=self, id=-1, - size=(75, 23), + size=(90, 24), label=label, style=style) @@ -45,7 +54,8 @@ class ConfigFooter(AbstractFooter): def __init__(self, parent, controller, **kwargs): AbstractFooter.__init__(self, parent, **kwargs) - self._controller = controller + self._controller = controller + self.Bind(wx.EVT_BUTTON, self.OnConfigCancel, self.cancel_button) self.Bind(wx.EVT_BUTTON, self.OnConfigNext, self.next_button) @@ -77,4 +87,10 @@ class MainFooter(AbstractFooter): self._controller.OnMainCancel(event) def OnMainNext(self, event): - self._controller.OnMainNext(event) \ No newline at end of file + self._controller.OnMainNext(event) + + + + + + \ No newline at end of file diff --git a/src/app/dialogs/footer.pyc b/src/app/dialogs/footer.pyc index 7f5f2931969452f78b0281d8cd083fbebe1a2cb0..781e14de0f36a790d1a13304a59f641a3472f4e4 100644 GIT binary patch literal 4125 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 diff --git a/src/app/dialogs/header.py b/src/app/dialogs/header.py index 4e6387a..adc202e 100644 --- a/src/app/dialogs/header.py +++ b/src/app/dialogs/header.py @@ -5,40 +5,72 @@ Created on Dec 23, 2013 ''' import wx +import imageutil +from app.dialogs.segoe_statictext import SegoeText + +PAD_SIZE = 10 class FrameHeader(wx.Panel): def __init__(self, - heading="Doin Stuff here", + heading="Settings", subheading="Small notification or intructional message", image_path=None, dlg_style=1, **kwargs): wx.Panel.__init__(self, **kwargs) - self.SetBackgroundColour('#ffffff') - self.SetMinSize((120, 90)) + + self._init_properties() + self._init_components(heading, subheading, image_path) + self._do_layout() + - header = self._bold_static_text(label=heading) - subheader = wx.StaticText(self, label=subheading) - img = self._load_image(image_path) + def _init_properties(self): + self.SetBackgroundColour('#ffffff') + self.SetMinSize((120, 80)) + def _init_components(self, heading, subheading, image_path): + self.header = self._bold_static_text(heading) + self.subheader = wx.StaticText(self, label=subheading) + self.img = wx.BitmapFromImage(imageutil.LoadAndResizeImage(image_path)) + print '\n' + print 'Image returned from original method:', type(self._load_image(image_path)) + print 'image returned from imageutil', type(self.img) + + def _do_layout(self): + vsizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.HORIZONTAL) - headings_sizer = self.build_heading_sizer(header, subheader) - sizer.Add(headings_sizer, 1, wx.ALIGN_LEFT | wx.EXPAND | wx.LEFT, 20) - sizer.Add(img, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.RIGHT, 20) - self.SetSizer(sizer) - - # for i in dir(self): print i + headings_sizer = self.build_heading_sizer() + sizer.Add(headings_sizer, 1, wx.ALIGN_LEFT | wx.EXPAND | wx.LEFT, PAD_SIZE) + sizer.Add(self.img, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.RIGHT, PAD_SIZE) + vsizer.Add(sizer, 1, wx.EXPAND) + self.SetSizer(vsizer) + + def _bold_static_text(self, label): + txt = wx.StaticText(self, label=label) + font_size = txt.GetFont().GetPointSize() + txt.SetFont(wx.Font(font_size * 1.2, wx.FONTFAMILY_DEFAULT, + wx.FONTWEIGHT_NORMAL, wx.FONTWEIGHT_BOLD, False) + ) + return txt + def build_heading_sizer(self): + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.AddStretchSpacer(1) + sizer.Add(self.header, 1) + sizer.Add(self.subheader, 1) + sizer.AddStretchSpacer(1) + return sizer + def _load_image(self, image_path): try: - bitmap = wx.Bitmap(image_path) - - bitmap = self._resize_bitmap(bitmap) - return wx.StaticBitmap(self, -1, bitmap) + bitmap = wx.Bitmap(image_path) + print bitmap + bitmap = self._resize_bitmap(bitmap) + return wx.StaticBitmap(self, -1, bitmap) except: - raise IOError('Invalid Image path') + raise IOError('Invalid Image path') def _resize_bitmap(self, bmap): ''' @@ -55,17 +87,15 @@ class FrameHeader(wx.Panel): ) return wx.BitmapFromImage(image) - def _bold_static_text(self, label): - txt = wx.StaticText(self, label=label) - txt.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, - wx.FONTWEIGHT_NORMAL, wx.FONTWEIGHT_BOLD, False) - ) - return txt - - def build_heading_sizer(self, header, subheader): - sizer = wx.BoxSizer(wx.VERTICAL) - sizer.AddStretchSpacer(1) - sizer.Add(header, 1) - sizer.Add(subheader, 1) - sizer.AddStretchSpacer(1) - return sizer \ No newline at end of file + + def UpdateImage(self, image): + pass + + + + + + + + + \ No newline at end of file diff --git a/src/app/dialogs/header.pyc b/src/app/dialogs/header.pyc index 033d3ed06c2aaaa5e2aa05a89adfba0c5f2def47..b6a98bf59a1ce5ccc1746939059f1ff4074dc595 100644 GIT binary patch literal 4229 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 > + > +''' + +import wx +import base_window +import advanced_config +from app.dialogs import argparse_test_data + +def WithNoOptions(): pass + +def WithBasicOptions(): pass + +def WithAdvancedOptions(parser): + app = wx.App(False) + frame = base_window.BaseWindow(advanced_config.AdvancedConfigPanel, parser) + frame.Show(True) # Show the frame. + app.MainLoop() + +if __name__ == '__main__': + parser = argparse_test_data.parser + WithAdvancedOptions(parser) + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/app/images/image_store.py b/src/app/images/image_store.py index 477b4d8..04daf8b 100644 --- a/src/app/images/image_store.py +++ b/src/app/images/image_store.py @@ -7,8 +7,10 @@ Convenience module for keeping the filepaths in one place. """ -computer = r"C:\Users\Chris\Dropbox\pretty_gui\Gui\src\app\images\computer.png" -computer2 = r"C:\Users\Chris\Dropbox\pretty_gui\Gui\src\app\images\computer2.png" -computer3 = r"C:\Users\Chris\Dropbox\pretty_gui\Gui\src\app\images\computer3.png" -icon = r"C:\Users\Chris\Dropbox\pretty_gui\Gui\src\app\images\icon.ico" -terminal = r"C:\Users\Chris\Dropbox\pretty_gui\Gui\src\app\images\terminal.png" +computer = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\computer.png" +computer2 = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\computer2.png" +computer3 = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\computer3.png" +icon = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\icon.ico" +settings = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\settings.png" +settings2 = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\settings2.png" +terminal = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\terminal.png" diff --git a/src/app/images/image_store.pyc b/src/app/images/image_store.pyc index d24a81a2c16614b47ac9bc32d10314c8ad91bbfd..7874e26b6135cbe5c378c2319d8b27743c3a5fe7 100644 GIT binary patch delta 350 zcmeBRyTC5Z{F#?4_|%=CWCkc;1kw&bTx>E?T8lr5jUk1dA&Q+Lg@YkjgL9(C+{p`> z)LHWLQ!6L)G0HN!Ox9skgK;I;jr0og(u>gqjlqKUAeAy8jWNYV$uWrq1u>bqiRr1u zF`3Evd3r!%@&YCeC2R_cQ%g!Rf#xC%SH!0b>-oYl#{F#?4Tx?fRG6NJa0%->zF4mYRt;HOy!9Fo$E~De*g-mKprJ0l0GD@)N z738HCJ0Xd%8=(uyG1`LUWlA$+ii?tC5(^4qGIJBtQ;TCVlk@ZRfJ8Ce$kR-6jBJx% mF}aDCq!#67<|XE6fSiILCVtQWS>4BMz{drYU}Iuqgg^k8Wiku^ diff --git a/src/app/images/settings.png b/src/app/images/settings.png new file mode 100644 index 0000000000000000000000000000000000000000..318269acc5ca532589bc6e7666b515a4c3f01039 GIT binary patch literal 16453 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