Internet radio browser GUI for music/video streams from various directory services.

⌈⌋ branch:  streamtuner2


Check-in [095de3353f]

Overview
Comment:Introduce `dict` configuration type, prepare TreeView in uikit (similar to record/play config table).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 095de3353f7cea5c64ad54b1985817a0acf43a67
User & Date: mario on 2016-10-27 16:42:04
Other Links: manifest | tags
Context
2016-10-28
18:11
Move liststore_edit() and app_bin_check() from configwin. to uikit.

Allow ListStore for config_play/_record/_specbuttons without `editable` row [2], which is now a property of the CellRenderers (instead of a cell-attribute).

Specialized uikit.config_treeview() builds a custom two-column TreeView now. check-in: d90db23c73 user: mario tags: trunk

2016-10-27
16:42
Introduce `dict` configuration type, prepare TreeView in uikit (similar to record/play config table). check-in: 095de3353f user: mario tags: trunk
2016-10-23
16:29
Cleaner specbuttons plugin, add support for placeholders in button commands. Add documentation and some config ideas. check-in: 824186a7c3 user: mario tags: trunk
Changes

Modified channels/configwin.py from [75725508ad] to [0227a222a4].

1
2
3
4
5
6
7

8
9
10
11
12
13
14
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
...
172
173
174
175
176
177
178







179
180
181
182
183
184
185
# api: streamtuner2
# title: Config dialog
# description: Allows to configure players, options, and plugins
# version: 2.5
# type: feature
# category: ui
# config: -

# priority: core
# 
# Configuration dialog for audio applications,
# general settings, and plugin activaiton and
# their options.


................................................................................
                # dropdown
                elif isinstance(w, ComboBoxText):
                    w.set_default(val)
                # number
                elif isinstance(w, gtk.SpinButton):
                    w.set_value(int(val))
                # list
                elif isinstance(w, gtk.ListStore):
                    w.clear()
                    for k,v in val.items():
                        w.append([k, v, True, self.app_bin_check(v)])
                    w.append(["", "", True, gtk.STOCK_NEW])
            #log.CONF("config load", prefix+key, val, type(w))

    # Store gtk widget valus back into conf. dict
................................................................................
                if ver == 2:
                    cb = gtk.SpinButton(adj, 1.0, 0)
                else:
                    cb = gtk.SpinButton()
                    cb.set_adjustment(adj)
                    cb.set_digits(0)








            # text field
            else:
                cb = gtk.Entry()
           
            add_( "config_"+opt["name"], cb, description, color )

        # Spacer between plugins







>







 







|







 







>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
..
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# api: streamtuner2
# title: Config dialog
# description: Allows to configure players, options, and plugins
# version: 2.5
# type: feature
# category: ui
# config: -
#    { name: arraysample, value: "1,2", type: array, rows: "xxx,yyy", description: table }
# priority: core
# 
# Configuration dialog for audio applications,
# general settings, and plugin activaiton and
# their options.


................................................................................
                # dropdown
                elif isinstance(w, ComboBoxText):
                    w.set_default(val)
                # number
                elif isinstance(w, gtk.SpinButton):
                    w.set_value(int(val))
                # list
                elif isinstance(w, gtk.ListStore) and isinstance(val, dict):
                    w.clear()
                    for k,v in val.items():
                        w.append([k, v, True, self.app_bin_check(v)])
                    w.append(["", "", True, gtk.STOCK_NEW])
            #log.CONF("config load", prefix+key, val, type(w))

    # Store gtk widget valus back into conf. dict
................................................................................
                if ver == 2:
                    cb = gtk.SpinButton(adj, 1.0, 0)
                else:
                    cb = gtk.SpinButton()
                    cb.set_adjustment(adj)
                    cb.set_digits(0)

            # ListView
            elif opt["type"] in ("list", "table", "array", "dict"):
                cb, ls = uikit.config_treeview(opt)
                add_("cfgui_tv", cb, "", None)
                self.widgets["config_" + opt["name"]] = ls
                continue

            # text field
            else:
                cb = gtk.Entry()
           
            add_( "config_"+opt["name"], cb, description, color )

        # Spacer between plugins

Modified channels/specbuttons.py from [a1cfea50d2] to [cb0390ac2c].

3
4
5
6
7
8
9

10
11
12
13
14
15
16
# description: Adds configurable mini toolbar buttons
# version: 0.7
# depends: streamtuner2 >= 2.2.0
# type: feature
# category: ui
# config:
#    { name: specbutton_rows, value: 2, max: 4, type: int, description: "Number of rows to arrange buttons in." }

# doc:
#    http://fossil.include-once.org/streamtuner2/info/43b36ed35b1488d5
#
# Adds the mini/extra buttons in the toolbar, which allow to control your
# audio player or run other system commands. The configuration list is in
# the Settings → Options tab.
#







