Changeset 108 for trunk

Show
Ignore:
Timestamp:
10/02/08 05:02:59 (4 years ago)
Author:
lgs
Message:

Generation of random points and about dialog

Location:
trunk/chavier
Files:
1 added
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/chavier/app.py

    r107 r108  
     1# Copyright (c) 2007-2008 by Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com> 
     2# 
     3# This file is part of Chavier. 
     4# 
     5# Chavier is free software: you can redistribute it and/or modify 
     6# it under the terms of the GNU Lesser General Public License as published by 
     7# the Free Software Foundation, either version 3 of the License, or 
     8# (at your option) any later version. 
     9# 
     10# Chavier is distributed in the hope that it will be useful, 
     11# but WITHOUT ANY WARRANTY; without even the implied warranty of 
     12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     13# GNU Lesser General Public License for more details. 
     14# 
     15# You should have received a copy of the GNU Lesser General Public License 
     16# along with Chavier.  If not, see <http://www.gnu.org/licenses/>. 
     17 
    118import cairo 
    219 
     
    107124        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) 
    108125        chart_factory = self.CHART_TYPES[chart_type] 
    109         chart = chart_factory(surface, DEFAULT_OPTIONS) 
     126        chart = chart_factory(surface, options) 
    110127        chart.addDataset(datasets) 
    111128        chart.render() 
  • trunk/chavier/gui.py

    r107 r108  
     1# Copyright (c) 2007-2008 by Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com> 
     2# 
     3# This file is part of Chavier. 
     4# 
     5# Chavier is free software: you can redistribute it and/or modify 
     6# it under the terms of the GNU Lesser General Public License as published by 
     7# the Free Software Foundation, either version 3 of the License, or 
     8# (at your option) any later version. 
     9# 
     10# Chavier is distributed in the hope that it will be useful, 
     11# but WITHOUT ANY WARRANTY; without even the implied warranty of 
     12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     13# GNU Lesser General Public License for more details. 
     14# 
     15# You should have received a copy of the GNU Lesser General Public License 
     16# along with Chavier.  If not, see <http://www.gnu.org/licenses/>. 
     17 
    118import pygtk 
    219pygtk.require('2.0') 
    320import gtk 
     21 
     22from chavier.dialogs import ( 
     23    TextInputDialog, PointDialog, OptionDialog, RandomGeneratorDialog, 
     24    AboutDialog, 
     25    ) 
    426 
    527class GUI(object): 
     
    96118                ('refresh', gtk.STOCK_REFRESH, None, '<ctrl>r', 
    97119                 'Update the chart', self.refresh), 
     120 
     121                ('tools', None, '_Tools', None, 'Tools', None), 
     122                ('random-points', gtk.STOCK_EXECUTE, '_Generate random points', 
     123                 '<ctrl>g', 'Generate random points', 
     124                 self.generate_random_points), 
     125                ('help', None, '_Help', None, 'Help', None), 
     126                ('about', gtk.STOCK_ABOUT, None, None, 'About this program', 
     127                 self.about), 
    98128                ]) 
    99129        action_group.add_radio_actions([ 
     
    136166      <menuitem action="scatter"/> 
    137167    </menu> 
     168    <menu action="tools"> 
     169      <menuitem action="random-points"/> 
     170    </menu> 
     171    <menu action="help"> 
     172      <menuitem action="about"/> 
     173    </menu> 
    138174  </menubar> 
    139175  <toolbar name="ToolBar"> 
     
    187223        treeview.append_column(column2) 
    188224 
     225        treeview.connect('row-activated', self.dataset_treeview_row_activated) 
     226 
    189227        scrolled_window = gtk.ScrolledWindow() 
    190228        scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) 
     
    209247        self.options_treeview.expand_all() 
    210248 
     249        self.options_treeview.connect('row-activated', 
     250                                      self.options_treeview_row_activated) 
     251 
    211252        scrolled_window = gtk.ScrolledWindow() 
    212253        scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) 
     
    220261            value_type = types[name] 
    221262            if isinstance(value, dict): 
    222                 current_parent = self.options_store.append(parent_node, (name, None, None)) 
     263                current_parent = self.options_store.append(parent_node, 
     264                                                           (name, None, None)) 
    223265                self._fill_options_store(value, current_parent, value_type) 
    224266 
    225267            else: 
    226                 print value_type 
    227268                if value is not None: 
    228269                    value = str(value) 
     
    261302    def _get_options(self, iter): 
    262303        options = {} 
    263         first_child = self.options_store.iter_children(iter) 
    264         if first_child is not None: 
    265             name = self.options_store.get_value(iter, 0) 
    266             options[name] = self._get_options(first_child) 
    267  
    268         iter = self.options_store.iter_next(iter) 
    269304        while iter is not None: 
    270             name = self.options_store.get_value(iter, 0) 
    271             options[name] = self._get_options(iter) 
     305            name, value, value_type  = self.options_store.get(iter, 0, 1, 2) 
     306            if value_type is None: 
     307                child = self.options_store.iter_children(iter) 
     308                options[name] = self._get_options(child) 
     309            else: 
     310                if value is not None: 
     311                    converter = str_converters[value_type] 
     312                    value = converter(value) 
     313                options[name] = value 
     314 
    272315            iter = self.options_store.iter_next(iter) 
    273316 
    274317        return options 
     318 
     319    def _edit_point_internal(self, model, iter): 
     320        x, y = model.get(iter, 0, 1) 
     321 
     322        dialog = PointDialog(self.main_window, x, y) 
     323        response = dialog.run() 
     324        if response == gtk.RESPONSE_ACCEPT: 
     325            x, y = dialog.get_point() 
     326            model.set(iter, 0, x, 1, y) 
     327            self.refresh() 
     328        dialog.destroy() 
     329 
     330    def _edit_option_internal(self, model, iter): 
     331        name, value, value_type = model.get(iter, 0, 1, 2) 
     332        parents = [] 
     333        parent = model.iter_parent(iter) 
     334        while parent is not None: 
     335            parents.append(model.get_value(parent, 0)) 
     336            parent = model.iter_parent(parent) 
     337        parents.reverse() 
     338        parents.append(name) 
     339        label = u'.'.join(parents) 
     340 
     341        dialog = OptionDialog(self.main_window, label, value, value_type) 
     342        response = dialog.run() 
     343        if response == gtk.RESPONSE_ACCEPT: 
     344            new_value = dialog.get_value() 
     345            if new_value == "": 
     346                new_value = None 
     347            model.set_value(iter, 1, new_value) 
     348            self.refresh() 
     349        dialog.destroy() 
    275350 
    276351    # Event and signal handlers 
     
    299374        if self.surface is not None: 
    300375            self.refresh() 
     376 
     377    def dataset_treeview_row_activated(self, treeview, path, view_column): 
     378        model = treeview.get_model() 
     379        iter = model.get_iter(path) 
     380        self._edit_point_internal(model, iter) 
     381 
     382    def options_treeview_row_activated(self, treeview, path, view_column): 
     383        model = treeview.get_model() 
     384        iter = model.get_iter(path) 
     385        self._edit_option_internal(model, iter) 
    301386 
    302387    # Action handlers 
     
    374459            return 
    375460 
    376         x, y = model.get(selected, 0, 1) 
    377  
    378         dialog = PointDialog(self.main_window, x, y) 
    379         response = dialog.run() 
    380         if response == gtk.RESPONSE_ACCEPT: 
    381             x, y = dialog.get_point() 
    382             model.set(selected, 0, x, 1, y) 
    383             self.refresh() 
    384         dialog.destroy() 
     461        self._edit_point_internal(model, selected) 
    385462 
    386463    def edit_option(self, action): 
     
    391468            return 
    392469 
    393         name, value, value_type = model.get(selected, 0, 1, 2) 
    394         parents = [] 
    395         parent = model.iter_parent(selected) 
    396         while parent is not None: 
    397             parents.append(model.get_value(parent, 0)) 
    398             parent = model.iter_parent(parent) 
    399         parents.reverse() 
    400         parents.append(name) 
    401         label = u'.'.join(parents) 
    402  
    403         dialog = OptionDialog(self.main_window, label, value, value_type) 
    404         response = dialog.run() 
    405         if response == gtk.RESPONSE_ACCEPT: 
    406             new_value = dialog.get_value() 
    407             model.set_value(selected, 1, new_value) 
    408             self.refresh() 
    409         dialog.destroy() 
     470        self._edit_option_internal(model, selected) 
    410471 
    411472    def refresh(self, action=None): 
     
    417478            chart_type = self._get_chart_type() 
    418479            alloc = self.drawing_area.get_allocation() 
    419             self.surface = self.app.get_chart(datasets, None, chart_type, 
     480            self.surface = self.app.get_chart(datasets, options, chart_type, 
    420481                                              alloc.width, alloc.height) 
    421482            self.drawing_area.queue_draw() 
     
    423484            self.surface = None 
    424485 
     486    def generate_random_points(self, action=None): 
     487        tab = self._get_current_dataset_tab() 
     488        assert tab is not None 
     489 
     490        treeview = tab.get_children()[0] 
     491        model = treeview.get_model() 
     492 
     493        dialog = RandomGeneratorDialog(self.main_window) 
     494        response = dialog.run() 
     495        if response == gtk.RESPONSE_ACCEPT: 
     496            points = dialog.generate_points() 
     497            for point in points: 
     498                model.append(point) 
     499            self.refresh() 
     500        dialog.destroy() 
     501 
     502    def about(self, action=None): 
     503        dialog = AboutDialog(self.main_window) 
     504        dialog.run() 
     505        dialog.destroy() 
     506 
    425507    # Public API 
    426508    def run(self): 
    427509        gtk.main() 
    428510 
    429 class TextInputDialog(gtk.Dialog): 
    430  
    431     def __init__(self, toplevel_window, suggested_name): 
    432         flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT 
    433         buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, 
    434                    gtk.STOCK_OK, gtk.RESPONSE_ACCEPT) 
    435         super(TextInputDialog, self).__init__(u'Enter a name for the dataset', 
    436                                               toplevel_window, flags, buttons) 
    437         self.set_default_size(300, -1) 
    438  
    439         hbox = gtk.HBox(spacing=6) 
    440         hbox.set_border_width(12) 
    441  
    442         label = gtk.Label(u'Name') 
    443         hbox.pack_start(label, False, False) 
    444  
    445         self.entry = gtk.Entry() 
    446         self.entry.set_text(suggested_name) 
    447         self.entry.set_activates_default(True) 
    448         hbox.pack_start(self.entry, True, True) 
    449  
    450         self.vbox.pack_start(hbox, False, False) 
    451  
    452         self.vbox.show_all() 
    453  
    454         self.set_default_response(gtk.RESPONSE_ACCEPT) 
    455  
    456     def get_name(self): 
    457         return self.entry.get_text() 
    458  
    459  
    460 class PointDialog(gtk.Dialog): 
    461     def __init__(self, toplevel_window, initial_x, initial_y): 
    462         flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT 
    463         buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, 
    464                    gtk.STOCK_OK, gtk.RESPONSE_ACCEPT) 
    465         super(PointDialog, self).__init__(u'Enter the point values', 
    466                                           toplevel_window, flags, buttons) 
    467  
    468         initials = {u'x': str(initial_x), u'y': str(initial_y)} 
    469         self.entries = {} 
    470         for coordinate in (u'x', u'y'): 
    471             hbox = gtk.HBox(spacing=6) 
    472             hbox.set_border_width(12) 
    473  
    474             label = gtk.Label(coordinate) 
    475             hbox.pack_start(label, False, False) 
    476  
    477             entry = gtk.Entry() 
    478             entry.set_activates_default(True) 
    479             entry.set_text(initials[coordinate]) 
    480             hbox.pack_start(entry, True, True) 
    481  
    482             self.entries[coordinate] = entry 
    483  
    484             self.vbox.pack_start(hbox, False, False) 
    485  
    486         self.vbox.show_all() 
    487  
    488         self.set_default_response(gtk.RESPONSE_ACCEPT) 
    489  
    490     def get_point(self): 
    491         return (float(self.entries[u'x'].get_text()), 
    492                 float(self.entries[u'y'].get_text())) 
    493  
    494  
    495 class OptionDialog(gtk.Dialog): 
    496     def __init__(self, toplevel_window, label, value, value_type): 
    497         flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT 
    498         buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, 
    499                    gtk.STOCK_OK, gtk.RESPONSE_ACCEPT) 
    500         super(OptionDialog, self).__init__(u'Enter the option value', 
    501                                            toplevel_window, flags, buttons) 
    502  
    503  
    504         hbox = gtk.HBox(spacing=6) 
    505         hbox.set_border_width(12) 
    506  
    507         label = gtk.Label(label) 
    508         hbox.pack_start(label, False, False) 
    509  
    510         self.entry = gtk.Entry() 
    511         self.entry.set_text(value) 
    512         self.entry.set_activates_default(True) 
    513         hbox.pack_start(self.entry, True, True) 
    514  
    515         self.vbox.pack_start(hbox, False, False) 
    516  
    517         self.vbox.show_all() 
    518  
    519         self.set_default_response(gtk.RESPONSE_ACCEPT) 
    520  
    521     def get_value(self): 
    522         return self.entry.get_text() 
    523  
    524  
    525 def warning(window, msg): 
    526     dialog = gtk.MessageDialog(window, 
    527                                gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, 
    528                                gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, msg) 
    529     dialog.run() 
    530     dialog.destroy() 
     511 
     512def str2bool(str): 
     513    if str.lower() == "true": 
     514        return True 
     515    else: 
     516        return False 
     517 
     518str_converters = { 
     519    str: str, 
     520    int: int, 
     521    float: float, 
     522    unicode: unicode, 
     523    bool: str2bool, 
     524}