Stefan Schuermans commited on 2013-11-23 17:19:11
              Showing 3 changed files, with 63 additions and 67 deletions.
            
| ... | ... | @@ -24,16 +24,21 @@ | 
| 24 | 24 | <property name="visible">True</property> | 
| 25 | 25 | <property name="can_focus">True</property> | 
| 26 | 26 | <property name="model">PlaylistStore</property> | 
| 27 | + <property name="headers_clickable">False</property> | |
| 28 | + <property name="rules_hint">True</property> | |
| 29 | + <property name="show_expanders">False</property> | |
| 27 | 30 | <signal name="row-activated" handler="onPlaylistDblClick" swapped="no"/> | 
| 28 | 31 | <child internal-child="selection"> | 
| 29 | 32 | <object class="GtkTreeSelection" id="PlaylistViewSelection"/> | 
| 30 | 33 | </child> | 
| 31 | 34 | <child> | 
| 32 | 35 | <object class="GtkTreeViewColumn" id="PlaylistColumnName"> | 
| 36 | + <property name="sizing">autosize</property> | |
| 33 | 37 | <property name="title" translatable="yes">Name</property> | 
| 34 | - <property name="sort_order">descending</property> | |
| 35 | 38 | <child> | 
| 36 | - <object class="GtkCellRendererText" id="PlaylistCellRendererTextName"/> | |
| 39 | + <object class="GtkCellRendererText" id="PlaylistCellRendererTextName"> | |
| 40 | + <property name="xalign">0</property> | |
| 41 | + </object> | |
| 37 | 42 | <attributes> | 
| 38 | 43 | <attribute name="text">2</attribute> | 
| 39 | 44 | <attribute name="weight">1</attribute> | 
| ... | ... | @@ -43,9 +48,13 @@ | 
| 43 | 48 | </child> | 
| 44 | 49 | <child> | 
| 45 | 50 | <object class="GtkTreeViewColumn" id="PlaylistColumnDuration"> | 
| 51 | + <property name="sizing">autosize</property> | |
| 46 | 52 | <property name="title" translatable="yes">Duration</property> | 
| 53 | + <property name="alignment">1</property> | |
| 47 | 54 | <child> | 
| 48 | - <object class="GtkCellRendererText" id="PlaylistCellRendererTextDuration"/> | |
| 55 | + <object class="GtkCellRendererText" id="PlaylistCellRendererTextDuration"> | |
| 56 | + <property name="xalign">1</property> | |
| 57 | + </object> | |
| 49 | 58 | <attributes> | 
| 50 | 59 | <attribute name="text">3</attribute> | 
| 51 | 60 | <attribute name="weight">1</attribute> | 
| ... | ... | @@ -54,6 +63,9 @@ | 
| 54 | 63 | </child> | 
| 55 | 64 | </object> | 
| 56 | 65 | </child> | 
| 66 | + <child> | |
| 67 | + <object class="GtkTreeViewColumn" id="PlaylistColumnDummy"/> | |
| 68 | + </child> | |
| 57 | 69 | </object> | 
| 58 | 70 | </child> | 
| 59 | 71 | </object> | 
| ... | ... | @@ -151,25 +163,6 @@ | 
| 151 | 163 | <property name="position">0</property> | 
| 152 | 164 | </packing> | 
| 153 | 165 | </child> | 
| 154 | - <child> | |
| 155 | - <object class="GtkButton" id="Backward"> | |
| 156 | - <property name="label">gtk-media-rewind</property> | |
| 157 | - <property name="use_action_appearance">False</property> | |
| 158 | - <property name="visible">True</property> | |
| 159 | - <property name="can_focus">True</property> | |
| 160 | - <property name="receives_default">True</property> | |
| 161 | - <property name="margin_right">3</property> | |
| 162 | - <property name="use_action_appearance">False</property> | |
| 163 | - <property name="use_stock">True</property> | |
| 164 | - <property name="image_position">top</property> | |
| 165 | - <signal name="clicked" handler="onBackward" swapped="no"/> | |
| 166 | - </object> | |
| 167 | - <packing> | |
| 168 | - <property name="expand">True</property> | |
| 169 | - <property name="fill">True</property> | |
| 170 | - <property name="position">1</property> | |
| 171 | - </packing> | |
| 172 | - </child> | |
| 173 | 166 | <child> | 
| 174 | 167 | <object class="GtkButton" id="Stop"> | 
| 175 | 168 | <property name="label">gtk-media-stop</property> | 
| ... | ... | @@ -186,7 +179,7 @@ | 
| 186 | 179 | <packing> | 
| 187 | 180 | <property name="expand">True</property> | 
| 188 | 181 | <property name="fill">True</property> | 
| 189 | - <property name="position">2</property> | |
| 182 | + <property name="position">1</property> | |
| 190 | 183 | </packing> | 
| 191 | 184 | </child> | 
| 192 | 185 | <child> | 
| ... | ... | @@ -204,7 +197,7 @@ | 
| 204 | 197 | <packing> | 
| 205 | 198 | <property name="expand">True</property> | 
| 206 | 199 | <property name="fill">True</property> | 
| 207 | - <property name="position">3</property> | |
| 200 | + <property name="position">2</property> | |
| 208 | 201 | </packing> | 
| 209 | 202 | </child> | 
| 210 | 203 | <child> | 
| ... | ... | @@ -223,26 +216,7 @@ | 
| 223 | 216 | <packing> | 
| 224 | 217 | <property name="expand">True</property> | 
| 225 | 218 | <property name="fill">True</property> | 
| 226 | - <property name="position">4</property> | |
| 227 | - </packing> | |
| 228 | - </child> | |
| 229 | - <child> | |
| 230 | - <object class="GtkButton" id="Forward"> | |
| 231 | - <property name="label">gtk-media-forward</property> | |
| 232 | - <property name="use_action_appearance">False</property> | |
| 233 | - <property name="visible">True</property> | |
| 234 | - <property name="can_focus">True</property> | |
| 235 | - <property name="receives_default">True</property> | |
| 236 | - <property name="margin_right">3</property> | |
| 237 | - <property name="use_action_appearance">False</property> | |
| 238 | - <property name="use_stock">True</property> | |
| 239 | - <property name="image_position">top</property> | |
| 240 | - <signal name="clicked" handler="onForward" swapped="no"/> | |
| 241 | - </object> | |
| 242 | - <packing> | |
| 243 | - <property name="expand">True</property> | |
| 244 | - <property name="fill">True</property> | |
| 245 | - <property name="position">5</property> | |
| 219 | + <property name="position">3</property> | |
| 246 | 220 | </packing> | 
| 247 | 221 | </child> | 
| 248 | 222 | <child> | 
| ... | ... | @@ -261,7 +235,7 @@ | 
| 261 | 235 | <packing> | 
| 262 | 236 | <property name="expand">True</property> | 
| 263 | 237 | <property name="fill">True</property> | 
| 264 | - <property name="position">6</property> | |
| 238 | + <property name="position">4</property> | |
| 265 | 239 | </packing> | 
| 266 | 240 | </child> | 
| 267 | 241 | </object> | 
| ... | ... | @@ -31,11 +31,9 @@ class SyncGui: | 
| 31 | 31 | "onPlaylistDblClick": self.onPlaylistDblClick, | 
| 32 | 32 | "onNewPosition": self.onNewPosition, | 
| 33 | 33 | "onPrevious": self.onPrevious, | 
| 34 | - "onBackward": self.onBackward, | |
| 35 | 34 | "onStop": self.onStop, | 
| 36 | 35 | "onPause": self.onPause, | 
| 37 | 36 | "onPlay": self.onPlay, | 
| 38 | - "onForward": self.onForward, | |
| 39 | 37 | "onNext": self.onNext, | 
| 40 | 38 | } | 
| 41 | 39 | self.builder.connect_signals(handlers) | 
| ... | ... | @@ -94,6 +92,10 @@ class SyncGui: | 
| 94 | 92 |  | 
| 95 | 93 | def updateEntry(self): | 
| 96 | 94 | """update current entry of playlist and duration, position, ...""" | 
| 95 | + # clear selection of playlist | |
| 96 | + sel = self.widPlaylistView.get_selection() | |
| 97 | + if sel: | |
| 98 | + sel.unselect_all() | |
| 97 | 99 | # sanity check for entry index | 
| 98 | 100 | if self.stEntryIdx < -1 or self.stEntryIdx >= len(self.playlist.entries): | 
| 99 | 101 | self.stEntryIdx = -1 | 
| ... | ... | @@ -104,9 +106,14 @@ class SyncGui: | 
| 104 | 106 | weight = pango.WEIGHT_BOLD | 
| 105 | 107 | else: | 
| 106 | 108 | weight = pango.WEIGHT_NORMAL | 
| 107 | -      print("DEBUG sync_gui idx=%d weight=%d" % (idx, weight)) | |
| 108 | 109 | model.set(it, 1, weight) | 
| 109 | 110 | self.widPlaylistStore.foreach(update, None) | 
| 111 | + # playing and (no entry or stop entry) | |
| 112 | + # -> stop playing and update button visibility | |
| 113 | + if self.stPlaying and (self.stEntryIdx < 0 or \ | |
| 114 | + self.playlist.entries[self.stEntryIdx]["type"] == "stop"): | |
| 115 | + self.stPlaying = False | |
| 116 | + self.updateButtonVisibility() | |
| 110 | 117 | # update duration, position, ... | 
| 111 | 118 | self.updateDuration() | 
| 112 | 119 |  | 
| ... | ... | @@ -128,17 +135,18 @@ class SyncGui: | 
| 128 | 135 | (model, it) = sel.get_selected() | 
| 129 | 136 | if it is not None: | 
| 130 | 137 | (idx,) = model.get(it, 0) | 
| 131 | -    print("DEBUG sync_gui playlist double-click idx=%d" % (idx)) | |
| 138 | +    #print("DEBUG sync_gui playlist double-click idx=%d" % (idx)) | |
| 132 | 139 | # update playlist entry | 
| 133 | 140 | self.stEntryIdx = idx | 
| 141 | + # set position to zero if playing | |
| 142 | + if self.stPlaying: | |
| 143 | + self.stPosition = 0 | |
| 134 | 144 | # update entry | 
| 135 | 145 | self.updateEntry() | 
| 136 | - # start playing | |
| 137 | - # TODO | |
| 138 | 146 |  | 
| 139 | 147 | def onNewPosition(self, widget, scroll, value): | 
| 140 | 148 | """slider has been moved to a new position""" | 
| 141 | -    print("DEBUG sync_gui new position " + str(value)); | |
| 149 | +    #print("DEBUG sync_gui new position " + str(value)); | |
| 142 | 150 | # clamp position to valid range | 
| 143 | 151 | if value < 0: | 
| 144 | 152 | value = 0 | 
| ... | ... | @@ -151,15 +159,17 @@ class SyncGui: | 
| 151 | 159 |  | 
| 152 | 160 | def onPrevious(self, widget): | 
| 153 | 161 | """previous button as been pressed""" | 
| 154 | -    print("DEBUG sync_gui previous") | |
| 155 | - | |
| 156 | - def onBackward(self, widget): | |
| 157 | - """backward button has been pressed""" | |
| 158 | -    print("DEBUG sync_gui backward") | |
| 162 | +    #print("DEBUG sync_gui previous") | |
| 163 | + # go to begin of previous entry (with wrap around) | |
| 164 | + self.stPosition = 0 | |
| 165 | + self.stEntryIdx = self.stEntryIdx - 1 | |
| 166 | + if self.stEntryIdx < 0: | |
| 167 | + self.stEntryIdx = len(self.playlist.entries) - 1 | |
| 168 | + self.updateEntry() | |
| 159 | 169 |  | 
| 160 | 170 | def onStop(self, widget): | 
| 161 | 171 | """stop button has been pressed""" | 
| 162 | -    print("DEBUG sync_gui stop") | |
| 172 | +    #print("DEBUG sync_gui stop") | |
| 163 | 173 | self.stPlaying = False | 
| 164 | 174 | self.stPosition = 0 # stop goes back to begin | 
| 165 | 175 | self.updatePosition() | 
| ... | ... | @@ -167,32 +177,40 @@ class SyncGui: | 
| 167 | 177 |  | 
| 168 | 178 | def onPause(self, widget): | 
| 169 | 179 | """pause button has been pressed""" | 
| 170 | -    print("DEBUG sync_gui pause") | |
| 180 | +    #print("DEBUG sync_gui pause") | |
| 171 | 181 | self.stPlaying = False | 
| 172 | 182 | self.updateButtonVisibility() | 
| 173 | 183 |  | 
| 174 | 184 | def onPlay(self, widget): | 
| 175 | 185 | """play button has been pressed""" | 
| 176 | -    print("DEBUG sync_gui play") | |
| 186 | +    #print("DEBUG sync_gui play") | |
| 177 | 187 | self.stPlaying = True | 
| 178 | 188 | self.updatePosition() | 
| 179 | 189 | self.updateButtonVisibility() | 
| 180 | 190 |  | 
| 181 | - def onForward(self, widget): | |
| 182 | - """forward button has been pressed""" | |
| 183 | -    print("DEBUG sync_gui forward") | |
| 184 | - | |
| 185 | 191 | def onNext(self, widget): | 
| 186 | 192 | """next button has been pressed""" | 
| 187 | -    print("DEBUG sync_gui next") | |
| 193 | +    #print("DEBUG sync_gui next") | |
| 194 | + # go to begin of next entry (with wrap around) | |
| 195 | + self.stPosition = 0 | |
| 196 | + self.stEntryIdx = self.stEntryIdx + 1 | |
| 197 | + if self.stEntryIdx >= len(self.playlist.entries): | |
| 198 | + self.stEntryIdx = 0 | |
| 199 | + self.updateEntry() | |
| 188 | 200 |  | 
| 189 | 201 | def onTimer10ms(self): | 
| 190 | 202 | """timer callback, every 10ms""" | 
| 191 | 203 | # update position if playing | 
| 192 | 204 | if self.stPlaying: | 
| 193 | 205 | self.stPosition = time.time() - self.stPlayStart | 
| 194 | - if self.stPosition > self.stDuration: | |
| 195 | - self.stPosition = 0 # FIXME: go to next entry | |
| 206 | + if self.stPosition >= self.stDuration: | |
| 207 | + # end of entry reached --> go to begin of next entry (with wrap around) | |
| 208 | + self.stPosition = 0 | |
| 209 | + self.stEntryIdx = self.stEntryIdx + 1 | |
| 210 | + if self.stEntryIdx >= len(self.playlist.entries): | |
| 211 | + self.stEntryIdx = 0 | |
| 212 | + self.updateEntry() | |
| 213 | + else: | |
| 196 | 214 | self.updatePosition() | 
| 197 | 215 | return True | 
| 198 | 216 |  | 
| 199 | 217 |