Beispiel #1
0
class AudioOptions(SizedFrame):
    def __init__(self):
        super(AudioOptions, self).__init__(application.frame,
                                           title='Audio Options')
        p = self.GetContentsPane()
        add_accelerator(self, 'ESCAPE', lambda event: self.Close(True))
        self.default_volume = config.system['volume']
        self.default_frequency = config.system['frequency']
        self.default_pan = config.system['pan']
        p.SetSizerType('form')
        wx.StaticText(p, label='&Output Device')
        self.device = wx.Choice(p,
                                choices=sorted(
                                    application.output.get_device_names()))
        self.device.SetStringSelection(config.system['output_device_name'])
        self.device.Bind(
            wx.EVT_CHOICE,
            lambda event: set_output_device(self.device.GetStringSelection()))
        wx.StaticText(p, label='&Volume')
        self.volume = wx.Slider(p, style=wx.VERTICAL)
        self.volume.SetValue(self.default_volume)
        self.volume.Bind(wx.EVT_SLIDER,
                         lambda event: set_volume(self.volume.GetValue()))
        wx.StaticText(p, label='&Pan')
        self.pan = wx.Slider(p, style=wx.HORIZONTAL)
        self.pan.SetValue(self.default_pan)
        self.pan.Bind(wx.EVT_SLIDER,
                      lambda event: set_pan(self.pan.GetValue()))
        wx.StaticText(p, label='&Frequency')
        self.frequency = IntCtrl(p,
                                 value=self.default_frequency,
                                 min=min_frequency,
                                 max=max_frequency,
                                 limited=True)
        self.frequency.Bind(EVT_INT, set_frequency(self.frequency.GetValue()))
        add_accelerator(
            self.frequency, 'UP', lambda event: self.update_frequency(
                min(self.frequency.GetMax(),
                    self.frequency.GetValue() + 100)))
        add_accelerator(
            self.frequency, 'DOWN', lambda event: self.update_frequency(
                max(self.frequency.GetMin(),
                    self.frequency.GetValue() - 100)))
        self.ok = wx.Button(p, label='&OK')
        self.ok.Bind(wx.EVT_BUTTON, lambda event: self.Close(True))
        self.restore = wx.Button(p, label='&Restore Defaults')
        self.restore.Bind(wx.EVT_BUTTON, self.on_restore)
        self.Show(True)
        self.Maximize(True)

    def update_frequency(self, value):
        """Update frequency."""
        self.frequency.SetValue(value)
        set_frequency(value)

    def on_restore(self, event):
        """Cancel button was pressed."""
        set_volume(100)
        set_pan(50)
        set_frequency(44100)
class NumberEntryDialog(wx.Dialog):
    def __init__(self,
                 parent,
                 message="Please enter a number.",
                 caption="Number Entry",
                 prompt="Number:",
                 value=None,
                 min=None,
                 max=None):

        super(NumberEntryDialog, self).__init__(parent, title=caption)
        kwargs = {
            'parent': self,
            'min': min,
            'max': max,
            'value': value,
            'limited': True,
            'allow_none': False,
        }
        self.intctrl = IntCtrl(
            **{k: v
               for k, v in kwargs.iteritems() if v is not None})

        sizer = wx.BoxSizer(wx.VERTICAL)
        if message:
            sizer.Add(wx.StaticText(self, label=message),
                      flag=wx.ALL,
                      border=4)
        hSizer = wx.BoxSizer(wx.HORIZONTAL)
        if prompt:
            hSizer.Add(wx.StaticText(self, label=prompt),
                       flag=wx.ALIGN_CENTER_VERTICAL)
        hSizer.Add(self.intctrl, 1, flag=wx.EXPAND)
        sizer.Add(hSizer, flag=wx.ALL | wx.EXPAND, border=4)

        btnsizer = wx.StdDialogButtonSizer()

        btn = wx.Button(self, wx.ID_OK)
        btn.SetDefault()
        btnsizer.AddButton(btn)

        btn = wx.Button(self, wx.ID_CANCEL)
        btnsizer.AddButton(btn)
        btnsizer.Realize()

        sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        self.SetSizer(sizer)
        self.SetSize(200, 50 * (2 + int(bool(message))))
        #self.Fit()

        self.CenterOnParent()

    def SetValue(self, v):
        self.intctrl.SetValue(v)

    def GetValue(self):
        return self.intctrl.GetValue()
