#Copyright (c) 2008, Media Modifications Ltd. #Permission is hereby granted, free of charge, to any person obtaining a copy #of this software and associated documentation files (the "Software"), to deal #in the Software without restriction, including without limitation the rights #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #copies of the Software, and to permit persons to whom the Software is #furnished to do so, subject to the following conditions: #The above copyright notice and this permission notice shall be included in #all copies or substantial portions of the Software. #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN #THE SOFTWARE. import gtk from gtk import gdk from gtk import keysyms import gobject import cairo import os import pygst pygst.require('0.10') import gst import gst.interfaces import math import shutil import time import pango import hippo import logging logger = logging.getLogger('record:ui.py') #from sugar.graphics.toolcombobox import ToolComboBox #from sugar.graphics.tray import HTray from sugar.graphics.toolbutton import ToolButton from sugar import profile from sugar import util from sugar.activity import activity from sugar.graphics import style from instance import Instance from constants import Constants, istrMinutes, istrSeconds from color import Color from p5 import P5 from p5_button import P5Button from p5_button import Polygon from p5_button import Button import glive from glive import LiveVideoWindow from gplay import PlayVideoWindow from recorded import Recorded from button import RecdButton import utils import record import aplay from tray import HTray from toolbarcombobox import ToolComboBox class UI: dim_THUMB_WIDTH = 108 dim_THUMB_HEIGHT = 81 dim_INSET = 10 dim_PIPW = 160 dim_PIPH = 120 #pipBorder dim_PIP_BORDER = 4 dim_PGDW = dim_PIPW + (dim_PIP_BORDER*2) dim_PGDH = dim_PIPH + (dim_PIP_BORDER*2) dim_CONTROLBAR_HT = 55 def __init__( self, pca ): self.ca = pca self.ACTIVE = False self.LAUNCHING = True self.ca.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) self.ca.connect("visibility-notify-event", self._visibleNotifyCb) self.inset = self.__class__.dim_INSET self.pgdh = self.__class__.dim_PGDH self.pgdw = self.__class__.dim_PGDW self.thumbTrayHt = 150 #todo: get sugar constant here self.thumbSvgW = 124 self.thumbSvgH = 124 self.maxw = 49 self.maxh = 49 self.controlBarHt = 60 self.recordButtWd = 55 self.pipw = self.__class__.dim_PIPW self.piph = self.__class__.dim_PIPH #ui modes # True when we're in full-screen mode, False otherwise self.FULLSCREEN = False # True when we're showing live video feed in the primary screen # area, False otherwise (even when we are still showing live video # in a p-i-p) self.LIVEMODE = True self.LAST_MODE = -1 self.LAST_FULLSCREEN = False self.LAST_LIVE = True self.LAST_MESHING = False self.LAST_RECD_INFO = False self.LAST_TRANSCODING = False self.TRANSCODING = False self.MESHING = False # RECD_INFO_ON is True when the 'info' for a recording is being # display on-screen (who recorded it, tags, etc), and False otherwise. self.RECD_INFO_ON = False self.UPDATE_DURATION_ID = 0 self.UPDATE_TIMER_ID = 0 self.COUNTINGDOWN = False #init self.mapped = False self.centered = False self.setup = False #prep for when to show self.shownRecd = None #this includes the default sharing tab self.toolbox = activity.ActivityToolbox(self.ca) self.ca.set_toolbox(self.toolbox) if glive.camera_presents: self.photoToolbar = PhotoToolbar() self.photoToolbar.set_sensitive( False ) self.toolbox.add_toolbar( Constants.istrPhoto, self.photoToolbar ) self.videoToolbar = VideoToolbar() self.videoToolbar.set_sensitive( False ) self.toolbox.add_toolbar( Constants.istrVideo, self.videoToolbar ) self.tbars = { Constants.MODE_PHOTO: 1, Constants.MODE_VIDEO: 2, Constants.MODE_AUDIO: 3 } else: self.photoToolbar = None self.videoToolbar = None self.tbars = { Constants.MODE_AUDIO: 1 } self.ca.m.MODE = Constants.MODE_AUDIO self.audioToolbar = AudioToolbar() self.audioToolbar.set_sensitive( False ) self.toolbox.add_toolbar( Constants.istrAudio, self.audioToolbar ) self.toolbox.set_current_toolbar(self.tbars[self.ca.m.MODE]) self.toolbox.remove(self.toolbox._separator) #taken directly from toolbox.py b/c I don't know how to mod the hongry hippo separator = hippo.Canvas() box = hippo.CanvasBox( border_color=Constants.colorBlack.get_int(), background_color=Constants.colorBlack.get_int(), box_height=style.TOOLBOX_SEPARATOR_HEIGHT, border_bottom=style.LINE_WIDTH) separator.set_root(box) self.toolbox.pack_start(separator, False) self.toolbox.separator = separator self.TOOLBOX_SIZE_ALLOCATE_ID = self.toolbox.connect_after("size-allocate", self._toolboxSizeAllocateCb) self.toolbox._notebook.set_property("can-focus", False) self.toolbox.connect("current-toolbar-changed", self._toolbarChangeCb) self.toolbox.show_all() def serialize(self): data = {} if self.photoToolbar: data['photo_timer'] = self.photoToolbar.timerCb.combo.get_active() if self.videoToolbar: data['video_timer'] = self.videoToolbar.timerCb.combo.get_active() data['video_duration'] = self.videoToolbar.durCb.combo.get_active() data['video_quality'] = self.videoToolbar.quality.combo.get_active() data['audio_timer'] = self.audioToolbar.timerCb.combo.get_active() data['audio_duration'] = self.audioToolbar.durCb.combo.get_active() return data def deserialize(self, data): if self.photoToolbar: self.photoToolbar.timerCb.combo.set_active( data.get('photo_timer', 0)) if self.videoToolbar: self.videoToolbar.timerCb.combo.set_active( data.get('video_timer', 0)) self.videoToolbar.durCb.combo.set_active( data.get('video_duration', 0)) self.videoToolbar.quality.combo.set_active( data.get('video_quality', 0)) self.audioToolbar.timerCb.combo.set_active(data.get('audio_timer', 0)) self.audioToolbar.durCb.combo.set_active(data.get('audio_duration')) def _toolboxSizeAllocateCb( self, widget, event ): self.toolbox.disconnect( self.TOOLBOX_SIZE_ALLOCATE_ID) toolboxHt = self.toolbox.size_request()[1] self.vh = gtk.gdk.screen_height()-(self.thumbTrayHt+toolboxHt+self.controlBarHt) self.vw = int(self.vh/.75) self.letterBoxW = (gtk.gdk.screen_width() - self.vw)/2 self.letterBoxVW = (self.vw/2)-(self.inset*2) self.letterBoxVH = int(self.letterBoxVW*.75) self.setUpWindows() #now that we know how big the toolbox is, we can layout more gobject.idle_add( self.layout ) def layout( self ): self.mainBox = gtk.VBox() self.ca.set_canvas(self.mainBox) topBox = gtk.HBox() self.mainBox.pack_start(topBox, expand=True) leftFill = gtk.VBox() leftFill.set_size_request( self.letterBoxW, -1 ) self.leftFillBox = gtk.EventBox( ) self.leftFillBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) leftFill.add( self.leftFillBox ) topBox.pack_start( leftFill, expand=True ) centerVBox = gtk.VBox() centerVBox.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) topBox.pack_start( centerVBox, expand=True ) self.centerBox = gtk.EventBox() self.centerBox.set_size_request(self.vw, -1) self.centerBox.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) centerVBox.pack_start( self.centerBox, expand=True ) centerSizer = gtk.VBox() centerSizer.set_size_request(self.vw, -1) centerSizer.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) self.centerBox.add(centerSizer) self.bottomCenter = gtk.EventBox() self.bottomCenter.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) self.bottomCenter.set_size_request(self.vw, self.controlBarHt) centerVBox.pack_start( self.bottomCenter, expand=False ) #into the center box we can put this guy... self.backgdCanvasBox = gtk.VBox() self.backgdCanvasBox.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) self.backgdCanvasBox.set_size_request(self.vw, -1) self.backgdCanvas = PhotoCanvas() self.backgdCanvas.set_size_request(self.vw, self.vh) self.backgdCanvasBox.pack_start( self.backgdCanvas, expand=False ) #or this guy... self.infoBox = gtk.EventBox() self.infoBox.modify_bg( gtk.STATE_NORMAL, Constants.colorButton.gColor ) iinfoBox = gtk.VBox(spacing=self.inset) self.infoBox.add( iinfoBox ) iinfoBox.set_size_request(self.vw, -1) iinfoBox.set_border_width(self.inset) rightFill = gtk.VBox() rightFill.set_size_request( self.letterBoxW, -1 ) rightFillBox = gtk.EventBox() rightFillBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) rightFill.add( rightFillBox ) topBox.pack_start( rightFill, expand=True ) #info box innards: self.infoBoxTop = gtk.HBox() iinfoBox.pack_start( self.infoBoxTop, expand=True ) self.infoBoxTopLeft = gtk.VBox(spacing=self.inset) self.infoBoxTop.pack_start( self.infoBoxTopLeft ) self.infoBoxTopRight = gtk.VBox() self.infoBoxTopRight.set_size_request(self.letterBoxVW, -1) self.infoBoxTop.pack_start( self.infoBoxTopRight ) self.namePanel = gtk.HBox() leftInfBalance = gtk.VBox() self.nameLabel = gtk.Label(""+Constants.istrTitle+"") self.nameLabel.set_use_markup( True ) self.namePanel.pack_start( self.nameLabel, expand=False, padding=self.inset ) self.nameLabel.set_alignment(0, .5) self.nameTextfield = gtk.Entry(140) self.nameTextfield.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) self.nameTextfield.connect('changed', self._nameTextfieldEditedCb ) self.nameTextfield.set_alignment(0) self.nameTextfield.set_size_request( -1, self.controlBarHt-(self.inset*2) ) self.namePanel.pack_start(self.nameTextfield) self.photographerPanel = gtk.VBox(spacing=self.inset) self.infoBoxTopLeft.pack_start(self.photographerPanel, expand=False) photographerLabel = gtk.Label("" + Constants.istrRecorder + "") photographerLabel.set_use_markup( True ) self.photographerPanel.pack_start(photographerLabel, expand=False) photographerLabel.set_alignment(0, .5) photoNamePanel = gtk.HBox(spacing=self.inset) self.photographerPanel.pack_start(photoNamePanel) self.photoXoPanel = xoPanel() photoNamePanel.pack_start( self.photoXoPanel, expand=False ) self.photoXoPanel.set_size_request( 40, 40 ) self.photographerNameLabel = gtk.Label("") self.photographerNameLabel.set_alignment(0, .5) photoNamePanel.pack_start(self.photographerNameLabel) self.datePanel = gtk.HBox(spacing=self.inset) self.infoBoxTopLeft.pack_start(self.datePanel, expand=False) dateLabel = gtk.Label(""+Constants.istrDate+"") dateLabel.set_use_markup(True) self.datePanel.pack_start(dateLabel, expand=False) self.dateDateLabel = gtk.Label("") self.dateDateLabel.set_alignment(0, .5) self.datePanel.pack_start(self.dateDateLabel) self.tagsPanel = gtk.VBox(spacing=self.inset) tagsLabel = gtk.Label(""+Constants.istrTags+"") tagsLabel.set_use_markup(True) tagsLabel.set_alignment(0, .5) self.tagsPanel.pack_start(tagsLabel, expand=False) self.tagsBuffer = gtk.TextBuffer() self.tagsBuffer.connect('changed', self._tagsBufferEditedCb) self.tagsField = gtk.TextView(self.tagsBuffer) self.tagsField.set_size_request( 100, 100 ) self.tagsPanel.pack_start(self.tagsField, expand=True) self.infoBoxTopLeft.pack_start(self.tagsPanel, expand=True) infoBotBox = gtk.HBox() infoBotBox.set_size_request( -1, self.pgdh+self.inset ) iinfoBox.pack_start(infoBotBox, expand=False) thumbnailsEventBox = gtk.EventBox() thumbnailsEventBox.set_size_request( -1, self.thumbTrayHt ) thumbnailsBox = gtk.HBox( ) thumbnailsEventBox.add( thumbnailsBox ) self.thumbTray = HTray() self.thumbTray.set_size_request( -1, self.thumbTrayHt ) self.mainBox.pack_end( self.thumbTray, expand=False ) self.thumbTray.show() self.CENTER_SIZE_ALLOCATE_ID = self.centerBox.connect_after("size-allocate", self._centerSizeAllocateCb) self.ca.show_all() def _centerSizeAllocateCb( self, widget, event ): #initial setup of the panels self.centerBox.disconnect(self.CENTER_SIZE_ALLOCATE_ID) self.centerBoxPos = self.centerBox.translate_coordinates( self.ca, 0, 0 ) centerKid = self.centerBox.get_child() if (centerKid != None): self.centerBox.remove( centerKid ) self.centered = True self.setUp() def _mapEventCb( self, widget, event ): #when your parent window is ready, turn on the feed of live video self.liveVideoWindow.disconnect(self.MAP_EVENT_ID) self.mapped = True self.setUp() def setUp( self ): if (self.mapped and self.centered and not self.setup): self.setup = True #set correct window sizes self.setUpWindowsSizes() #listen for ctrl+c & game key buttons self.ca.connect('key-press-event', self._keyPressEventCb) #overlay widgets can go away after they've been on screen for a while self.HIDE_WIDGET_TIMEOUT_ID = 0 self.hiddenWidgets = False self.resetWidgetFadeTimer() self.showLiveVideoTags() if self.photoToolbar: self.photoToolbar.set_sensitive( True ) if self.videoToolbar: self.videoToolbar.set_sensitive( True ) self.audioToolbar.set_sensitive( True ) #initialize the app with the default thumbs self.ca.m.setupMode( self.ca.m.MODE, True ) gobject.idle_add( self.finalSetUp ) def finalSetUp( self ): self.LAUNCHING = False self.ACTIVE = self.ca.get_property( "visible" ) self.updateVideoComponents() if (self.ACTIVE): self.ca.glive.play() def setUpWindows( self ): #image windows self.windowStack = [] #live video windows self.livePhotoWindow = gtk.Window() self.livePhotoWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.livePhotoWindow.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) self.addToWindowStack( self.livePhotoWindow, self.ca ) self.livePhotoCanvas = PhotoCanvas() self.livePhotoWindow.add(self.livePhotoCanvas) self.livePhotoWindow.connect("button_release_event", self._mediaClickedForPlayback) self.livePhotoWindow.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) self.livePhotoWindow.connect("visibility-notify-event", self._visibleNotifyCb) #video playback windows self.playOggWindow = PlayVideoWindow(Constants.colorBlack.gColor) self.addToWindowStack( self.playOggWindow, self.windowStack[len(self.windowStack)-1] ) #self.playOggWindow.set_gplay(self.ca.gplay) self.ca.gplay.window = self.playOggWindow self.playOggWindow.set_events(gtk.gdk.BUTTON_RELEASE_MASK) self.playOggWindow.connect("button_release_event", self._mediaClickedForPlayback) self.playOggWindow.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) self.playOggWindow.connect("visibility-notify-event", self._visibleNotifyCb) #border behind self.pipBgdWindow = gtk.Window() self.pipBgdWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorWhite.gColor ) self.pipBgdWindow.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorWhite.gColor ) self.addToWindowStack( self.pipBgdWindow, self.windowStack[len(self.windowStack)-1] ) self.liveVideoWindow = LiveVideoWindow(Constants.colorBlack.gColor) self.addToWindowStack( self.liveVideoWindow, self.windowStack[len(self.windowStack)-1] ) self.liveVideoWindow.set_glive(self.ca.glive) self.liveVideoWindow.set_events(gtk.gdk.BUTTON_RELEASE_MASK) self.liveVideoWindow.connect("button_release_event", self._liveButtonReleaseCb) self.liveVideoWindow.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) self.liveVideoWindow.connect("visibility-notify-event", self._visibleNotifyCb) self.recordWindow = RecordWindow(self) self.addToWindowStack( self.recordWindow, self.windowStack[len(self.windowStack)-1] ) self.progressWindow = ProgressWindow(self) self.addToWindowStack( self.progressWindow, self.windowStack[len(self.windowStack)-1] ) self.maxWindow = gtk.Window() self.maxWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.maxWindow.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) maxButton = MaxButton(self) self.maxWindow.add( maxButton ) self.addToWindowStack( self.maxWindow, self.windowStack[len(self.windowStack)-1] ) self.scrubWindow = ScrubberWindow(self) self.addToWindowStack( self.scrubWindow, self.windowStack[len(self.windowStack)-1] ) self.infWindow = gtk.Window() self.infWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.infWindow.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) infButton= InfButton(self) self.infWindow.add(infButton) self.addToWindowStack( self.infWindow, self.windowStack[len(self.windowStack)-1] ) self.hideAllWindows() self.MAP_EVENT_ID = self.liveVideoWindow.connect_after("map-event", self._mapEventCb) for i in range (0, len(self.windowStack)): # self.windowStack[i].add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) # self.windowStack[i].connect("visibility-notify-event", self._visibleNotifyCb) self.windowStack[i].show_all() def _visibleNotifyCb( self, widget, event ): if (self.LAUNCHING): return temp_ACTIVE = True if (event.state == gtk.gdk.VISIBILITY_FULLY_OBSCURED): if (not self.FULLSCREEN): if (widget == self.ca): temp_ACTIVE = False else: if (self.ca.m.MODE == Constants.MODE_PHOTO): if (not self.LIVEMODE and widget == self.livePhotoWindow): temp_ACTIVE = False if ( self.LIVEMODE and widget == self.liveVideoWindow): temp_ACTIVE = False if (self.ca.m.MODE == Constants.MODE_VIDEO): if (not self.LIVEMODE and widget == self.playOggWindow): temp_ACTIVE = False if ( self.LIVEMODE and widget == self.liveVideoWindow): temp_ACTIVE = False if (temp_ACTIVE != self.ACTIVE): self.ACTIVE = temp_ACTIVE if (self.ACTIVE): self.ca.restartPipes() else: self.ca.stopPipes() def setUpWindowsSizes( self ): pipDim = self.getPipDim(False) eyeDim = self.getEyeDim(False) imgDim = self.getImgDim( False ) pgdDim = self.getPgdDim( False ) maxDim = self.getMaxDim( False ) prgDim = self.getPrgDim( False ) infDim = self.getInfDim( False ) self.livePhotoWindow.resize( imgDim[0], imgDim[1] ) self.pipBgdWindow.resize( pgdDim[0], pgdDim[1] ) self.liveVideoWindow.resize( imgDim[0], imgDim[1] ) self.playOggWindow.resize( imgDim[0], imgDim[1] ) self.recordWindow.resize( eyeDim[0], eyeDim[1] ) self.maxWindow.resize( maxDim[0], maxDim[1] ) self.progressWindow.resize( prgDim[0], prgDim[1] ) self.infWindow.resize( infDim[0], infDim[1] ) def _toolbarChangeCb( self, tbox, num ): if (num != 0) and (self.ca.m.RECORDING or self.ca.m.UPDATING): self.toolbox.set_current_toolbar(self.tbars[self.ca.m.MODE]) else: mode = [mode for mode, i in self.tbars.items() if i == num] if not mode: return if (mode[0] == Constants.MODE_PHOTO) and \ (self.ca.m.MODE != Constants.MODE_PHOTO): self.ca.m.doPhotoMode() elif(mode[0] == Constants.MODE_VIDEO) and \ (self.ca.m.MODE != Constants.MODE_VIDEO): self.ca.m.doVideoMode() elif(mode[0] == Constants.MODE_AUDIO) and \ (self.ca.m.MODE != Constants.MODE_AUDIO): self.ca.m.doAudioMode() def addToWindowStack( self, win, parent ): self.windowStack.append( win ) win.set_transient_for( parent ) win.set_type_hint( gtk.gdk.WINDOW_TYPE_HINT_DIALOG ) win.set_decorated( False ) win.set_focus_on_map( False ) win.set_property("accept-focus", False) win.props.destroy_with_parent = True def resetWidgetFadeTimer( self ): #only show the clutter when the mouse moves self.mx = -1 self.my = -1 self.hideWidgetsTimer = time.time() if (self.hiddenWidgets): self.showWidgets() self.hiddenWidgets = False #remove, then add self.doMouseListener( False ) if (self.HIDE_WIDGET_TIMEOUT_ID != 0): gobject.source_remove( self.HIDE_WIDGET_TIMEOUT_ID) self.HIDE_WIDGET_TIMEOUT_ID = gobject.timeout_add( 500, self._mouseMightaMovedCb ) def doMouseListener( self, listen ): if (listen): self.resetWidgetFadeTimer() else: if (self.HIDE_WIDGET_TIMEOUT_ID != None): if (self.HIDE_WIDGET_TIMEOUT_ID != 0): gobject.source_remove( self.HIDE_WIDGET_TIMEOUT_ID ) def hideWidgets( self ): self.moveWinOffscreen( self.maxWindow ) self.moveWinOffscreen( self.pipBgdWindow ) self.moveWinOffscreen( self.infWindow ) if (self.FULLSCREEN): self.moveWinOffscreen( self.recordWindow ) self.moveWinOffscreen( self.progressWindow ) self.moveWinOffscreen( self.scrubWindow ) if (self.ca.m.MODE == Constants.MODE_PHOTO): if (not self.LIVEMODE): self.moveWinOffscreen( self.liveVideoWindow ) elif (self.ca.m.MODE == Constants.MODE_VIDEO): if (not self.LIVEMODE): self.moveWinOffscreen( self.liveVideoWindow ) elif (self.ca.m.MODE == Constants.MODE_AUDIO): if (not self.LIVEMODE): self.moveWinOffscreen( self.liveVideoWindow ) self.LAST_MODE = -1 def _mouseMightaMovedCb( self ): x, y = self.ca.get_pointer() passedTime = 0 if (x != self.mx or y != self.my): self.hideWidgetsTimer = time.time() if (self.hiddenWidgets): self.showWidgets() self.hiddenWidgets = False else: passedTime = time.time() - self.hideWidgetsTimer if (self.ca.m.RECORDING): self.hideWidgetsTimer = time.time() passedTime = 0 if (passedTime >= 3): if (not self.hiddenWidgets): if (self.mouseInWidget(x,y)): self.hideWidgetsTimer = time.time() elif (self.RECD_INFO_ON): self.hideWidgetsTimer = time.time() elif (self.UPDATE_TIMER_ID != 0): self.hideWidgetsTimer = time.time() else: self.hideWidgets() self.hiddenWidgets = True self.mx = x self.my = y return True def mouseInWidget( self, mx, my ): if (self.ca.m.MODE != Constants.MODE_AUDIO): if (self.inWidget( mx, my, self.getLoc("max", self.FULLSCREEN), self.getDim("max", self.FULLSCREEN))): return True if (not self.LIVEMODE): if (self.inWidget( mx, my, self.getLoc("pgd", self.FULLSCREEN), self.getDim("pgd", self.FULLSCREEN))): return True if (self.inWidget( mx, my, self.getLoc("inb", self.FULLSCREEN), self.getDim("inb", self.FULLSCREEN))): return True if (self.inWidget( mx, my, self.getLoc("prg", self.FULLSCREEN), self.getDim("prg", self.FULLSCREEN))): return True if (self.inWidget( mx, my, self.getLoc("inf", self.FULLSCREEN), self.getDim("inf", self.FULLSCREEN))): return True if (self.LIVEMODE): if (self.inWidget( mx, my, self.getLoc("eye", self.FULLSCREEN), self.getDim("eye", self.FULLSCREEN))): return True return False def _mediaClickedForPlayback(self, widget, event): if (not self.LIVEMODE): if (self.shownRecd != None): if (self.ca.m.MODE != Constants.MODE_PHOTO): self.showThumbSelection( self.shownRecd ) def inWidget( self, mx, my, loc, dim ): if ( (mx > loc[0]) and (my > loc[1]) ): if ( (mx < loc[0]+dim[0]) and (my < loc[1]+dim[1]) ): return True def _nameTextfieldEditedCb(self, widget): if (self.shownRecd != None): if (self.nameTextfield.get_text() != self.shownRecd.title): self.shownRecd.setTitle( self.nameTextfield.get_text() ) def _tagsBufferEditedCb(self, widget): if (self.shownRecd != None): txt = self.tagsBuffer.get_text( self.tagsBuffer.get_start_iter(), self.tagsBuffer.get_end_iter() ) if (txt != self.shownRecd.tags): self.shownRecd.setTags( txt ) def _keyPressEventCb( self, widget, event): #todo: trac #4144 self.resetWidgetFadeTimer() #we listen here for CTRL+C events and game keys, and pass on events to gtk.Entry fields keyname = gtk.gdk.keyval_name(event.keyval) if (keyname == 'KP_Page_Up'): #O, up if (self.LIVEMODE): if (not self.ca.m.UPDATING): self.doShutter() else: if (self.COUNTINGDOWN): self.doShutter() else: if (self.ca.m.MODE == Constants.MODE_PHOTO): self.resumeLiveVideo() else: self.resumePlayLiveVideo() elif (keyname == 'KP_Page_Down'): #x, down if (not self.ca.m.UPDATING and not self.ca.m.RECORDING): self.ca.m.showLastThumb() elif (keyname == 'KP_Home'): #square, left if (not self.ca.m.UPDATING and not self.ca.m.RECORDING and not self.LIVEMODE): self.ca.m.showPrevThumb( self.shownRecd ) elif (keyname == 'KP_End'): #check, right if (not self.ca.m.UPDATING and not self.ca.m.RECORDING and not self.LIVEMODE): self.ca.m.showNextThumb( self.shownRecd ) elif (keyname == 'c' and event.state == gtk.gdk.CONTROL_MASK): if (self.shownRecd != None): self.copyToClipboard( self.shownRecd ) elif (keyname == 'Escape'): if (self.FULLSCREEN): self.FULLSCREEN = False if (self.RECD_INFO_ON): self.infoButtonClicked() else: self.updateVideoComponents() elif (keyname == 'i' and event.state == gtk.gdk.CONTROL_MASK): if (not self.LIVEMODE): self.infoButtonClicked() return False def copyToClipboard( self, recd ): if (recd.isClipboardCopyable( )): tmpImgPath = self.doClipboardCopyStart( recd ) gtk.Clipboard().set_with_data( [('text/uri-list', 0, 0)], self._clipboardGetFuncCb, self._clipboardClearFuncCb, tmpImgPath ) return True def doClipboardCopyStart( self, recd ): imgPath_s = recd.getMediaFilepath() if (imgPath_s == None): record.Record.log.error("doClipboardCopyStart: imgPath_s==None") return None tmpImgPath = recd.getMediaFilepath() tmpImgPath = utils.getUniqueFilepath(tmpImgPath, 0) shutil.copyfile( imgPath_s, tmpImgPath ) return tmpImgPath def doClipboardCopyCopy( self, tmpImgPath, selection_data ): tmpImgUri = "file://" + tmpImgPath selection_data.set( "text/uri-list", 8, tmpImgUri ) def doClipboardCopyFinish( self, tmpImgPath ): if (tmpImgPath != None): if (os.path.exists(tmpImgPath)): os.remove( tmpImgPath ) tmpImgPath = None def _clipboardGetFuncCb( self, clipboard, selection_data, info, data): self.doClipboardCopyCopy( data, selection_data ) def _clipboardClearFuncCb( self, clipboard, data): self.doClipboardCopyFinish( data ) def showPhoto( self, recd ): pixbuf = self.getPhotoPixbuf( recd ) if (pixbuf != None): #self.shownRecd = recd img = hippo.cairo_surface_from_gdk_pixbuf(pixbuf) self.livePhotoCanvas.setImage( img ) self.ca.glive.thumb_play() self.LIVEMODE = False self.updateVideoComponents() self.showRecdMeta(recd) def getPhotoPixbuf( self, recd ): pixbuf = None downloading = self.ca.requestMeshDownload(recd) self.MESHING = downloading if (not downloading): self.progressWindow.updateProgress(0, "") imgPath = recd.getMediaFilepath() if (not imgPath == None): if ( os.path.isfile(imgPath) ): pixbuf = gtk.gdk.pixbuf_new_from_file(imgPath) if (pixbuf == None): #maybe it is not downloaded from the mesh yet... #but we can show the low res thumb in the interim pixbuf = recd.getThumbPixbuf() return pixbuf def showLiveVideoTags( self ): self.shownRecd = None self.livePhotoCanvas.setImage( None ) self.nameTextfield.set_text("") self.tagsBuffer.set_text("") self.scrubWindow.removeCallbacks() self.scrubWindow.reset() self.MESHING = False self.progressWindow.updateProgress( 0, "" ) self.resetWidgetFadeTimer( ) def updateButtonSensitivities( self ): switchStuff = ((not self.ca.m.UPDATING) and (not self.ca.m.RECORDING)) if self.photoToolbar: self.photoToolbar.set_sensitive( switchStuff ) if self.videoToolbar: self.videoToolbar.set_sensitive( switchStuff ) self.audioToolbar.set_sensitive( switchStuff ) if (not self.COUNTINGDOWN): if (self.ca.m.UPDATING): self.ca.ui.setWaitCursor( self.ca.window ) for i in range (0, len(self.windowStack)): self.ca.ui.setWaitCursor( self.windowStack[i].window ) else: self.ca.ui.setDefaultCursor( self.ca.window ) for i in range (0, len(self.windowStack)): self.ca.ui.setDefaultCursor( self.windowStack[i].window ) #display disc is full messages self.ca.m.updateXoFullStatus() self.recordWindow.displayDiscFullText(self.ca.m.FULL) if (self.ca.m.FULL): self.recordWindow.shutterButton.set_sensitive( False, True) fullMessage = Constants.istrYourDiskIsFull % {"1":Constants.istrJournal} self.progressWindow.updateProgress( 1, fullMessage, "gray" ) else: self.recordWindow.shutterButton.set_sensitive( not self.ca.m.UPDATING, False ) if (self.ca.m.RECORDING): self.recordWindow.shutterButton.doRecordButton() else: self.recordWindow.shutterButton.doNormalButton() kids = self.thumbTray.get_children() for i in range (0, len(kids)): if (self.ca.m.UPDATING or self.ca.m.RECORDING): if (kids[i].getButtClickedId() != 0): kids[i].disconnect( kids[i].getButtClickedId() ) kids[i].setButtClickedId(0) else: if (kids[i].getButtClickedId() == 0): BUTT_CLICKED_ID = kids[i].connect( "clicked", self._thumbClicked, kids[i].recd ) kids[i].setButtClickedId(BUTT_CLICKED_ID) def hideAllWindows( self ): for i in range (0, len(self.windowStack)): self.moveWinOffscreen( self.windowStack[i] ) def _liveButtonReleaseCb(self, widget, event): self.ca.gplay.stop() self.ca.glive.play() self.resumeLiveVideo() def resumeLiveVideo( self ): self.livePhotoCanvas.setImage( None ) bottomKid = self.bottomCenter.get_child() if (bottomKid != None): self.bottomCenter.remove( bottomKid ) self.RECD_INFO_ON = False if (not self.LIVEMODE): self.ca.m.setUpdating(True) self.ca.gplay.stop() self.showLiveVideoTags() self.LIVEMODE = True self.updateVideoComponents() self.ca.m.setUpdating(False) def _playLiveButtonReleaseCb(self, widget, event): self.resumePlayLiveVideo() def resumePlayLiveVideo( self ): self.ca.gplay.stop() self.RECD_INFO_ON = False #if you are big on the screen, don't go changing anything, ok? if (self.LIVEMODE): return self.showLiveVideoTags() self.LIVEMODE = True self.startLiveVideo( False ) self.updateVideoComponents() def recordVideo( self ): self.ca.glive.startRecordingVideo(self.videoToolbar.getQuality()) self.beginRecordingTimer( ) def recordAudio( self ): self.ca.glive.startRecordingAudio( ) self.beginRecordingTimer( ) def beginRecordingTimer( self ): self.recTime = time.time() self.UPDATE_DURATION_ID = gobject.timeout_add( 500, self._updateDurationCb ) def _updateDurationCb( self ): passedTime = time.time() - self.recTime duration = 10.0 if (self.ca.m.MODE == Constants.MODE_VIDEO): duration = self.videoToolbar.getDuration()+0.0 elif (self.ca.m.MODE == Constants.MODE_AUDIO): duration = self.audioToolbar.getDuration()+0.0 if (passedTime >= duration ): self.completeCountdown() self.progressWindow.updateProgress( 1, Constants.istrFinishedRecording ) if (self.ca.m.RECORDING): gobject.idle_add( self.doShutter ) return False else: secsRemaining = duration - passedTime if (secsRemaining >= 60): mins = int( secsRemaining/60 ) secs = int( secsRemaining%60 ) timeRemainStr = istrMinutes(mins) + ', ' + istrSeconds(secs) else: timeRemainStr = istrSeconds(secsRemaining) self.progressWindow.updateProgress( passedTime/duration, Constants.istrRemaining + " " + timeRemainStr ) return True def completeCountdown( self ): if (self.UPDATE_DURATION_ID != 0): gobject.source_remove( self.UPDATE_DURATION_ID ) self.UPDATE_DURATION_ID = 0 def updateModeChange(self): #this is called when a menubar button is clicked self.LIVEMODE = True self.FULLSCREEN = False self.RECD_INFO_ON = False self.MESHING = False self.progressWindow.updateProgress(0, "") #set up the x & xv x-ition (if need be) self.ca.gplay.stop() self.startLiveVideo( True ) bottomKid = self.bottomCenter.get_child() if (bottomKid != None): self.bottomCenter.remove( bottomKid ) self.doMouseListener( True ) self.showLiveVideoTags() self.LAST_MODE = -1 #force an update self.updateVideoComponents() self.resetWidgetFadeTimer() def startLiveVideo(self, force): #We need to know which window and which pipe here #if returning from another activity, active won't be false and needs to be to get started if (self.ca.glive.window == self.liveVideoWindow and self.ca.props.active and not force): return self.liveVideoWindow.set_glive(self.ca.glive) self.ca.glive.play() def doFullscreen( self ): self.FULLSCREEN = not self.FULLSCREEN self.updateVideoComponents() def moveWinOffscreen( self, win ): #we move offscreen to resize or else we get flashes on screen, and setting hide() doesn't allow resize & moves offW = (gtk.gdk.screen_width() + 100) offH = (gtk.gdk.screen_height() + 100) self.smartMove(win, offW, offH) def setImgLocDim( self, win ): imgDim = self.getImgDim( self.FULLSCREEN ) self.smartResize( win, imgDim[0], imgDim[1] ) imgLoc = self.getImgLoc( self.FULLSCREEN ) self.smartMove( win, imgLoc[0], imgLoc[1] ) def setPrgLocDim( self, win ): prgDim = self.getPrgDim( self.FULLSCREEN ) self.smartResize( win, prgDim[0], prgDim[1] ) prgLoc = self.getPrgLoc( self.FULLSCREEN ) self.smartMove( win, prgLoc[0], prgLoc[1] ) def setTmrLocDim( self, win ): tmrDim = self.getTmrDim( self.FULLSCREEN ) self.smartResize( win, tmrDim[0], tmrDim[1] ) tmrLoc = self.getTmrLoc( self.FULLSCREEN ) self.smartMove( win, tmrLoc[0], tmrLoc[1] ) def setScrLocDim( self, win ): scrDim = self.getScrDim( self.FULLSCREEN ) self.smartResize( win, scrDim[0], scrDim[1] ) scrLoc = self.getScrLoc( self.FULLSCREEN ) self.smartMove( win, scrLoc[0], scrLoc[1] ) def setInfLocDim( self, win ): infDim = self.getInfDim( self.FULLSCREEN ) self.smartResize( win, infDim[0], infDim[1] ) infLoc = self.getInfLoc( self.FULLSCREEN ) self.smartMove( win, infLoc[0], infLoc[1] ) def getScrDim( self, full ): if (full): return [gtk.gdk.screen_width()-(self.inset+self.pgdw+self.inset+self.inset), self.controlBarHt] else: return [self.vw, self.controlBarHt] def getScrLoc( self, full ): if (full): return [(self.inset+self.pgdw+self.inset), gtk.gdk.screen_height()-(self.inset+self.controlBarHt)] else: return [self.centerBoxPos[0], self.centerBoxPos[1]+self.vh] def getImgDim( self, full ): if (full): return [gtk.gdk.screen_width(), gtk.gdk.screen_height()] else: return [self.vw, self.vh] def getImgLoc( self, full ): if (full): return[0, 0] else: return[self.centerBoxPos[0], self.centerBoxPos[1]] def getTmrLoc( self, full ): if (not full): return [self.centerBoxPos[0], self.centerBoxPos[1]+self.vh] else: return [self.inset, gtk.gdk.screen_height()-(self.inset+self.controlBarHt)] def getTmrDim( self, full ): if (not full): return [self.vw, self.controlBarHt] else: return [gtk.gdk.screen_width()-(self.inset+self.inset), self.controlBarHt] def setPipLocDim( self, win ): self.smartResize( win, self.pipw, self.piph ) loc = self.getPipLoc( self.FULLSCREEN ) self.smartMove( win, loc[0], loc[1] ) def getPipLoc( self, full ): if (full): return [self.inset+self.__class__.dim_PIP_BORDER, gtk.gdk.screen_height()-(self.inset+self.piph+self.__class__.dim_PIP_BORDER)] else: return [self.centerBoxPos[0]+self.inset+self.__class__.dim_PIP_BORDER, (self.centerBoxPos[1]+self.vh)-(self.inset+self.piph+self.__class__.dim_PIP_BORDER)] def setPipBgdLocDim( self, win ): pgdLoc = self.getPgdLoc( self.FULLSCREEN ) self.smartMove( win, pgdLoc[0], pgdLoc[1] ) def getPgdLoc( self, full ): if (full): return [self.inset, gtk.gdk.screen_height()-(self.inset+self.pgdh)] else: return [self.centerBoxPos[0]+self.inset, (self.centerBoxPos[1]+self.vh)-(self.inset+self.pgdh)] def setMaxLocDim( self, win ): maxLoc = self.getMaxLoc( self.FULLSCREEN ) self.smartMove( win, maxLoc[0], maxLoc[1] ) def getMaxLoc( self, full ): if (full): return [gtk.gdk.screen_width()-(self.maxw+self.inset), self.inset] else: return [(self.centerBoxPos[0]+self.vw)-(self.inset+self.maxw), self.centerBoxPos[1]+self.inset] def getInfLoc( self, full ): if (full): return [gtk.gdk.screen_width()+100,gtk.gdk.screen_height()+100 ] else: dim = self.getInfDim(self.FULLSCREEN) return [(self.centerBoxPos[0]+self.vw)-dim[0], (self.centerBoxPos[1]+self.vh)-dim[1]] def setEyeLocDim( self, win ): dim = self.getEyeDim( self.FULLSCREEN ) self.smartResize( win, dim[0], dim[1] ) loc = self.getEyeLoc( self.FULLSCREEN ) self.smartMove( win, loc[0], loc[1] ) def getEyeLoc( self, full ): if (not full): return [self.centerBoxPos[0], self.centerBoxPos[1]+self.vh] else: return [self.inset, gtk.gdk.screen_height()-(self.inset+self.controlBarHt)] def getEyeDim( self, full ): if (not full): if (self.ca.m.MODE == Constants.MODE_PHOTO): return [self.vw, self.controlBarHt] else: return [self.recordButtWd, self.controlBarHt] else: if (self.ca.m.MODE == Constants.MODE_PHOTO): return [gtk.gdk.screen_width()-(self.inset*2), self.controlBarHt] else: return [self.recordButtWd, self.controlBarHt] def getInbLoc( self, full ): return [(self.centerBoxPos[0]+self.vw)-(self.inset+self.letterBoxVW), self.centerBoxPos[1]+self.inset] def setInbLocDim( self, win ): dim = self.getInbDim( self.FULLSCREEN ) self.smartResize( win, dim[0], dim[1] ) loc = self.getInbLoc(self.FULLSCREEN) self.smartMove( win, loc[0], loc[1] ) def smartResize( self, win, w, h ): winSize = win.get_size() if ( (winSize[0] != w) or (winSize[1] != h) ): win.resize( w, h ) return True else: return False def smartMove( self, win, x, y ): winLoc = win.get_position() if ( (winLoc[0] != x) or (winLoc[1] != y) ): win.move( x, y ) return True else: return False def getDim( self, pos, full ): if (pos == "pip"): return self.getPipDim( full ) elif(pos == "pgd"): return self.getPgdDim( full ) elif(pos == "max"): return self.getMaxDim( full ) elif(pos == "img"): return self.getImgDim( full ) elif(pos == "eye"): return self.getEyeDim( full ) elif(pos == "inb"): return self.getInbDim( full ) elif(pos == "prg"): return self.getPrgDim( full ) elif(pos == "inf"): return self.getInfDim( full ) def getMaxDim( self, full ): return [self.maxw, self.maxh] def getInfDim( self, full ): return [75, 75] def getPipDim( self, full ): return [self.pipw, self.piph] def getPgdDim( self, full ): return [self.pgdw, self.pgdh] def getInbDim( self, full ): return [self.letterBoxVW, self.letterBoxVH] def getPrgDim( self, full ): if (not full): return [self.vw-self.recordButtWd, self.controlBarHt] else: return [gtk.gdk.screen_width()-(self.inset+self.inset+self.recordButtWd), self.controlBarHt] def getPrgLoc( self, full ): if (not full): return [self.centerBoxPos[0]+self.recordButtWd, self.centerBoxPos[1]+self.vh] else: return [self.inset+self.recordButtWd, gtk.gdk.screen_height()-(self.inset+self.controlBarHt)] def getLoc( self, pos, full ): if (pos == "pip"): return self.getPipLoc( full ) elif(pos == "pgd"): return self.getPgdLoc( full ) elif(pos == "max"): return self.getMaxLoc( full ) elif(pos == "img"): return self.getImgLoc( full ) elif(pos == "eye"): return self.getEyeLoc( full ) elif(pos == "inb"): return self.getInbLoc( full ) elif(pos == "prg"): return self.getPrgLoc( full ) elif(pos == "inf"): return self.getInfLoc( full ) def _shutterClickCb( self, arg ): self.doShutter() def doShutter( self ): if (self.UPDATE_TIMER_ID == 0): if (not self.ca.m.RECORDING): self.ca.m.updateXoFullStatus() if (self.ca.m.FULL): self.updateButtonSensitivities() return #there is no update timer running, so we need to find out if there is a timer needed timerTime = 0 if (self.ca.m.MODE == Constants.MODE_PHOTO): timerTime = self.photoToolbar.getTimer() elif (self.ca.m.MODE == Constants.MODE_VIDEO): timerTime = self.videoToolbar.getTimer() elif (self.ca.m.MODE == Constants.MODE_AUDIO): timerTime = self.audioToolbar.getTimer() if (timerTime > 0): self.timerStartTime = time.time() self.UPDATE_TIMER_ID = gobject.timeout_add( 500, self._updateTimerCb ) self.COUNTINGDOWN = True self.ca.m.setUpdating(True) else: self.clickShutter() else: #or, if there is no countdown, it might be because we are recording self.clickShutter() else: #we're timing down something, but interrupted by user click or the timer completing self.completeTimer() gobject.idle_add( self.clickShutter ) def completeTimer( self ): self.COUNTINGDOWN = False self.ca.m.setUpdating(False) self.recordWindow.updateCountdown(-1) self.progressWindow.updateProgress( 1, "" ) gobject.source_remove( self.UPDATE_TIMER_ID ) self.UPDATE_TIMER_ID = 0 def _updateTimerCb( self ): nowTime = time.time() passedTime = nowTime - self.timerStartTime timerTime = 0 if (self.ca.m.MODE == Constants.MODE_PHOTO): timerTime = self.photoToolbar.getTimer() elif (self.ca.m.MODE == Constants.MODE_VIDEO): timerTime = self.videoToolbar.getTimer() elif (self.ca.m.MODE == Constants.MODE_AUDIO): timerTime = self.audioToolbar.getTimer() if (passedTime >= timerTime): self.COUNTINGDOWN = False self.ca.m.setUpdating(False) self.doShutter() return False else: secsRemaining = timerTime-passedTime timeRemainStr = istrSeconds(secsRemaining) self.progressWindow.updateProgress( passedTime/timerTime, Constants.istrRemaining + " " + timeRemainStr) self.recordWindow.updateCountdown( int(secsRemaining) ) return True def clickShutter( self ): if self.ca.m.RECORDING: self.ca.m.doShutter() aplay.play(Constants.soundClick) else: aplay.play(Constants.soundClick, self.ca.m.doShutter) def updateVideoComponents( self ): logger.debug('updateVideoComponents: MODE=(%s,%s) FULLSCREEN=(%s,%s)' \ ' LIVE=(%s,%s) RECD_INFO=(%s,%s) TRANSCODING=(%s,%s)' \ ' MESHING=(%s,%s) windowStack=%s' \ % (self.LAST_MODE, self.ca.m.MODE, self.LAST_FULLSCREEN, self.FULLSCREEN, self.LAST_LIVE, self.LIVEMODE, self.LAST_RECD_INFO, self.RECD_INFO_ON, self.LAST_TRANSCODING, self.TRANSCODING, self.LAST_MESHING, self.MESHING, len(self.windowStack))) if ( (self.LAST_MODE == self.ca.m.MODE) and (self.LAST_FULLSCREEN == self.FULLSCREEN) and (self.LAST_LIVE == self.LIVEMODE) and (self.LAST_RECD_INFO == self.RECD_INFO_ON) and (self.LAST_TRANSCODING == self.TRANSCODING) and (self.LAST_MESHING == self.MESHING) ): return #something's changing so start counting anew self.resetWidgetFadeTimer() pos = [] if (self.RECD_INFO_ON and not self.TRANSCODING): if (self.ca.m.MODE == Constants.MODE_PHOTO): pos.append({"position":"pgd", "window":self.pipBgdWindow} ) pos.append({"position":"pip", "window":self.liveVideoWindow} ) pos.append({"position":"inb", "window":self.livePhotoWindow} ) pos.append({"position":"inf", "window":self.infWindow} ) elif (self.ca.m.MODE == Constants.MODE_VIDEO): pos.append({"position":"pgd", "window":self.pipBgdWindow} ) pos.append({"position":"pip", "window":self.liveVideoWindow} ) pos.append({"position":"inb", "window":self.playOggWindow} ) pos.append({"position":"inf", "window":self.infWindow} ) elif (self.ca.m.MODE == Constants.MODE_AUDIO): pos.append({"position":"pgd", "window":self.pipBgdWindow} ) pos.append({"position":"pip", "window":self.liveVideoWindow} ) pos.append({"position":"inb", "window":self.livePhotoWindow} ) pos.append({"position":"inf", "window":self.infWindow} ) elif (not self.RECD_INFO_ON and not self.TRANSCODING): if (self.ca.m.MODE == Constants.MODE_PHOTO): if (self.LIVEMODE): pos.append({"position":"img", "window":self.liveVideoWindow} ) pos.append({"position":"max", "window":self.maxWindow} ) pos.append({"position":"eye", "window":self.recordWindow} ) else: pos.append({"position":"img", "window":self.livePhotoWindow} ) pos.append({"position":"pgd", "window":self.pipBgdWindow} ) pos.append({"position":"pip", "window":self.liveVideoWindow} ) if (not self.MESHING): pos.append({"position":"max", "window":self.maxWindow} ) pos.append({"position":"inf", "window":self.infWindow} ) else: pos.append({"position":"tmr", "window":self.progressWindow} ) elif (self.ca.m.MODE == Constants.MODE_VIDEO): if (self.LIVEMODE): pos.append({"position":"img", "window":self.liveVideoWindow} ) pos.append({"position":"max", "window":self.maxWindow} ) pos.append({"position":"eye", "window":self.recordWindow} ) pos.append({"position":"prg", "window":self.progressWindow} ) else: pos.append({"position":"img", "window":self.playOggWindow} ) pos.append({"position":"pgd", "window":self.pipBgdWindow} ) pos.append({"position":"pip", "window":self.liveVideoWindow} ) if (not self.MESHING): pos.append({"position":"max", "window":self.maxWindow} ) pos.append({"position":"scr", "window":self.scrubWindow} ) pos.append({"position":"inf", "window":self.infWindow} ) else: pos.append({"position":"tmr", "window":self.progressWindow} ) elif (self.ca.m.MODE == Constants.MODE_AUDIO): if (self.LIVEMODE): pos.append({"position":"img", "window":self.liveVideoWindow} ) pos.append({"position":"eye", "window":self.recordWindow} ) pos.append({"position":"prg", "window":self.progressWindow} ) else: pos.append({"position":"img", "window":self.livePhotoWindow} ) pos.append({"position":"pgd", "window":self.pipBgdWindow} ) pos.append({"position":"pip", "window":self.liveVideoWindow} ) if (not self.MESHING): pos.append({"position":"scr", "window":self.scrubWindow} ) pos.append({"position":"inf", "window":self.infWindow} ) else: pos.append({"position":"tmr", "window":self.progressWindow} ) elif (self.TRANSCODING): pos.append({"position":"tmr", "window":self.progressWindow} ) for i in range (0, len(self.windowStack)): self.windowStack[i].hide_all() self.hideAllWindows() self.updatePos( pos ) for i in range (0, len(self.windowStack)): self.windowStack[i].show_all() self.LAST_MODE = self.ca.m.MODE self.LAST_FULLSCREEN = self.FULLSCREEN self.LAST_LIVE = self.LIVEMODE self.LAST_RECD_INFO = self.RECD_INFO_ON self.LAST_TRANSCODING = self.TRANSCODING self.LAST_MESHING = self.MESHING def debugWindows( self ): for i in range (0, len(self.windowStack)): print self.windowStack[i], self.windowStack[i].get_size(), self.windowStack[i].get_position() def showWidgets( self ): pos = [] if (self.ca.m.MODE == Constants.MODE_PHOTO): if (not self.LIVEMODE): pos.append({"position":"pgd", "window":self.pipBgdWindow} ) pos.append({"position":"pip", "window":self.liveVideoWindow} ) if (not self.MESHING): pos.append({"position":"max", "window":self.maxWindow} ) pos.append({"position":"inf", "window":self.infWindow} ) else: pos.append({"position":"max", "window":self.maxWindow} ) pos.append({"position":"eye", "window":self.recordWindow} ) elif (self.ca.m.MODE == Constants.MODE_VIDEO): if (not self.LIVEMODE): pos.append({"position":"pgd", "window":self.pipBgdWindow} ) pos.append({"position":"pip", "window":self.liveVideoWindow} ) if (not self.MESHING): pos.append({"position":"max", "window":self.maxWindow} ) pos.append({"position":"scr", "window":self.scrubWindow} ) pos.append({"position":"inf", "window":self.infWindow} ) else: pos.append({"position":"max", "window":self.maxWindow} ) pos.append({"position":"eye", "window":self.recordWindow} ) pos.append({"position":"prg", "window":self.progressWindow} ) elif (self.ca.m.MODE == Constants.MODE_AUDIO): if (not self.LIVEMODE): pos.append({"position":"pgd", "window":self.pipBgdWindow} ) pos.append({"position":"pip", "window":self.liveVideoWindow} ) if (not self.MESHING): pos.append({"position":"scr", "window":self.scrubWindow} ) pos.append({"position":"inf", "window":self.infWindow} ) else: pos.append({"position":"eye", "window":self.recordWindow} ) pos.append({"position":"prg", "window":self.progressWindow} ) self.updatePos( pos ) def updatePos( self, pos ): #now move those pieces where they need to be... for i in range (0, len(self.windowStack)): for j in range (0, len(pos)): if (self.windowStack[i] == pos[j]["window"]): if (pos[j]["position"] == "img"): self.setImgLocDim( pos[j]["window"] ) elif (pos[j]["position"] == "max"): self.setMaxLocDim( pos[j]["window"] ) elif (pos[j]["position"] == "pip"): self.setPipLocDim( pos[j]["window"] ) elif (pos[j]["position"] == "pgd"): self.setPipBgdLocDim( pos[j]["window"] ) elif (pos[j]["position"] == "eye"): self.setEyeLocDim( pos[j]["window"] ) elif (pos[j]["position"] == "inb"): self.setInbLocDim( pos[j]["window"]) elif (pos[j]["position"] == "prg"): self.setPrgLocDim( pos[j]["window"]) elif (pos[j]["position"] == "tmr"): self.setTmrLocDim( pos[j]["window"]) elif (pos[j]["position"] == "scr"): self.setScrLocDim( pos[j]["window"]) elif (pos[j]["position"] == "inf"): self.setInfLocDim( pos[j]["window"]) def removeThumb( self, recd ): kids = self.thumbTray.get_children() for i in range (0, len(kids)): if (kids[i].recd == recd): self.thumbTray.remove_item(kids[i]) kids[i].cleanUp() kids[i].disconnect( kids[i].getButtClickedId() ) kids[i].setButtClickedId(0) def addThumb( self, recd, forceScroll ): butt = RecdButton( self, recd ) BUTT_CLICKED_ID = butt.connect( "clicked", self._thumbClicked, recd ) butt.setButtClickedId(BUTT_CLICKED_ID) self.thumbTray.add_item( butt, len(self.thumbTray.get_children()) ) butt.show() if (forceScroll): self.thumbTray.scroll_to_end() def removeThumbs( self ): kids = self.thumbTray.get_children() for i in range (0, len(kids)): self.thumbTray.remove_item(kids[i]) kids[i].cleanUp() if (kids[i].getButtClickedId() != 0): kids[i].disconnect( kids[i].getButtClickedId() ) def _thumbClicked( self, button, recd ): self.showThumbSelection( recd ) def infoButtonClicked( self ): self.RECD_INFO_ON = not self.RECD_INFO_ON centerKid = self.centerBox.get_child() if (centerKid != None): self.centerBox.remove( centerKid ) bottomKid = self.bottomCenter.get_child() if (bottomKid != None): self.bottomCenter.remove( bottomKid ) if (not self.RECD_INFO_ON): if (self.ca.m.MODE == Constants.MODE_PHOTO): self.bottomCenter.add( self.namePanel ) self.bottomCenter.show_all( ) else: self.centerBox.add( self.infoBox ) self.centerBox.show_all( ) self.bottomCenter.add( self.namePanel ) self.bottomCenter.show_all( ) self.updateVideoComponents( ) def showMeshRecd( self, recd ): record.Record.log.debug('showMeshRecd: heres the downloaded recd to display...') #if this thumbnail is being shown, add the option to copy it now kids = self.thumbTray.get_children() for i in range (0, len(kids)): if (kids[i].recd == recd): kids[i].addCopyMenuItem() if (recd == self.shownRecd): record.Record.log.debug('showMeshRecd: and since were still looking at same recd, here it is!') self.showThumbSelection( recd ) def updateMeshProgress( self, progressMade, recd ): self.resetWidgetFadeTimer() if (self.shownRecd != recd): if (self.shownRecd == None): type = Constants.mediaTypes[recd.type][Constants.keyIstr] if (progressMade): msg = Constants.istrDownloadingFrom% {"1":type, "2":recd.meshDownloadingFromNick} self.progressWindow.updateProgress(recd.meshDownlodingPercent, msg) else: type = Constants.mediaTypes[recd.type][Constants.keyIstr] if (progressMade): msg = Constants.istrDownloadingFrom% {"1":type, "2":recd.meshDownloadingFromNick} self.progressWindow.updateProgress(recd.meshDownlodingPercent, msg) else: type = Constants.mediaTypes[recd.type][Constants.keyIstr] msg = Constants.istrCannotDownload % {"1":type} self.progressWindow.updateProgress(0, msg) def showThumbSelection( self, recd ): lastRecd = self.shownRecd self.shownRecd = recd #do we need to know the type, since we're showing based on the mode of the app? if (recd.type == Constants.TYPE_PHOTO): self.showPhoto( recd ) elif (recd.type == Constants.TYPE_VIDEO): self.showVideo( recd ) elif (recd.type == Constants.TYPE_AUDIO): self.showAudio( recd ) if (self.shownRecd != lastRecd): self.photoXoPanel.updateXoColors(self.shownRecd.colorStroke.hex, self.shownRecd.colorFill.hex) bottomKid = self.bottomCenter.get_child() if (bottomKid != None): self.bottomCenter.remove( bottomKid ) if (recd.type == Constants.TYPE_PHOTO): self.bottomCenter.add( self.namePanel ) elif (recd.type == Constants.TYPE_VIDEO or recd.type == Constants.TYPE_AUDIO): if (self.RECD_INFO_ON): self.bottomCenter.add( self.namePanel ) self.bottomCenter.show_all() self.resetWidgetFadeTimer() def showAudio( self, recd ): self.ca.glive.thumb_play() self.LIVEMODE = False #if (recd != self.shownRecd): pixbuf = recd.getAudioImagePixbuf() img = hippo.cairo_surface_from_gdk_pixbuf(pixbuf) self.livePhotoCanvas.setImage( img ) #self.shownRecd = recd self.showRecdMeta(recd) downloading = self.ca.requestMeshDownload(recd) self.MESHING = downloading record.Record.log.debug("showAudio: downloading->" + str(downloading)) if (not downloading): self.progressWindow.updateProgress(0, "") mediaFilepath = recd.getMediaFilepath( ) record.Record.log.debug("showAudio: mediaFilepath->" + str(mediaFilepath)) if (mediaFilepath != None): videoUrl = "file://" + str( mediaFilepath ) self.ca.gplay.setLocation(videoUrl) self.scrubWindow.doPlay() self.updateVideoComponents() def showVideo( self, recd ): logger.debug('showVideo') downloading = self.ca.requestMeshDownload(recd) if (not downloading): self.progressWindow.updateProgress(0, "") self.MESHING = downloading self.LIVEMODE = False #self.shownRecd = recd self.updateVideoComponents() gobject.idle_add( self.showVideo2, recd, downloading ) def showVideo2( self, recd, downloading ): self.showRecdMeta(recd) ableToShowVideo = False if (not downloading): mediaFilepath = recd.getMediaFilepath() if (mediaFilepath != None): self.ca.glive.thumb_play(use_fallback=True) logger.debug('showVideo2 file=%s' % mediaFilepath) videoUrl = "file://" + str( mediaFilepath ) self.ca.gplay.setLocation(videoUrl) self.scrubWindow.doPlay() ableToShowVideo = True if (not ableToShowVideo): self.ca.glive.thumb_play(use_fallback=True) # FIXME is this correct? thumbFilepath = recd.getThumbFilepath( ) logger.debug('showVideo3 file=%s' % thumbFilepath) thumbUrl = "file://" + str( thumbFilepath ) self.ca.gplay.setLocation(thumbUrl) def deleteThumbSelection( self, recd ): self.ca.m.deleteRecorded( recd ) self.ca.glive.play() self.removeThumb( recd ) self.removeIfSelectedRecorded( recd ) def removeIfSelectedRecorded( self, recd ): if (recd == self.shownRecd): if (recd.type == Constants.TYPE_PHOTO): self.livePhotoCanvas.setImage( None ) elif (recd.type == Constants.TYPE_VIDEO): self.ca.gplay.stop() self.startLiveVideo( False ) elif (recd.type == Constants.TYPE_AUDIO): self.livePhotoCanvas.setImage( None ) self.startLiveAudio() self.RECD_INFO_ON = False self.LIVEMODE = True self.updateVideoComponents() self.showLiveVideoTags() def startLiveAudio( self ): self.ca.m.setUpdating(True) self.ca.gplay.stop() self.liveVideoWindow.set_glive(self.ca.glive) self.showLiveVideoTags() self.LIVEMODE = True self.updateVideoComponents() self.ca.m.setUpdating(False) def showPostProcessGfx( self, show ): #not self.FULLSCREEN centerKid = self.centerBox.get_child() if (centerKid != None): self.centerBox.remove( centerKid ) if ( show ): self.centerBox.add( self.backgdCanvasBox ) self.centerBox.show_all() else: self.backgdCanvas.setImage( None ) def setPostProcessPixBuf( self, pixbuf ): if (pixbuf.get_width()>self.__class__.dim_THUMB_WIDTH): pixbuf = pixbuf.scale_simple(self.__class__.dim_THUMB_WIDTH, self.__class__.dim_THUMB_HEIGHT, gtk.gdk.INTERP_NEAREST) pixbuf = utils.grayScalePixBuf(pixbuf, True) img = hippo.cairo_surface_from_gdk_pixbuf(pixbuf) self.backgdCanvas.setImage(img) def showRecdMeta( self, recd ): self.photographerNameLabel.set_label( recd.recorderName ) self.nameTextfield.set_text( recd.title ) self.nameTextfield.set_sensitive( True ) self.tagsBuffer.set_text( recd.tags ) self.dateDateLabel.set_label( utils.getDateString(recd.time) ) self.photographerPanel.show() self.namePanel.show() self.datePanel.show() self.tagsPanel.show() self.tagsField.set_sensitive(True) def setWaitCursor( self, win ): win.set_cursor( gtk.gdk.Cursor(gtk.gdk.WATCH) ) def setDefaultCursor( self, win ): win.set_cursor( None ) class PhotoCanvas(P5): def __init__(self): P5.__init__(self) self.img = None self.drawImg = None self.SCALING_IMG_ID = 0 self.cacheWid = -1 self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) def draw(self, ctx, w, h): self.background( ctx, Constants.colorBlack, w, h ) if (self.img != None): if (w == self.img.get_width()): self.cacheWid == w self.drawImg = self.img #only scale images when you need to, otherwise you're wasting cycles, fool! if (self.cacheWid != w): if (self.SCALING_IMG_ID == 0): self.drawImg = None self.SCALING_IMG_ID = gobject.idle_add( self.resizeImage, w, h ) if (self.drawImg != None): #center the image based on the image size, and w & h ctx.set_source_surface(self.drawImg, (w/2)-(self.drawImg.get_width()/2), (h/2)-(self.drawImg.get_height()/2)) ctx.paint() self.cacheWid = w def setImage(self, img): self.cacheWid = -1 self.img = img self.drawImg = None self.queue_draw() def resizeImage(self, w, h): self.SCALING_IMG_ID = 0 if (self.img == None): return #use image size in case 640 no more scaleImg = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h) sCtx = cairo.Context(scaleImg) sScl = (w+0.0)/(self.img.get_width()+0.0) sCtx.scale( sScl, sScl ) sCtx.set_source_surface( self.img, 0, 0 ) sCtx.paint() self.drawImg = scaleImg self.cacheWid = w self.queue_draw() class xoPanel(P5): def __init__(self): P5.__init__(self) self.xoGuy = None self.lastStroke = None self.lastFill = None def updateXoColors( self, strokeHex, fillHex ): if (self.lastStroke != None): if ((self.lastStroke == strokeHex) and (self.lastFill == fillHex)): return lastStroke = strokeHex lastFill = fillHex self.xoGuy = utils.loadSvg(Constants.xoGuySvgData, strokeHex, fillHex) self.queue_draw() def draw(self, ctx, w, h): #todo: 2x buffer self.background( ctx, Constants.colorButton, w, h ) if (self.xoGuy != None): #todo: scale mr xo to fit in his box ctx.scale( .6, .6 ) self.xoGuy.render_cairo( ctx ) class ScrubberWindow(gtk.Window): def __init__(self, ui): gtk.Window.__init__(self) self.ui = ui self.UPDATE_INTERVAL = 500 self.UPDATE_SCALE_ID = 0 self.CHANGED_ID = 0 self.was_playing = False self.p_position = gst.CLOCK_TIME_NONE self.p_duration = gst.CLOCK_TIME_NONE self.hbox = gtk.HBox() self.hbox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.hbox.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) self.add( self.hbox ) self.button = gtk.Button() buttBox = gtk.EventBox() buttBox.add(self.button) buttBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.button.set_image( Constants.recPlayImg ) self.button.set_property('can-default', True) self.button.set_relief(gtk.RELIEF_NONE) self.button.set_size_request( self.ui.recordButtWd, self.ui.recordButtWd ) buttBox.set_size_request( self.ui.recordButtWd, self.ui.recordButtWd ) #self.button.set_border_width( UI.dim_INSET/2 ) self.button.show() buttBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.button.modify_bg( gtk.STATE_ACTIVE, Constants.colorBlack.gColor ) self.button.connect('clicked', self._buttonClickedCb) self.hbox.pack_start(buttBox, expand=False) self.adjustment = gtk.Adjustment(0.0, 0.00, 100.0, 0.1, 1.0, 1.0) self.hscale = gtk.HScale(self.adjustment) self.hscale.set_draw_value(False) self.hscale.set_update_policy(gtk.UPDATE_CONTINUOUS) hscaleBox = gtk.EventBox() hscaleBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) hscaleBox.add( self.hscale ) self.hscale.connect('button-press-event', self._scaleButtonPressCb) self.hscale.connect('button-release-event', self._scaleButtonReleaseCb) self.hbox.pack_start(hscaleBox, expand=True) def removeCallbacks( self ): if (self.UPDATE_SCALE_ID != 0): gobject.source_remove(self.UPDATE_SCALE_ID) self.UPDATE_SCALE_ID = 0 if (self.CHANGED_ID != 0): gobject.source_remove(self.CHANGED_ID) self.CHANGED_ID = 0 def reset(self): self.adjustment.set_value(0) def _buttonClickedCb(self, widget): self.play_toggled() def set_button_play(self): self.button.set_image(Constants.recPlayImg) def set_button_pause(self): self.button.set_image(Constants.recPauseImg) def play_toggled(self): self.p_position, self.p_duration = self.ui.ca.gplay.queryPosition() if (self.p_position == self.p_duration): self.ui.ca.gplay.seek(0) self.ui.ca.gplay.pause() if self.ui.ca.gplay.is_playing(): self.ui.ca.gplay.pause() self.set_button_play() else: #if self.ui.ca.gplay.error: # #todo: check if we have "error", and also to disable everything # self.button.set_disabled() #else: self.doPlay() def doPlay(self): self.ui.ca.gplay.play() if self.UPDATE_SCALE_ID == 0: self.UPDATE_SCALE_ID = gobject.timeout_add(self.UPDATE_INTERVAL, self._updateScaleCb) self.set_button_pause() def _scaleButtonPressCb(self, widget, event): #self.button.set_sensitive(False) self.was_playing = self.ui.ca.gplay.is_playing() if self.was_playing: self.ui.ca.gplay.pause() # don't timeout-update position during seek if self.UPDATE_SCALE_ID != 0: gobject.source_remove(self.UPDATE_SCALE_ID) self.UPDATE_SCALE_ID = 0 # make sure we get changed notifies if self.CHANGED_ID == 0: self.CHANGED_ID = self.hscale.connect('value-changed', self._scaleValueChangedCb) def _scaleButtonReleaseCb(self, widget, event): # see seek.cstop_seek widget.disconnect(self.CHANGED_ID) self.CHANGED_ID = 0 #self.button.set_sensitive(True) if self.was_playing: self.ui.ca.gplay.play() if self.UPDATE_SCALE_ID != 0: pass #print('Had a previous update timeout id') else: self.UPDATE_SCALE_ID = gobject.timeout_add(self.UPDATE_INTERVAL, self._updateScaleCb) def _scaleValueChangedCb(self, scale): real = long(scale.get_value() * self.p_duration / 100) # in ns self.ui.ca.gplay.seek(real) # allow for a preroll self.ui.ca.gplay.get_state(timeout=50*gst.MSECOND) # 50 ms def _updateScaleCb(self): self.p_position, self.p_duration = self.ui.ca.gplay.queryPosition() if self.p_position != gst.CLOCK_TIME_NONE: value = self.p_position * 100.0 / self.p_duration if (value > 99): value = 99 elif (value < 0): value = 0 self.adjustment.set_value(value) if self.ui.ca.gplay.is_playing() and (self.p_position == self.p_duration): self.ui.ca.gplay.pause() self.set_button_play() return True class MaxButton(P5Button): def __init__(self, ui): P5Button.__init__(self) self.ui = ui self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) xs = [] ys = [] xs.append(0) ys.append(0) xs.append(self.ui.maxw) ys.append(0) xs.append(self.ui.maxw) ys.append(self.ui.maxh) xs.append(0) ys.append(self.ui.maxh) poly = Polygon( xs, ys ) butt = Button( poly, 0, 0) butt.addActionListener( self ) self.maxS = "max" butt.setActionCommand( self.maxS ) self._butts.append( butt ) def draw(self, ctx, w, h): if (self.ui.FULLSCREEN): Constants.maxEnlargeSvg.render_cairo( ctx ) else: Constants.maxReduceSvg.render_cairo( ctx ) def fireButton(self, actionCommand): if (actionCommand == self.maxS): self.ui.doFullscreen() class InfButton(P5Button): #todo: just a gtk.Image here, no? def __init__(self, ui): P5Button.__init__(self) self.ui = ui self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) self.set_size_request( 75, 75 ) xs = [] ys = [] xs.append(0) ys.append(0) xs.append(75) ys.append(0) xs.append(75) ys.append(75) xs.append(0) ys.append(75) poly = Polygon( xs, ys ) butt = Button( poly, 0, 0) butt.addActionListener( self ) self.infS = "inf" butt.setActionCommand( self.infS ) self._butts.append( butt ) def draw(self, ctx, w, h): self.background( ctx, Constants.colorBlack, w, h ) Constants.infoOnSvg.render_cairo( ctx ) def fireButton(self, actionCommand): if (actionCommand == self.infS): self.ui.infoButtonClicked() class RecordButton(gtk.Button): def __init__(self): gtk.Button.__init__(self) self.sens = True self.img = None #todo: check on record state, compare button imgs def set_sensitive(self, sen, full): if (sen == self.sens): return self.sens = sen if (self.sens): self.set_image( Constants.recImg ) else: if (full): self.set_image( Constants.fullInsensitiveImg ) else: self.set_image( Constants.recInsensitiveImg ) super(RecordButton, self).set_sensitive(self.sens) def doRecordButton(self): if (not self.sens): return self.set_image( Constants.recRedImg ) def doNormalButton(self): if (not self.sens): return self.set_image( Constants.recImg ) class RecordWindow(gtk.Window): def __init__(self, ui): gtk.Window.__init__(self) self.ui = ui self.num = -1 self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.shutterButton = RecordButton() self.shutterButton.set_size_request(self.ui.recordButtWd, self.ui.recordButtWd) self.shutterButton.set_relief(gtk.RELIEF_NONE) self.shutterButton.set_image( Constants.recImg ) self.shutterButton.connect("clicked", self.ui._shutterClickCb) shutterBox = gtk.EventBox() shutterBox.add( self.shutterButton ) shutterBox.set_size_request( self.ui.controlBarHt, self.ui.controlBarHt ) shutterBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.shutterButton.modify_bg( gtk.STATE_ACTIVE, Constants.colorBlack.gColor ) hbox = gtk.HBox() self.add( hbox ) leftPanel = gtk.VBox() self.leftEvent = gtk.EventBox() self.leftEvent.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.leftEvent.add( leftPanel ) self.leftEvent.set_size_request(self.ui.vw/2-self.ui.controlBarHt, -1) hbox.pack_start( self.leftEvent, expand=True ) hbox.pack_start( shutterBox, expand=False ) rightPanel = gtk.VBox() self.rightEvent = gtk.EventBox() self.rightEvent.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.rightEvent.add( rightPanel ) hbox.pack_start( self.rightEvent, expand=True ) self.rightPanelLabel = gtk.Label() rightPanel.pack_start( self.rightPanelLabel ) def updateCountdown(self, num): if(num>0): if (num != self.num): ok = self.getCairoCountdown(num) self.shutterButton.set_image(ok) self.num = num else: self.num = -1 def getCairoCountdown(self, num): return Constants.countdownImgs[int(num)] def minimize( self ): self.leftEvent.set_size_request(-1, -1) self.rightEvent.set_size_request(-1, -1) def maximize( self ): w = self.ui.vw/2-self.ui.controlBarHt self.rightEvent.set_size_request(w, -1) self.leftEvent.set_size_request(w, -1) def displayDiscFullText( self, full ): if (not full or self.ui.ca.m.MODE != Constants.MODE_PHOTO): self.rightPanelLabel.set_text("") self.minimize() else: fullMessage = Constants.istrYourDiskIsFull % {"1":Constants.istrJournal} self.rightPanelLabel.set_text("" + fullMessage + "") self.rightPanelLabel.set_use_markup( True ) self.rightPanelLabel.set_alignment(1, 1) self.maximize() class ProgressWindow(gtk.Window): def __init__(self, ui): gtk.Window.__init__(self) self.ui = ui self.update = "" self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) eb = gtk.EventBox() eb.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) eb.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) self.add( eb ) vb = gtk.VBox() vb.set_border_width(5) #todo: use variable eb.add(vb) self.progBar = gtk.ProgressBar() self.progBar.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.progBar.modify_bg( gtk.STATE_ACTIVE, Constants.colorBlack.gColor ) self.progBar.modify_bg( gtk.STATE_PRELIGHT, Constants.colorBlack.gColor ) self.progBar.modify_bg( gtk.STATE_SELECTED, Constants.colorBlack.gColor ) self.progBar.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) vb.add( self.progBar ) hbox = gtk.HBox() vb.add( hbox ) self.infoLabel = gtk.Label() self.infoLabel.set_alignment( 1, .5 ) self.infoLabel.set_text( "SPACE") self.infoLabel.set_use_markup( True ) hbox.pack_start(self.infoLabel) def updateProgress( self, amt, update, color='white' ): logging.debug('updateProgress %s' % amt) self.progBar.set_fraction( amt ) if (update != None and update != self.update): self.update = update self.infoLabel.set_text( ""+self.update+"") self.infoLabel.set_use_markup( True ) if (self.update==""): self.infoLabel.set_text( "SPACE") self.infoLabel.set_use_markup( True ) if (amt >= 1): self.progBar.set_fraction( 0 ) class PhotoToolbar(gtk.Toolbar): def __init__(self): gtk.Toolbar.__init__(self) img = ToolButton('media-photo') img.connect('clicked', self._shutterClickCb) img.get_icon_widget().set_property( 'fill-color', Instance.colorFill.hex ) img.get_icon_widget().set_property( 'stroke-color', Instance.colorStroke.hex ) self.insert(img, -1) img.set_sensitive(False) img.show() separator = gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(True) self.insert(separator, -1) separator.show() timerCbb = gtk.combo_box_new_text() self.timerCb = ToolComboBox(combo=timerCbb, label_text=Constants.istrTimer) for i in range (0, len(Constants.TIMERS)): if (i == 0): self.timerCb.combo.append_text( Constants.istrNow ) else: self.timerCb.combo.append_text(istrSeconds(Constants.TIMERS[i])) self.timerCb.combo.set_active(0) self.insert( self.timerCb, -1 ) def _shutterClickCb(self, button): pass #self.ui.doShutter() def getTimer(self): return Constants.TIMERS[self.timerCb.combo.get_active()] class VideoToolbar(gtk.Toolbar): def __init__(self): gtk.Toolbar.__init__(self) img = ToolButton('media-video') img.connect('clicked', self._shutterClickCb) img.get_icon_widget().set_property( 'fill-color', Instance.colorFill.hex ) img.get_icon_widget().set_property( 'stroke-color', Instance.colorStroke.hex ) self.insert(img, -1) img.set_sensitive(False) img.show() separator = gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(True) self.insert(separator, -1) separator.show() combo = gtk.combo_box_new_text() self.quality = ToolComboBox(combo=combo, label_text=Constants.istrQuality+':') self.quality.combo.append_text(Constants.istrLowQuality) self.quality.combo.append_text(Constants.istrHighQuality) self.quality.combo.append_text(Constants.istrBestQuality) self.quality.combo.set_active(0) self.insert(self.quality, -1 ) timerCbb = gtk.combo_box_new_text() self.timerCb = ToolComboBox(combo=timerCbb, label_text=Constants.istrTimer) for i in range (0, len(Constants.TIMERS)): if (i == 0): self.timerCb.combo.append_text( Constants.istrNow ) else: self.timerCb.combo.append_text(istrSeconds(Constants.TIMERS[i])) self.timerCb.combo.set_active(0) self.insert( self.timerCb, -1 ) separator2 = gtk.SeparatorToolItem() separator2.set_draw(False) separator2.set_expand(False) separator2.set_size_request(UI.dim_INSET, -1) self.insert( separator2, -1 ) durCbb = gtk.combo_box_new_text() self.durCb = ToolComboBox(combo=durCbb, label_text=Constants.istrDuration) for i in range (0, len(Constants.DURATIONS)): self.durCb.combo.append_text(istrMinutes(Constants.DURATIONS[i])) self.durCb.combo.set_active(0) self.insert(self.durCb, -1 ) def _shutterClickCb(self, button): pass #self.ui.doShutter() def getTimer(self): return Constants.TIMERS[self.timerCb.combo.get_active()] def getDuration(self): return 60 * Constants.DURATIONS[self.durCb.combo.get_active()] def getQuality(self): return self.quality.combo.get_active() class AudioToolbar(gtk.Toolbar): def __init__(self): gtk.Toolbar.__init__(self) img = ToolButton('media-audio') img.connect('clicked', self._shutterClickCb) img.get_icon_widget().set_property( 'fill-color', Instance.colorFill.hex ) img.get_icon_widget().set_property( 'stroke-color', Instance.colorStroke.hex ) self.insert(img, -1) img.set_sensitive(False) img.show() separator = gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(True) self.insert(separator, -1) separator.show() timerCbb = gtk.combo_box_new_text() self.timerCb = ToolComboBox(combo=timerCbb, label_text=Constants.istrTimer) for i in range (0, len(Constants.TIMERS)): if (i == 0): self.timerCb.combo.append_text( Constants.istrNow ) else: self.timerCb.combo.append_text(istrSeconds(Constants.TIMERS[i])) self.timerCb.combo.set_active(0) self.insert( self.timerCb, -1 ) separator2 = gtk.SeparatorToolItem() separator2.set_draw(False) separator2.set_expand(False) separator2.set_size_request(UI.dim_INSET, -1) self.insert( separator2, -1 ) durCbb = gtk.combo_box_new_text() self.durCb = ToolComboBox(combo=durCbb, label_text=Constants.istrDuration) for i in range (0, len(Constants.DURATIONS)): self.durCb.combo.append_text(istrMinutes(Constants.DURATIONS[i])) self.durCb.combo.set_active(0) self.insert(self.durCb, -1 ) def _shutterClickCb(self, button): pass #self.ui.doShutter() def getTimer(self): return Constants.TIMERS[self.timerCb.combo.get_active()] def getDuration(self): return 60 * Constants.DURATIONS[self.durCb.combo.get_active()]