>







3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# description: Adds configurable mini toolbar buttons
# version: 0.7
# depends: streamtuner2 >= 2.2.0
# type: feature
# category: ui
# config:
#    { name: specbutton_rows, value: 2, max: 4, type: int, description: "Number of rows to arrange buttons in." }
#    { name: specbuttons, type: dict, rows: "icon,command", description: "Associate icons to external commands." }
# doc:
#    http://fossil.include-once.org/streamtuner2/info/43b36ed35b1488d5
#
# Adds the mini/extra buttons in the toolbar, which allow to control your
# audio player or run other system commands. The configuration list is in
# the Settings → Options tab.
#

Modified gtk3.xml.gz from [9e4c8a0b5c] to [fc5477f880].

cannot compute difference between binary files

Modified uikit.py from [a196775096] to [22fa63b417].

135
136
137
138
139
140
141

142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
...
502
503
504
505
506
507
508

























509
510
511
512
513
514
515
                    for attr,val in list(cell[3].items()):
                        col.add_attribute(rend, attr, val)
                    # next
                    datapos += 1
                    #log.INFO(cell, len(cell))

                # add column to treeview

                widget.append_column(col)
           
        # add data?
        if (entries is not None):
            #- expand datamap
            vartypes = []  #(str, str, bool, str, int, int, gtk.gdk.Pixbuf, str, int)
            rowmap = []    #["title", "desc", "bookmarked", "name", "count", "max", "img", ...]
            for desc in datamap:
                for var in xrange(2, len(desc)):
                    vartypes.append(desc[var][1])  # content types
                    rowmap.append(desc[var][0])    # dict{} column keys in entries[] list
            # create gtk array storage
            ls = gtk.ListStore(*vartypes)   # could be a TreeStore, too
            #log.UI(vartypes, len(vartypes))

            #log.DATA(rowmap, len(rowmap))
 
            # prepare for missing values, and special variable types
            defaults = {
                str: "",
                unicode: "",
                bool: False,
................................................................................
        if align:
            a = gtk.Alignment()
            a.set_padding(0, 0, align, 0)
            a.add(w)
            w = a
        w.show_all()
        return w



























    # Attach textual menu entry and callback
    @staticmethod
    def add_menu(menuwidget, label, action, insert=None):
        for where in list(menuwidget):
            m = gtk.MenuItem(label)







>












<

>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
...
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
                    for attr,val in list(cell[3].items()):
                        col.add_attribute(rend, attr, val)
                    # next
                    datapos += 1
                    #log.INFO(cell, len(cell))

                # add column to treeview
                #log.E(col)
                widget.append_column(col)
           
        # add data?
        if (entries is not None):
            #- expand datamap
            vartypes = []  #(str, str, bool, str, int, int, gtk.gdk.Pixbuf, str, int)
            rowmap = []    #["title", "desc", "bookmarked", "name", "count", "max", "img", ...]
            for desc in datamap:
                for var in xrange(2, len(desc)):
                    vartypes.append(desc[var][1])  # content types
                    rowmap.append(desc[var][0])    # dict{} column keys in entries[] list
            # create gtk array storage

            #log.UI(vartypes, len(vartypes))
            ls = gtk.ListStore(*vartypes)   # could be a TreeStore, too
            #log.DATA(rowmap, len(rowmap))
 
            # prepare for missing values, and special variable types
            defaults = {
                str: "",
                unicode: "",
                bool: False,
................................................................................
        if align:
            a = gtk.Alignment()
            a.set_padding(0, 0, align, 0)
            a.add(w)
            w = a
        w.show_all()
        return w
    
    
    # Config win table
    @staticmethod
    def config_treeview(opt):
        w = gtk.TreeView()
        w.set_property("width_request", 450)
        w.set_property("height_request", 125)
        # options
        _k,_v = str(opt.get("rows", "x,y")).split(",")
        # fill columns
        liststore, rowmap, pix_entry = uikit.columns(
            w,
            [    # datamap
                 [_k,125, [_k,str,"text",{"editable":2}] ],
                 [_v,275, [_v,str,"text",{"editable":True}] ],
                 [None,0, ['b',bool,None,{}] ],
                 [None,0, ['i',str,None,{}] ]
            ],
            [{}]
        )
        for i,tvc in enumerate(w.get_children()):
          for tvcr in tvc.get_children():
            tvcr.connect("edited", lambda *x: log.EDIT(x))
        return w, liststore


    # Attach textual menu entry and callback
    @staticmethod
    def add_menu(menuwidget, label, action, insert=None):
        for where in list(menuwidget):
            m = gtk.MenuItem(label)