Beispiel #3
0
class IntegerEditPanel(wx.Panel):
    edits = Integral

    def __init__(self, *args, **kwargs):
        super(IntegerEditPanel, self).__init__(*args, **kwargs)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.intspin = wx.SpinCtrl(self,
                                   style=wx.ALIGN_RIGHT | wx.SP_ARROW_KEYS)
        self.intctrl = IntCtrl(self,
                               limited=True,
                               allow_long=True,
                               style=wx.ALIGN_RIGHT)
        self.floatctrl = wx.TextCtrl(self, style=wx.ALIGN_RIGHT)
        self.floatchk = wx.CheckBox(self, label='Treat as floating-point')
        sizer.Add(self.intspin, flag=wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self.intctrl, flag=wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self.floatctrl, flag=wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self.floatchk,
                  flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
                  border=10)
        self.Bind(wx.EVT_CHECKBOX, self.OnFloatToggle, self.floatchk)
        self.SetSizer(sizer)

    def SetValue(self, value, kind):
        self.kind = kind
        self.Freeze()
        self.floatchk.Value = False
        self.floatctrl.Hide()
        if type(value).maxval > sys.maxsize:
            self.intspin.Hide()
            self.intctrl.Show()
            self.intctrl.SetBounds(type(value).minval, type(value).maxval)
            self.intctrl.SetValue(long(value))
        else:
            self.intctrl.Hide()
            self.intspin.Show()
            self.intspin.SetRange(type(value).minval, type(value).maxval)
            self.intspin.SetValue(value)
        if kind.size in (4, 8):
            self.floatchk.Show()
            self.intfmt = kind.format[False]
            self.floatfmt = FLOAT32.format[
                False] if kind.size == 4 else FLOAT64.format[False]
        else:
            self.floatchk.Hide()
        self.Layout()
        self.Thaw()

    def GetValue(self):
        if self.intspin.Shown:
            return self.kind(self.intspin.GetValue())
        elif self.intctrl.Shown:
            try:
                return self.kind(self.intctrl.GetValue())
            except ValueError, e:
                raise ValueError, "%r" % e
        else:
