#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
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
timeRemainStr = Constants.istrSecondsRemaining % {"1":str(int(secsRemaining))}
if (secsRemaining >= 60):
mins = int( secsRemaining/60 )
secs = int( secsRemaining%60 )
timeRemainStr = Constants.istrMinutesSecondsRemaining % {"1":str(int(mins)), "2":str(int(secs))}
self.progressWindow.updateProgress( passedTime/duration, Constants.istrDuration + " " + 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
self.progressWindow.updateProgress( passedTime/timerTime, Constants.istrTimer + " " + Constants.istrSecondsRemaining % {"1":str(int(secsRemaining))} )
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( Constants.istrSeconds % {"1":(str(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( Constants.istrSeconds % {"1":(str(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( Constants.istrMinutes % {"1":(str(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( Constants.istrSeconds % {"1":(str(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( Constants.istrMinutes % {"1":(str(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()]