Browse code

initial implementation

Dario Rodriguez authored on 09/01/2015 17:43:05
Showing 1 changed files
1 1
new file mode 100755
... ...
@@ -0,0 +1,260 @@
1
+#!/usr/bin/wish
2
+
3
+# apt-get install libtk-img
4
+package require Img
5
+
6
+
7
+option add *font "-*-*-*-*-*-*-34-*-*-*-*-*-*-*"
8
+option add *.borderwidth 1
9
+set tk_strictMotif
10
+
11
+wm title . "mamegui.tcl"
12
+
13
+
14
+#-------------------------------------
15
+# Scrolled frame implementation
16
+# http://wiki.tcl.tk/9223
17
+#-------------------------------------
18
+# sframe.tcl
19
+# Paul Walton
20
+# Create a ttk-compatible, scrollable frame widget.
21
+#   Usage:
22
+#       sframe new <path> ?-toplevel true?  ?-anchor nsew?
23
+#       -> <path>
24
+#
25
+#       sframe content <path>
26
+#       -> <path of child frame where the content should go>
27
+
28
+namespace eval sframe {
29
+    namespace ensemble create
30
+    namespace export *
31
+
32
+    # Create a scrollable frame or window.
33
+    proc new {path args} {
34
+        # Use the ttk theme's background for the canvas and toplevel
35
+        set bg [ttk::style lookup TFrame -background]
36
+        if { [ttk::style theme use] eq "aqua" } {
37
+            # Use a specific color on the aqua theme as 'ttk::style lookup' is not accurate.
38
+            set bg "#e9e9e9"
39
+        }
40
+
41
+        # Create the main frame or toplevel.
42
+        if { [dict exists $args -toplevel]  &&  [dict get $args -toplevel] } {
43
+            toplevel $path  -bg $bg
44
+        } else {
45
+            ttk::frame $path
46
+        }
47
+
48
+        # Create a scrollable canvas with scrollbars which will always be the same size as the main frame.
49
+        set canvas [canvas $path.canvas -bg $bg -bd 0 -highlightthickness 0 -yscrollcommand [list $path.scrolly set] -xscrollcommand [list $path.scrollx set]]
50
+        ttk::scrollbar $path.scrolly -orient vertical   -command [list $canvas yview]
51
+        ttk::scrollbar $path.scrollx -orient horizontal -command [list $canvas xview]
52
+
53
+        # Create a container frame which will always be the same size as the canvas or content, whichever is greater.
54
+        # This allows the child content frame to be properly packed and also is a surefire way to use the proper ttk background.
55
+        set container [ttk::frame $canvas.container]
56
+        pack propagate $container 0
57
+
58
+        # Create the content frame. Its size will be determined by its contents. This is useful for determining if the
59
+        # scrollbars need to be shown.
60
+        set content [ttk::frame $container.content]
61
+
62
+        # Pack the content frame and place the container as a canvas item.
63
+        set anchor "n"
64
+        if { [dict exists $args -anchor] } {
65
+            set anchor [dict get $args -anchor]
66
+        }
67
+        pack $content -anchor $anchor
68
+        $canvas create window 0 0 -window $container -anchor nw
69
+
70
+        # Grid the scrollable canvas sans scrollbars within the main frame.
71
+        grid $canvas   -row 0 -column 0 -sticky nsew
72
+        grid rowconfigure    $path 0 -weight 1
73
+        grid columnconfigure $path 0 -weight 1
74
+
75
+        # Make adjustments when the the sframe is resized or the contents change size.
76
+        bind $path.canvas <Expose> [list [namespace current]::resize $path]
77
+
78
+        # Mousewheel bindings for scrolling.
79
+        bind [winfo toplevel $path] <MouseWheel>       [list +[namespace current] scroll $path yview %W %D]
80
+        bind [winfo toplevel $path] <Shift-MouseWheel> [list +[namespace current] scroll $path xview %W %D]
81
+
82
+        return $path
83
+    }
84
+
85
+
86
+    # Given the toplevel path of an sframe widget, return the path of the child frame suitable for content.
87
+    proc content {path} {
88
+        return $path.canvas.container.content
89
+    }
90
+
91
+
92
+    # Make adjustments when the the sframe is resized or the contents change size.
93
+    proc resize {path} {
94
+        set canvas    $path.canvas
95
+        set container $canvas.container
96
+        set content   $container.content
97
+
98
+        # Set the size of the container. At a minimum use the same width & height as the canvas.
99
+        set width  [winfo width $canvas]
100
+        set height [winfo height $canvas]
101
+
102
+        # If the requested width or height of the content frame is greater then use that width or height.
103
+        if { [winfo reqwidth $content] > $width } {
104
+            set width [winfo reqwidth $content]
105
+        }
106
+        if { [winfo reqheight $content] > $height } {
107
+            set height [winfo reqheight $content]
108
+        }
109
+        $container configure  -width $width  -height $height
110
+
111
+        # Configure the canvas's scroll region to match the height and width of the container.
112
+        $canvas configure -scrollregion "0 0 $width $height"
113
+
114
+        # Show or hide the scrollbars as necessary.
115
+        # Horizontal scrolling.
116
+        if { [winfo reqwidth $content] > [winfo width $canvas] } {
117
+            grid $path.scrollx  -row 1 -column 0 -sticky ew
118
+        } else {
119
+            grid forget $path.scrollx
120
+        }
121
+        # Vertical scrolling.
122
+        if { [winfo reqheight $content] > [winfo height $canvas] } {
123
+            grid $path.scrolly  -row 0 -column 1 -sticky ns
124
+        } else {
125
+            grid forget $path.scrolly
126
+        }
127
+        return
128
+    }
129
+
130
+
131
+    # Handle mousewheel scrolling.
132
+    proc scroll {path view W D} {
133
+        if { [winfo exists $path.canvas]  &&  [string match $path.canvas* $W] } {
134
+            $path.canvas $view scroll [expr {-$D}] units
135
+        }
136
+        return
137
+    }
138
+}
139
+#-------------------------------------
140
+# End of Scrolled frame implementation
141
+#-------------------------------------
142
+
143
+#-------------------------------------
144
+# Read png header implementation
145
+# http://wiki.tcl.tk/759
146
+#-------------------------------------
147
+proc read_png_header {file} {
148
+   set fh [open $file r]
149
+   fconfigure $fh -encoding binary -translation binary -eofchar {}
150
+   if {[read $fh 8] != "\x89PNG\r\n\x1a\n"} { close $fh; return }
151
+   binary scan [read $fh 8] Ia4 len type
152
+   set r [read $fh $len]
153
+   if {![eof $fh] && $type == "IHDR"} {
154
+       binary scan $r IIccccc width height depth color compression filter interlace
155
+       close $fh
156
+       return [list $width $height $depth $color $compression $filter $interlace]
157
+   }
158
+   close $fh
159
+   return
160
+}
161
+#-------------------------------------
162
+# End of Read png header implementation
163
+#-------------------------------------
164
+
165
+
166
+# files locations
167
+set mameconf "/etc/mame/mame.ini"
168
+set snapsdir "/usr/local/share/games/mame/snaps/"
169
+set catverini "/usr/local/share/gnome-video-arcade/catver.ini"
170
+set historydat "/usr/local/share/gnome-video-arcade/history.dat"
171
+set nplayersini "/usr/share/games/mame/data/nplayers.ini"
172
+
173
+set rompaths [split [regsub {\$HOME} [lindex [split [exec grep ^rompath $mameconf ] " "] end] "$env(HOME)\1"] ";"]
174
+
175
+set games "dynablst gauntlet snowbro2"
176
+
177
+set gameslist [split [exec sh -c "grep =4P.sim $nplayersini | cut -d '=' -f 1 | tr '\n' ':' | head -20"] ":"]
178
+
179
+set gamesnoalt [lsort [split [exec sh -c " cat $historydat | grep \"^.info=\" | cut -d '=' -f 2 | cut -d ',' -f 1 | tr '\n' ':'"] ":"]]
180
+
181
+foreach i $gameslist {
182
+        if {[lsearch -glob $games $i]==-1 && [lsearch -glob -sort $gamesnoalt $i]!=-1} {
183
+                lappend games $i
184
+        }
185
+}
186
+
187
+foreach i $rompaths {
188
+        puts $i
189
+}
190
+
191
+# The UI
192
+proc add_navibuttons { page pagesize parent} {
193
+        global games
194
+        set n [llength $games]
195
+        if { $page>0 } {
196
+                button $parent.prev -text "<<< [expr $page-1+1] <<< " -command "redraw_list [expr $page-1]"
197
+                pack $parent.prev -side left -fill none -expand false
198
+        }
199
+        set totalpages [expr $n/$pagesize]
200
+        label $parent.current -text "[expr $page+1] of [expr $totalpages+1]"
201
+        pack $parent.current -side left -fill none -expand false
202
+        if { $page<$totalpages } {
203
+                button $parent.next -text ">>> [expr $page+1+1] >>>" -command "redraw_list [expr $page+1]"
204
+                pack $parent.next -side left -fill none -expand false
205
+        }
206
+
207
+}
208
+
209
+proc redraw_list { page } {
210
+        global games snapsdir
211
+        catch { destroy .gameslist }
212
+        # Use the -toplevel option to create a scrollable toplevel window.
213
+        sframe new .gameslist -anchor w
214
+        pack .gameslist -side top -fill both -expand true
215
+
216
+        # Retrieve the path where the scrollable contents go.
217
+        set sf [sframe content .gameslist]
218
+
219
+        set pagesize 30
220
+        frame $sf.buttonstop
221
+        add_navibuttons $page $pagesize $sf.buttonstop
222
+        pack $sf.buttonstop -side top -fill x -expand true
223
+
224
+        set n 0
225
+        foreach i $games {
226
+                if { $n<[expr $page*$pagesize] || $n>=[expr $page*$pagesize+$pagesize] } {
227
+                        incr n
228
+                        continue
229
+                }
230
+                set f [frame $sf.f$n -relief raised -borderwidth 15]
231
+                button $f.nombre -text "$i" -command "exec mame $i"
232
+                pack $f.nombre -side left -fill both -expand true
233
+                bind $f <1> "event generate $f.nombre <1>
234
+                                 $f.nombre invoke
235
+                                 after 100 \"event generate $f.nombre <ButtonRelease-1>\""
236
+                set imgfile $snapsdir/[set i].png
237
+                if { [file isfile $imgfile] } {
238
+                        puts "$n $imgfile"
239
+                        set im1 [image create photo -file $imgfile]
240
+                        set xsize [lindex [read_png_header $imgfile] 0]
241
+                        if { $xsize<=384 } {
242
+                                set im2 [image create photo]
243
+                                $im2 copy $im1 -zoom 2 2
244
+                                label $f.img -image $im2
245
+                        } else {
246
+                                label $f.img -image $im1
247
+                        }
248
+                        pack $f.img -side left -fill none -expand false
249
+                }
250
+                pack $f -side top -fill x -expand true
251
+                incr n
252
+        }
253
+        frame $sf.buttonsbottom
254
+        add_navibuttons $page $pagesize $sf.buttonsbottom
255
+        pack $sf.buttonsbottom -side top -fill x -expand true
256
+}
257
+
258
+redraw_list 0
259
+bind . <Escape> { exit 0 }
260
+