Beispiel #4
0
class ScopeConnection(wx.Panel):
    """This is the view and controller for connecting to the scope"""
    def __init__(self, parent, env):
        """Initialize the panel for setting up the scope"""
        wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.BORDER_SIMPLE)

        self.env = env
        self.scope = self.env.scope_source

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(self.sizer)

        input_host = wx.BoxSizer(wx.HORIZONTAL)
        target_cpu = wx.BoxSizer(wx.HORIZONTAL)
        scope_cpu = wx.BoxSizer(wx.HORIZONTAL)
        buttons = wx.BoxSizer(wx.HORIZONTAL)

        self.status = wx.StaticText(self, wx.ID_ANY, "")
        font = self.status.GetFont()
        font.SetWeight(wx.BOLD)
        self.status.SetFont(font)

        self.btn_enable = wx.Button(self, wx.ID_ANY, "")
        self.btn_collect = wx.Button(self, wx.ID_ANY, "Collect")

        buttons.Add(self.btn_enable, 1, wx.ALIGN_CENTER)
        buttons.Add(self.btn_collect, 1, wx.ALIGN_CENTER)

        lbl_server = wx.StaticText(self, wx.ID_ANY, "Scope Server")
        self.txt_server = wx.TextCtrl(self, wx.ID_ANY, self.scope.server)
        self.btn_connect = wx.Button(self, wx.ID_ANY, "Connect")
        input_host.Add(lbl_server, 0, wx.ALIGN_CENTER | wx.RIGHT, 5)
        input_host.Add(self.txt_server, 1, wx.EXPAND)
        input_host.Add(self.btn_connect, 0, wx.EXPAND)

        self.sizer.Add(self.status, 0, wx.EXPAND | wx.ALL, 5)
        self.sizer.Add(input_host, 0,
                       wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT, 5)

        self.choice_t_cpu = wx.Choice(self, wx.ID_ANY)
        self._add_field("Target CPU", self.choice_t_cpu, small=True)

        self.choice_s_cpu = wx.Choice(self, wx.ID_ANY)
        self._add_field("Scope CPU", self.choice_s_cpu, small=True)

        self.command = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_RIGHT)
        self._add_field("Target Command", self.command)
        self.command.Bind(wx.EVT_TEXT, self.onchange_capture_settings)

        self.ta = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_RIGHT)
        self._add_field("Target App", self.ta)
        self.ta.Bind(wx.EVT_TEXT, self.onchange_capture_settings)

        self.target_cbuf = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_RIGHT)
        self._add_field("Target Trigger Buffer", self.target_cbuf)
        self.target_cbuf.Bind(wx.EVT_TEXT, self.onchange_capture_settings)

        self.msamples = IntCtrl(self, wx.ID_ANY, style=wx.TE_RIGHT)
        self._add_field("Max # Samples", self.msamples, small=True)
        self.msamples.Bind(wx.EVT_TEXT, self.onchange_capture_settings)

        self.delta = IntCtrl(self, wx.ID_ANY, style=wx.TE_RIGHT)
        self._add_field("Time Step", self.delta, small=True)
        self.delta.Bind(wx.EVT_TEXT, self.onchange_capture_settings)

        self.debug = wx.CheckBox(self, wx.ID_ANY)
        self._add_field("Debug TA Calls", self.debug, small=True)
        self.debug.Bind(wx.EVT_CHECKBOX, self.onchange_capture_settings)

        self.sizer.Add(buttons, 0, wx.ALL | wx.CENTER, 5)

        # Events
        self.btn_enable.Bind(wx.EVT_BUTTON, self.onclick_btn_enable)
        self.btn_connect.Bind(wx.EVT_BUTTON, self.onclick_btn_connect)
        self.choice_t_cpu.Bind(wx.EVT_CHOICE, self.onchoice_t_cpu)
        self.choice_s_cpu.Bind(wx.EVT_CHOICE, self.onchoice_s_cpu)
        self.btn_collect.Bind(wx.EVT_BUTTON, self.onclick_btn_collect)

        pub.subscribe(self.on_enable_changed, ScopeSource.ENABLED_CHANGED)
        pub.subscribe(self.on_connect_changed, ScopeSource.CONNECTED_CHANGED)
        pub.subscribe(self.on_capture_settings_changed,
                      ScopeSource.CAPTURE_SETTINGS_CHANGED)
        pub.subscribe(self.on_readiness_changed,
                      CaptureSource.READINESS_CHANGED)

        # Initial data
        self.draw_status()
        self.draw_capture_settings()
        self.draw_collect_btn()

    def _add_field(self, label, item, small=False):
        """Add a label/element pair to the UI"""
        szr = wx.BoxSizer(wx.HORIZONTAL)
        lbl = wx.StaticText(self, wx.ID_ANY, label)
        szr.Add(lbl, 1 if small else 0, wx.ALIGN_CENTER)
        szr.Add((15, 15), 0, wx.EXPAND)
        szr.Add(item, 0 if small else 1, wx.ALIGN_RIGHT)
        self.sizer.Add(szr, 0, wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT, 5)

    def onclick_btn_connect(self, evt):
        """Connect button has been clicked."""
        server = self.txt_server.GetValue()
        if self.scope.is_connected():
            self.scope.disconnect()
        self.scope.connect(server)

    def onclick_btn_enable(self, evt):
        """Enable button has been clicked."""
        if not self.scope.is_enabled():
            self.scope.enable()
        else:
            self.scope.disable()

    def onclick_btn_collect(self, evt):
        """Collect button has been clicked."""
        if self.env.get_active_dataset_name() is not None:
            self.env.collection_pipeline.run(1)

    def onchoice_t_cpu(self, evt):
        """The target CPU has changed."""
        sel = self.choice_t_cpu.GetSelection()
        if sel != wx.NOT_FOUND:
            self.scope.set_target_core(sel)

    def onchoice_s_cpu(self, evt):
        """The scope CPU has changed."""
        sel = self.choice_s_cpu.GetSelection()
        if sel != wx.NOT_FOUND:
            self.scope.set_scope_core(sel)

    def on_enable_changed(self):
        """The enable state of the scope has changed."""
        self.draw_status()

    def on_connect_changed(self):
        """The connection state of the scope has changed."""
        self.draw_status()
        self.draw_capture_settings()

    def on_capture_settings_changed(self):
        """The capture settings have changed."""
        self.draw_capture_settings()

    def on_readiness_changed(self):
        """The readiness of the scope has changed."""
        self.draw_collect_btn()

    def onchange_capture_settings(self, evt):
        """The user is trying to change the capture settings."""
        cmd = self.command.GetValue()
        ta = self.ta.GetValue()
        cbuf = self.target_cbuf.GetValue()
        msamp = self.msamples.GetValue()
        delta = self.delta.GetValue()
        debug = self.debug.GetValue()

        self.scope.set_capture_params(max_samples=msamp,
                                      time_delta=delta,
                                      ta_command=cmd,
                                      ta_name=ta,
                                      ta_cbuf=cbuf,
                                      debug=debug)

    def draw_status(self):
        """Update the state, buttons, and spinners based on current state"""
        enabled = self.scope.is_enabled()
        connected = self.scope.is_connected()

        if enabled and connected:
            scope_state = "Enabled"
        elif connected and not enabled:
            scope_state = "Connected and Disabled"
        else:
            scope_state = "Disconnected"

        btn_label = "Disable" if enabled else "Enable"
        scope_status = "Scope is %s" % scope_state

        self.status.SetLabel(scope_status)
        self.btn_connect.Enable(not enabled or not connected)
        self.txt_server.Enable(not enabled or not connected)
        self.btn_enable.SetLabel(btn_label)
        self.btn_enable.Enable(connected)

        ncores = self.scope.num_cores
        cores = ["Core %u" % i for i in range(ncores)]

        sel = self.choice_t_cpu.GetSelection()
        if sel == wx.NOT_FOUND:
            sel = self.scope.get_target_core()
        self.choice_t_cpu.SetItems(cores)
        if ncores > 0:
            self.choice_t_cpu.SetSelection(sel)
        self.choice_t_cpu.Enable(connected and not enabled)

        sel = self.choice_s_cpu.GetSelection()
        if sel == wx.NOT_FOUND:
            sel = self.scope.get_scope_core()
        self.choice_s_cpu.SetItems(cores)
        if ncores > 0:
            self.choice_s_cpu.SetSelection(sel)
        self.choice_s_cpu.Enable(connected and not enabled)

    def draw_capture_settings(self):
        """Draw the capture settings."""
        enabled = self.scope.is_enabled()
        connected = self.scope.is_connected()

        self.command.ChangeValue(self.scope.ta_command)
        self.ta.ChangeValue(self.scope.ta_name)
        self.target_cbuf.ChangeValue(self.scope.ta_cbuf)
        self.msamples.ChangeValue(self.scope.max_samples)
        self.delta.ChangeValue(self.scope.time_delta)
        self.debug.SetValue(self.scope.debug)

        self.command.Enable(connected)
        self.ta.Enable(connected)
        self.target_cbuf.Enable(connected)
        self.msamples.Enable(connected)
        self.delta.Enable(connected)
        self.debug.Enable(connected)

    def draw_collect_btn(self):
        """Enable or disable the collection button"""
        self.btn_collect.Enable(self.scope.is_ready())
Beispiel #5
0
class ProbeConfig(wx.Panel):
    """This is the view and controller for a single probe configuration"""
    def __init__(self, parent, probe):
        """Initialization"""
        wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.BORDER_SIMPLE)
        self.probe = probe

        sizer = wx.BoxSizer(wx.VERTICAL)

        assoc = wx.BoxSizer(wx.HORIZONTAL)
        nset = wx.BoxSizer(wx.HORIZONTAL)
        line = wx.BoxSizer(wx.HORIZONTAL)
        capt = wx.BoxSizer(wx.HORIZONTAL)
        btns = wx.BoxSizer(wx.HORIZONTAL)

        self.status = wx.StaticText(self, wx.ID_ANY, "Probe is Active")
        font = self.status.GetFont()
        font.SetWeight(wx.BOLD)
        self.status.SetFont(font)

        lbl_assoc = wx.StaticText(self, wx.ID_ANY, "Associativity")
        self.int_assoc = IntCtrl(self, wx.ID_ANY)
        self.int_assoc.SetValue(self.probe.associativity)
        assoc.Add(lbl_assoc, 1, wx.ALIGN_CENTER | wx.RIGHT, 5)
        assoc.Add(self.int_assoc, 0, wx.ALIGN_RIGHT)

        lbl_nset = wx.StaticText(self, wx.ID_ANY, "Number of Sets")
        self.int_nset = IntCtrl(self, wx.ID_ANY)
        self.int_nset.SetValue(self.probe.num_sets)
        nset.Add(lbl_nset, 1, wx.ALIGN_CENTER | wx.RIGHT, 5)
        nset.Add(self.int_nset, 0, wx.ALIGN_RIGHT)

        lbl_line = wx.StaticText(self, wx.ID_ANY, "Size of Line")
        self.int_line = IntCtrl(self, wx.ID_ANY)
        self.int_line.SetValue(self.probe.line_size)
        line.Add(lbl_line, 1, wx.ALIGN_CENTER | wx.RIGHT, 5)
        line.Add(self.int_line, 0, wx.ALIGN_RIGHT)

        lbl_capt = wx.StaticText(self, wx.ID_ANY, "Capture Limits:")
        lbl_lp = wx.StaticText(self, wx.ID_ANY, "[")
        self.spn_lo = wx.SpinButton(self, wx.ID_ANY)
        lbl_cm = wx.StaticText(self, wx.ID_ANY, ",")
        self.spn_hi = wx.SpinButton(self, wx.ID_ANY)
        lbl_rp = wx.StaticText(self, wx.ID_ANY, ")")
        self.btn_config = wx.Button(self, wx.ID_ANY, "Configure")
        capt.Add(lbl_capt, 3, wx.ALIGN_CENTER)
        capt.Add(lbl_lp, 0, wx.ALIGN_CENTER)
        capt.Add(self.spn_lo, 1, wx.ALIGN_CENTER)
        capt.Add(lbl_cm, 0, wx.ALIGN_CENTER)
        capt.Add(self.spn_hi, 1, wx.ALIGN_CENTER)
        capt.Add(lbl_rp, 0, wx.ALIGN_CENTER)
        capt.Add(self.btn_config, 0, wx.ALIGN_CENTER)

        self.btn_enable = wx.Button(self, wx.ID_ANY, "Enable")
        btns.Add(self.btn_enable, 0, wx.ALL, 5)

        sizer.Add(self.status, 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 5)
        sizer.Add(assoc, 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 5)
        sizer.Add(nset, 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 5)
        sizer.Add(line, 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 5)
        sizer.Add(capt, 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 5)
        sizer.Add(btns, 0, wx.ALIGN_CENTER | wx.ALL, 5)

        self.SetSizer(sizer)
        sizer.SetSizeHints(self)

        # Events
        self.btn_enable.Bind(wx.EVT_BUTTON, self.onclick_btn_enable)
        self.btn_config.Bind(wx.EVT_BUTTON, self.onclick_btn_config)

        pub.subscribe(self.on_enable_changed, Probe.ENABLED_CHANGED)
        pub.subscribe(self.on_enable_changed, Probe.CONFIG_CHANGED)

        # Initial data
        self.on_enable_changed()

    def set_status(self):
        """Display the status of the probe."""
        name = self.probe.name
        status = "Probe %s is active" % name
        self.status.SetLabel(status)

    def onclick_btn_enable(self, evt):
        """Enable button has been clicked."""
        if not self.probe.is_enabled():
            assoc = self.int_assoc.GetValue()
            nset = self.int_nset.GetValue()
            lsize = self.int_line.GetValue()
            self.probe.enable(assoc, nset, lsize)
        else:
            self.probe.disable()

    def onclick_btn_config(self, evt):
        """Configure button has been clicked."""
        lo = self.spn_lo.GetValue()
        hi = self.spn_hi.GetValue()
        if not self.probe.configure(lo, hi):
            msg = wx.MessageDialog(
                self, 'Failed to configure probe %s' % self.probe.name,
                'Failure', wx.OK)
            msg.ShowModal()
            msg.Destroy()

    def on_enable_changed(self, name=None):
        """The enable state of the scope has changed."""
        if name is not None and self.probe.name != name:
            return

        enabled = self.probe.is_enabled()
        prb_state = "Enabled" if enabled else "Disabled"
        btn_status = "Disable" if enabled else "Enable"
        prb_status = "Probe %s is %s" % (self.probe.name, prb_state)
        self.status.SetLabel(prb_status)
        self.btn_enable.SetLabel(btn_status)

        self.int_assoc.Enable(not enabled)
        self.int_nset.Enable(not enabled)
        self.int_line.Enable(not enabled)
        self.spn_lo.Enable(enabled)
        self.spn_hi.Enable(enabled)
        self.btn_config.Enable(enabled)
        self.spn_lo.SetRange(0, self.probe.num_sets)
        self.spn_hi.SetRange(0, self.probe.num_sets)
        self.spn_lo.SetValue(self.probe.low_set)
        self.spn_hi.SetValue(self.probe.high_set)
Beispiel #6
0
class ClippyFrame(wx.Frame):
    def __init__(self, parent, title):
        self.port = 0
        self.init_clippy()

        ### Frame

        wx.Frame.__init__(self,
                          parent,
                          title=title,
                          size=(300, 200),
                          style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX)

        ### Menu

        fileMenu = wx.Menu()
        menuAbout = fileMenu.Append(
            wx.ID_ABOUT, "&About",
            "developed by Rahul Madhavan ([email protected])")
        menuExit = fileMenu.Append(wx.ID_EXIT, "&Exit", "Adios !!!")

        menuBar = wx.MenuBar()
        menuBar.Append(fileMenu, "File")
        self.SetMenuBar(menuBar)

        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)

        ### UI Elements

        self.current_port_no_label = wx.StaticText(self, wx.ID_ANY,
                                                   "Current Port No : ")
        self.port_text_box = IntCtrl(self,
                                     wx.ID_ANY,
                                     value=self.port,
                                     min=1000,
                                     max=100000)

        self.port_no_label = wx.StaticText(self, wx.ID_ANY, " Port No : ")
        self.current_port = wx.StaticText(self, wx.ID_ANY, str(self.port))

        self.restart_button = wx.Button(self, -1, "Restart Clippy")
        self.restart_button.Disable()

        ### Binders
        self.Bind(wx.EVT_BUTTON, self.OnRestart, self.restart_button)
        self.Bind(wx.EVT_TEXT, self.OnTextChange, self.port_text_box)

        ### Sizers

        flex_sizer = wx.FlexGridSizer(2, 2, 20, 35)

        flex_sizer.AddMany([(self.current_port_no_label),
                            (self.current_port, 1, wx.EXPAND),
                            (self.port_no_label),
                            (self.port_text_box, 1, wx.EXPAND)])

        v_sizer = wx.BoxSizer(wx.VERTICAL)

        v_sizer.Add(flex_sizer, 1, wx.EXPAND)
        v_sizer.Add(self.restart_button, 1, wx.EXPAND | wx.ALIGN_CENTER)

        f_sizer = wx.BoxSizer(wx.VERTICAL)
        f_sizer.Add(v_sizer, 1, wx.EXPAND | wx.ALL, 20)

        self.SetSizer(f_sizer)
        self.Show()

    def OnAbout(self, event):
        dlg = wx.MessageDialog(
            self,
            "developed by Rahul Madhavan ([email protected])",
            "Clippy",
            style=wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()

    def OnExit(self, event):
        self.Close(True)

    def OnRestart(self, e):
        self.watcher.stop()
        self.receiver.stop()
        port = self.port_text_box.GetValue()
        self.persist_json_config({'port': port})
        self.init_clippy()
        self.current_port.SetLabelText(str(self.port))
        self.restart_button.Disable()

    def OnTextChange(self, e):
        temp_port = self.port_text_box.GetValue()
        if self.port != temp_port and self.port_text_box.IsInBounds():
            self.restart_button.Enable()
        else:
            self.restart_button.Disable()

    def init_clippy(self):
        self.msg = Msg("")
        config = self.fetch_clippy_configuration()
        port = config["port"]
        self.port = port
        print "USING PORT : " + str(port)
        self.watcher = ClippyWatcher(self.msg, port)
        self.receiver = ClippyReceiver(self.msg, port)
        self.watcher.daemon = True
        self.receiver.daemon = True
        self.watcher.start()
        self.receiver.start()

    def fetch_clippy_configuration(self):
        config = {}
        data_dir = wx.StandardPaths.Get().GetUserDataDir()
        filename = CONFIG_FILE
        file_abs_path = os.path.join(data_dir, filename)
        if os.path.isfile(file_abs_path):
            fp = open(file_abs_path, 'r')
            str = fp.read()
            config = json.loads(str)
        else:
            print "config file not found"
            config = self.create_json_config()
        return config

    def persist_json_config(self, config):
        data_dir = wx.StandardPaths.Get().GetUserDataDir()
        filename = CONFIG_FILE
        file_abs_path = os.path.join(data_dir, filename)
        with open(file_abs_path, 'w') as outfile:
            json.dump(config, outfile)
        return config

    def create_json_config(self):
        config = {"port": MCAST_PORT}
        data_dir = wx.StandardPaths.Get().GetUserDataDir()
        filename = CONFIG_FILE
        file_abs_path = os.path.join(data_dir, filename)
        if not os.path.exists(data_dir):
            os.makedirs(data_dir)
        with open(file_abs_path, 'w') as outfile:
            json.dump(config, outfile)
        return config