diff --git a/Ivolutioner b/Ivolutioner
index f4646c3..9910e9f 100755
--- a/Ivolutioner
+++ b/Ivolutioner
@@ -1,10 +1,8 @@
#!/usr/bin/env python
-from gi.repository import Gtk, GObject
+import wx
from ivolution.gui import IvolutionWindow
-
-import os
-my_app = IvolutionWindow.IvolutionWindow("Ivolution")
-GObject.threads_init()
-Gtk.main()
+app = wx.App(False)
+frame = IvolutionWindow.IvolutionWindow(None, "Ivolution Window")
+app.MainLoop() # Runs application
diff --git a/Ivolutioner_wx b/Ivolutioner_wx
deleted file mode 100755
index b2dec15..0000000
--- a/Ivolutioner_wx
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env python
-
-from ivolution.gui_wx import IvolutionWindow
-
-
-import wx
-
-app = wx.App(False)
-frame = IvolutionWindow.IvolutionWindow(None, "Ivolution Window")
-app.MainLoop() # Runs application
diff --git a/ivolution/data/ui/AboutIvolutionDialog.glade b/ivolution/data/ui/AboutIvolutionDialog.glade
deleted file mode 100644
index 76412d2..0000000
--- a/ivolution/data/ui/AboutIvolutionDialog.glade
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
diff --git a/ivolution/data/ui/IvolutionWindow.glade b/ivolution/data/ui/IvolutionWindow.glade
deleted file mode 100644
index cb4e516..0000000
--- a/ivolution/data/ui/IvolutionWindow.glade
+++ /dev/null
@@ -1,711 +0,0 @@
-
-
-
-
-
- True
- False
- 0.46000000834465027
- gtk-help
-
-
- False
- Ivolution
- ../media/ivolution.svg
-
-
-
- True
- False
- 5
-
-
-
- False
- True
- 0
-
-
-
-
- 100
- True
- False
-
-
- True
- False
- 0
- ../media/vitruve_50.jpg
-
-
- False
- True
- -1
-
-
-
-
- True
- False
- vertical
-
-
- True
- False
- 0
- 3
- 1
- Ivolution
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- 0
- 3
- Take one picture of yourself a day,
-automatically generate a movie!
-
-
-
-
-
- False
- True
- 1
-
-
-
-
- False
- True
- 2
-
-
-
-
- False
- False
- 1
-
-
-
-
- True
- False
-
-
- True
- False
- vertical
-
-
- True
- False
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- 7
- Required parameters :
-
-
-
-
-
-
- False
- True
- 1
-
-
-
-
- True
- False
- vertical
-
-
- True
- False
- 0.10000000149011612
- Choose your input folder :
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- vertical
- select-folder
-
-
- False
- True
- 1
-
-
-
-
- False
- True
- 2
-
-
-
-
- True
- False
- vertical
-
-
- True
- False
- 0.10000000149011612
- Choose your output folder:
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- vertical
- select-folder
-
-
- False
- True
- 1
-
-
-
-
- False
- True
- 3
-
-
-
-
- True
- False
- vertical
-
-
- True
- False
- 7
- Optional parameters :
-
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- vertical
-
-
- True
- False
- 0.10000000149011612
- Type of face :
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- 0
-
- - frontal_face
- - profile_face
-
-
-
- False
- True
- 1
-
-
-
-
- False
- True
- 1
-
-
-
-
- True
- False
- vertical
-
-
- True
- False
- 0.10000000149011612
- Video speed :
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- 0
- 1
-
- - slow
- - medium
- - fast
-
-
-
- False
- True
- 1
-
-
-
-
- False
- True
- 2
-
-
-
-
- True
- False
- vertical
-
-
- True
- False
- 0.10000000149011612
- Choose your prefered mode :
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- 6
- True
-
-
- False
- True
- True
- False
- False
- 0
- True
- blackboxradiobutton
-
-
-
- True
- False
- Crop Mode
-
-
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- False
- True
- True
- False
- False
- 0
- True
- True
- cropradiobutton
-
-
- True
- False
- Conservative Mode
-
-
-
-
-
-
-
- False
- True
- 1
-
-
-
-
- False
- True
- 1
- 1
-
-
-
-
- False
- True
- 3
-
-
-
-
- True
- False
- vertical
-
-
- True
- False
- 0.10000000149011612
- File sorting method :
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- 6
- True
-
-
- False
- True
- True
- False
- False
- 0
- 0.51999998092651367
- True
- True
- EXIFsortradiobutton
-
-
-
- True
- False
- File Name
-
-
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- False
- True
- True
- False
- False
- 0
- True
- True
- namesortradiobutton
-
-
- True
- False
- EXIF Metadata
-
-
-
-
-
-
-
- False
- True
- 1
-
-
-
-
- False
- True
- 1
-
-
-
-
- False
- True
- 4
-
-
-
-
- False
- True
- 4
-
-
-
-
- True
- False
-
-
- False
- True
- 3
- 5
-
-
-
-
- True
- False
- True
-
-
- False
- True
- True
- True
- False
-
-
-
- True
- False
- Create Movie !
-
-
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- False
- True
- True
- True
- False
-
-
-
- True
- False
- Stop Processing
-
-
-
-
-
-
-
- False
- True
- 1
-
-
-
-
- False
- True
- 5
- 7
-
-
-
-
- False
- True
- 2
-
-
-
-
- False
- False
- 2
-
-
-
-
- True
- False
-
- True
-
-
- True
- True
- 4
-
-
-
-
- True
- False
- 2
-
-
- True
- False
- 0
- 5
- 5
- Status Area
-
-
- True
- True
- 0
-
-
-
-
- False
- True
- end
- 5
-
-
-
-
-
-
diff --git a/ivolution/gui/AboutDialog.py b/ivolution/gui/AboutDialog.py
deleted file mode 100755
index d88dd3d..0000000
--- a/ivolution/gui/AboutDialog.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from gi.repository import Gtk
-
-from .. import get_data
-
-
-class AboutDialog():
-
- def __init__(self):
- """
- Special static method that's automatically called by Python when
- constructing a new instance of this class.
-
- Returns a fully instantiated AboutDialog object.
- """
- self.builder = Gtk.Builder()
- self.builder.add_from_file(get_data("/ui/AboutIvolutionDialog.glade"))
- self.window = self.builder.get_object("about_ivolution_dialog")
-
- self.window.run()
- self.window.destroy()
diff --git a/ivolution/gui_wx/IvolutionTemplate.py b/ivolution/gui/IvolutionTemplate.py
similarity index 100%
rename from ivolution/gui_wx/IvolutionTemplate.py
rename to ivolution/gui/IvolutionTemplate.py
diff --git a/ivolution/gui/IvolutionWindow.py b/ivolution/gui/IvolutionWindow.py
old mode 100755
new mode 100644
index cf2d7af..8914693
--- a/ivolution/gui/IvolutionWindow.py
+++ b/ivolution/gui/IvolutionWindow.py
@@ -1,108 +1,97 @@
#!/usr/bin/env python
+"""
+.. module:: IvolutionWindow
+ :platform: Unix, Windows, Mac
+ :synopsis: Main Window of the Ivolution GUI designed to be supported by all platforms.
+.. moduleauthor:: Julien Lengrand-Lambert
+
+"""
+
+import wx
+import wx.lib.newevent
+
+import sys
import os
-import webbrowser
import logging
+import webbrowser
-from gi.repository import Gtk, GLib
-from AboutDialog import AboutDialog
-
-from .. import get_data
-
-# import os
-# parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-# os.sys.path.insert(0,parentdir) # import parent folder
+from .. import get_data # used to load images and files
from .. import FaceParams
from .. import FacemovieThread
+
from ..util.Notifier import Observer
from ..util.Notifier import Observable
+from IvolutionTemplate import IvolutionTemplate
+from SettingsWindow import SettingsWindow
-class IvolutionWindow(Observer, Observable):
- def __init__(self, name):
- Observer.__init__(self, name)
+
+class IvolutionWindow(IvolutionTemplate, Observer, Observable):
+ """
+ Main Window of the Ivolution application
+ """
+ def __init__(self, parent, title):
+ """
+ Overrides init frame IvolutionTemplate
+ """
+ IvolutionTemplate.__init__(self, parent)
+ Observer.__init__(self, "Interface")
Observable.__init__(self)
+ # Sets up logging capability
self.my_logger = None
self.console_logger = None
+ self.setup_logger()
- self.builder = Gtk.Builder()
- self.builder.add_from_file(get_data('ui/IvolutionWindow.glade'))
- #self.builder.add_from_file("ivolution/data/ui/IvolutionWindow.glade")
- #self.builder.connect_signals({ "on_ivolutionwindow_destroy" : Gtk.main_quit })
- self.window = self.builder.get_object("ivolution_window")
- self.window.show()
- self.builder.connect_signals(self)
+ # Defines all our parameters neededfor the facemovie
+ self.get_default_parameters()
+
+ self.process_running = False
+ self.facemovie = None
+
+ self.inputtextbox.SetLabel(self.in_fo) # sets label to default input folder
+ self.SetIcon(wx.Icon('ivolution/data/media/vitruve.ico', wx.BITMAP_TYPE_ICO)) # Sets icon
+
+ self.Show(True) # Finally show the frame
+
+ def get_default_parameters(self):
+ """
+ """
+ # FIXME: Put really general stuff here !
+ self.videospeedlistChoices = [u"slow", u"medium", u"fast"]
+ self.gaugerange = 100
- ## Defines parameters needed to run the FaceMovie
self.root_fo = ""
- self.in_fo = "" # Input folder, where images are located
- self.out_fo = "" # Input folder, where the video will be saved
self.mode = "crop" # type of video to be created
self.sort = "name" # how image files will be chronologically sorted
self.speed = 1 # Speed of the movie
self.param = "frontal_face" # type of face profile to be searched for
- self.in_fo = "" # Input folder, where images are located
-
- self.process_running = False
-
- self.facemovie = None
-
- self.AboutDialog = None # class
-
- self.setup()
- self.setup_logger()
-
- def setup(self):
- """
- Sets up all the default paramters and retrieve the element of the GUI we want to follow
- """
- self.AboutDialog = AboutDialog # FIXME : Still not working
-
- self.startbutton = self.builder.get_object("startbutton")
-
- self.filechooserinput = self.builder.get_object("filechooserinput")
- self.filechooseroutput = self.builder.get_object("filechooseroutput")
-
- self.typecombobox = self.builder.get_object("typecombobox")
- self.typecombobox.set_active(0)
-
- self.speedcombobox = self.builder.get_object("speedcombobox")
- self.speedcombobox.set_active(0)
-
- self.cropradiobutton = self.builder.get_object("cropradiobutton")
- self.namesortradiobutton = self.builder.get_object("namesortradiobutton")
-
- self.progressbar = self.builder.get_object("progressbar")
- self.statuslabel = self.builder.get_object("statuslabel")
-
- # Signal handling related stuff
- def on_cropradiobutton_toggled(self, widget):
- """
- We need to take care only of this one as both are grouped
- """
- if widget.get_active(): # means crop is activated
- self.mode = "crop"
+ if "win" in sys.platform:
+ self.out_fo = "C:/Users/jll/Videos/" # Default folder for Windows
+ self.in_fo = "C:\Users\jll\Pictures/"
else:
- self.mode = "conservative"
+ self.out_fo = "/home/jll/Videos/" # Default folder for Linux
+ self.in_fo = "/home/jll/Pictures/"
- def on_namesortradiobutton_toggled(self, widget):
- """
- We need to take care only of this one as both are grouped
- """
- if widget.get_active(): # means name is activated
- self.sort = "name"
- else:
- self.sort = "exif"
+ # Overriding event handling methods
+ def on_settings(self, event):
+ settings = SettingsWindow(self)
+ settings.Show(True) # Finally show the frame
- def on_startbutton_pressed(self, widget):
+ def on_start(self, event):
"""
+ User asks for starting the algorithm
Sets all parameters and start processing
"""
self.my_logger.debug("start pressed")
+
if not self.process_running: # start only if not already running
+ # Empty list on screen
+ self.filelist.DeleteAllItems()
+
self.set_parameters()
self.print_parameters()
# Instantiating the facemovie
@@ -117,59 +106,150 @@ class IvolutionWindow(Observer, Observable):
self.console_logger.error("Cannot start, process already running !")
self.my_logger.error("Cannot start, process already running !")
- def on_stopbutton_pressed(self, widget):
+ def on_stop(self, event):
"""
- Asks the Facemovie thread to terminate
+ User asks for stopping the algorithm
+ Asks the FacemovieThread to terminate
"""
self.my_logger.debug("Stop pressed")
self.console_logger.debug("Stop pressed")
- self.notify(["STOP"]) # Asking the Facemovie to stop
+ self.notify(["Application", ["STOP"]]) # Asking the Facemovie to stop
self.process_running = False
- def on_destroy(self, widget, data=None):
- """Called when the IvolutionWindow is closed."""
- # Clean up code for saving application state should be added here.
- self.notify(["STOP"]) # Asking the Facemovie to stop
- self.process_running = False
+ #self.on_exit(event) # Finally shuts down the interface
- Gtk.main_quit()
- print "Gtk Exited"
-
- def on_menu_about_activate(self, widget, data=None):
+ def on_input(self, event):
"""
- Displays the about box for Ivolution
- # FIXME : Can start several about Dialogs at the same time
+ Activated when a user clicks to choose its input location
"""
- if self.AboutDialog is not None:
- about = self.AboutDialog()
+ self.inputdialog = wx.DirDialog(self, "Please choose your input directory", style=1, defaultPath=self.in_fo)
- def on_menu_help_activate(self, widget, data=None):
+ if self.inputdialog.ShowModal() == wx.ID_OK:
+ self.in_fo = self.inputdialog.GetPath()
+ self.inputtextbox.SetLabel(self.in_fo)
+ self.inputdialog.Destroy()
+
+ def on_output(self, event):
+ """
+ Activated when a user clicks to choose its output location
+ """
+ default_dir = "~/Videos"
+ self.outputdialog = wx.DirDialog(self, "Please choose your output directory", style=1, defaultPath=default_dir)
+
+ if self.outputdialog.ShowModal() == wx.ID_OK:
+ self.outputchoosertext.SetLabel(self.outputdialog.GetPath())
+ self.outputdialog.Destroy()
+
+ def on_help(self, event):
"""
Opens a browser and points to online help.
"""
url = "http://jlengrand.github.com/FaceMovie/"
webbrowser.open(url, new=2) # in new tab if possible
- #print "Should open help"
- #Methods processing data
+ def on_about(self, event):
+ """
+ Displays the about box for Ivolution
+ """
+ description =""" Ivolution is a project aiming at helping you
+create videos of yourself over time.
+ Simply take pictures of yourself, Ivolution does
+everything else for you.
+
+ Ivolution may be used for faces, but also profiles
+(to show women along pregnancy for example)
+or full body (for people workouting).
+
+ The only limitation comes from you !
+"""
+
+ licence = """Copyright (c) <2012>,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those
+of the authors and should not be interpreted as representing official policies,
+either expressed or implied, of the FreeBSD Project."""
+
+ info = wx.AboutDialogInfo()
+
+ info.SetIcon(wx.Icon('ivolution/data/media/vitruve.png', wx.BITMAP_TYPE_PNG))
+ info.SetName('Ivolution')
+ info.SetVersion('0.8')
+ info.SetDescription(description)
+ info.SetCopyright('(C) 2012 Julien Lengrand-Lambert')
+ info.SetWebSite('http://www.lengrand.fr')
+ info.SetLicence(licence)
+ info.AddDeveloper('Julien Lengrand-Lambert')
+ info.AddDocWriter('Julien Lengrand-Lambert')
+ info.AddArtist('Luc Viatour')
+ info.AddTranslator('Julien Lengrand-Lambert')
+
+ wx.AboutBox(info)
+
+ def on_exit(self, event):
+ """
+ Called when the IvolutionWindow is closed, or File/Exit is called.
+ """
+ # Clean up code for saving application state should be added here.
+ self.notify(["Application", ["STOP"]]) # Asking the Facemovie to stop
+ self.process_running = False
+ self.Close(True) # Close the frame.
+
+ # system methods
+ def get_current_mode(self):
+ """
+ """
+ if self.cropmode.GetValue():
+ mode = "crop"
+ else:
+ mode = "conservative"
+
+ return mode
+
+ def get_current_sort(self):
+ """
+ """
+ if self.namemode.GetValue():
+ sort = "name"
+ else:
+ sort = "exif"
+
+ return sort
+
def set_parameters(self):
"""
- Sets all needed parameters for create the movie.
+ Retrieves all parameters needed for the algorithm to run
"""
- self.in_fo = self.filechooserinput.get_current_folder() + "/" # TODO : Find correct fix
- self.out_fo = self.filechooseroutput.get_current_folder() + "/" # TODO : Find correct fix
- self.param = self.typecombobox.get_active_text()
- self.speed = self.speedcombobox.get_active() # We need and integer between 0 and 2
-
# Instantiating the face_params object that will be needed by the facemovie
+ self.out_fo += "/" #FIXME: enhance that
par_fo = os.path.join(self.root_fo, get_data("haarcascades"))
self.face_params = FaceParams.FaceParams(par_fo,
- self.in_fo,
- self.out_fo,
- self.param,
- self.sort,
- self.mode,
- self.speed)
+ self.in_fo,
+ self.out_fo,
+ self.param,
+ self.sort,
+ self.mode,
+ self.speed)
def print_parameters(self):
print "#########"
@@ -234,10 +314,10 @@ class IvolutionWindow(Observer, Observable):
if message[0] == "PROGRESS": # progress bar
# big steps performed
-
- # Uses GLib to run Thread safe operations on GUI
- GLib.idle_add(self.progressbar.set_fraction, float(message[2]))
- GLib.idle_add(self.progressbar.set_text, message[1])
+ wx.MutexGuiEnter() # to avoid thread problems
+ self.progressgauge.SetValue(self.gaugerange * float(message[2]))
+ self.statusbar.SetStatusText(message[1], 0)
+ wx.MutexGuiLeave()
if float(message[2]) >= 1.0: # 100% of process
self.my_logger.debug("Reached end of facemovie process")
@@ -245,16 +325,35 @@ class IvolutionWindow(Observer, Observable):
self.process_running = False
elif message[0] == "STATUS": # status label
- # intermediate results
- GLib.idle_add(self.statuslabel.set_text, message[1])
- #pass
+ if message[1] == "Error":
+ wx.MutexGuiEnter() # to avoid thread problems
+ self.statusbar.SetStatusText("Error detected", 0)
+ self.progressgauge.SetValue(0)
+ wx.MutexGuiLeave()
+ self.process_running = False
+
+ wx.MutexGuiEnter() # to avoid thread problems
+ self.statusbar.SetStatusText(message[1], 1)
+ wx.MutexGuiLeave()
+ elif message[0] == "FILEADD":
+ item = wx.ListItem()
+ item.SetText(message[1])
+ wx.MutexGuiEnter() # to avoid thread problems
+ self.filelist.InsertItem(item)
+ wx.MutexGuiLeave()
+ elif message[0] == "FILEDONE":
+ for i in range(self.filelist.GetItemCount()):
+ if message[1] == self.filelist.GetItemText(i):
+ if message[2] == 1:
+ color = "green"
+ else:
+ color = "red"
+ wx.MutexGuiEnter() # to avoid thread problems
+ self.filelist.SetItemTextColour(i, color)
+ wx.MutexGuiLeave()
elif len(message) > 1: # system commands shall be ignored
self.console_logger.debug("Unrecognized command")
self.my_logger.debug("Unrecognized command")
self.console_logger.debug(message)
self.my_logger.debug(message)
-
-if __name__ == "__main__":
- app = IvolutionWindow()
- Gtk.main()
diff --git a/ivolution/gui_wx/SettingsTemplate.py b/ivolution/gui/SettingsTemplate.py
similarity index 100%
rename from ivolution/gui_wx/SettingsTemplate.py
rename to ivolution/gui/SettingsTemplate.py
diff --git a/ivolution/gui_wx/SettingsWindow.py b/ivolution/gui/SettingsWindow.py
similarity index 100%
rename from ivolution/gui_wx/SettingsWindow.py
rename to ivolution/gui/SettingsWindow.py
diff --git a/ivolution/gui/__init__.py b/ivolution/gui/__init__.py
old mode 100755
new mode 100644
diff --git a/ivolution/gui_wx/IvolutionWindow.py b/ivolution/gui_wx/IvolutionWindow.py
deleted file mode 100644
index 8914693..0000000
--- a/ivolution/gui_wx/IvolutionWindow.py
+++ /dev/null
@@ -1,359 +0,0 @@
-#!/usr/bin/env python
-"""
-.. module:: IvolutionWindow
- :platform: Unix, Windows, Mac
- :synopsis: Main Window of the Ivolution GUI designed to be supported by all platforms.
-
-.. moduleauthor:: Julien Lengrand-Lambert
-
-"""
-
-import wx
-import wx.lib.newevent
-
-import sys
-import os
-import logging
-import webbrowser
-
-from .. import get_data # used to load images and files
-
-from .. import FaceParams
-from .. import FacemovieThread
-
-from ..util.Notifier import Observer
-from ..util.Notifier import Observable
-
-from IvolutionTemplate import IvolutionTemplate
-from SettingsWindow import SettingsWindow
-
-
-class IvolutionWindow(IvolutionTemplate, Observer, Observable):
- """
- Main Window of the Ivolution application
- """
- def __init__(self, parent, title):
- """
- Overrides init frame IvolutionTemplate
- """
- IvolutionTemplate.__init__(self, parent)
- Observer.__init__(self, "Interface")
- Observable.__init__(self)
-
- # Sets up logging capability
- self.my_logger = None
- self.console_logger = None
- self.setup_logger()
-
- # Defines all our parameters neededfor the facemovie
- self.get_default_parameters()
-
- self.process_running = False
- self.facemovie = None
-
- self.inputtextbox.SetLabel(self.in_fo) # sets label to default input folder
- self.SetIcon(wx.Icon('ivolution/data/media/vitruve.ico', wx.BITMAP_TYPE_ICO)) # Sets icon
-
- self.Show(True) # Finally show the frame
-
- def get_default_parameters(self):
- """
- """
- # FIXME: Put really general stuff here !
- self.videospeedlistChoices = [u"slow", u"medium", u"fast"]
- self.gaugerange = 100
-
- self.root_fo = ""
- self.mode = "crop" # type of video to be created
- self.sort = "name" # how image files will be chronologically sorted
- self.speed = 1 # Speed of the movie
- self.param = "frontal_face" # type of face profile to be searched for
-
- if "win" in sys.platform:
- self.out_fo = "C:/Users/jll/Videos/" # Default folder for Windows
- self.in_fo = "C:\Users\jll\Pictures/"
- else:
- self.out_fo = "/home/jll/Videos/" # Default folder for Linux
- self.in_fo = "/home/jll/Pictures/"
-
- # Overriding event handling methods
- def on_settings(self, event):
- settings = SettingsWindow(self)
- settings.Show(True) # Finally show the frame
-
- def on_start(self, event):
- """
- User asks for starting the algorithm
- Sets all parameters and start processing
- """
- self.my_logger.debug("start pressed")
-
- if not self.process_running: # start only if not already running
- # Empty list on screen
- self.filelist.DeleteAllItems()
-
- self.set_parameters()
- self.print_parameters()
- # Instantiating the facemovie
- self.facemovie = FacemovieThread.FacemovieThread(self.face_params)
- self.facemovie.subscribe(self) # I want new information ! Subscribes to facemovie reports
- self.subscribe(self.facemovie) # Subscribing facemovie to our messages
-
- self.facemovie.start()
-
- self.process_running = True
- else:
- self.console_logger.error("Cannot start, process already running !")
- self.my_logger.error("Cannot start, process already running !")
-
- def on_stop(self, event):
- """
- User asks for stopping the algorithm
- Asks the FacemovieThread to terminate
- """
- self.my_logger.debug("Stop pressed")
- self.console_logger.debug("Stop pressed")
- self.notify(["Application", ["STOP"]]) # Asking the Facemovie to stop
- self.process_running = False
-
- #self.on_exit(event) # Finally shuts down the interface
-
- def on_input(self, event):
- """
- Activated when a user clicks to choose its input location
- """
- self.inputdialog = wx.DirDialog(self, "Please choose your input directory", style=1, defaultPath=self.in_fo)
-
- if self.inputdialog.ShowModal() == wx.ID_OK:
- self.in_fo = self.inputdialog.GetPath()
- self.inputtextbox.SetLabel(self.in_fo)
- self.inputdialog.Destroy()
-
- def on_output(self, event):
- """
- Activated when a user clicks to choose its output location
- """
- default_dir = "~/Videos"
- self.outputdialog = wx.DirDialog(self, "Please choose your output directory", style=1, defaultPath=default_dir)
-
- if self.outputdialog.ShowModal() == wx.ID_OK:
- self.outputchoosertext.SetLabel(self.outputdialog.GetPath())
- self.outputdialog.Destroy()
-
- def on_help(self, event):
- """
- Opens a browser and points to online help.
- """
- url = "http://jlengrand.github.com/FaceMovie/"
- webbrowser.open(url, new=2) # in new tab if possible
-
- def on_about(self, event):
- """
- Displays the about box for Ivolution
- """
- description =""" Ivolution is a project aiming at helping you
-create videos of yourself over time.
- Simply take pictures of yourself, Ivolution does
-everything else for you.
-
- Ivolution may be used for faces, but also profiles
-(to show women along pregnancy for example)
-or full body (for people workouting).
-
- The only limitation comes from you !
-"""
-
- licence = """Copyright (c) <2012>,
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-The views and conclusions contained in the software and documentation are those
-of the authors and should not be interpreted as representing official policies,
-either expressed or implied, of the FreeBSD Project."""
-
- info = wx.AboutDialogInfo()
-
- info.SetIcon(wx.Icon('ivolution/data/media/vitruve.png', wx.BITMAP_TYPE_PNG))
- info.SetName('Ivolution')
- info.SetVersion('0.8')
- info.SetDescription(description)
- info.SetCopyright('(C) 2012 Julien Lengrand-Lambert')
- info.SetWebSite('http://www.lengrand.fr')
- info.SetLicence(licence)
- info.AddDeveloper('Julien Lengrand-Lambert')
- info.AddDocWriter('Julien Lengrand-Lambert')
- info.AddArtist('Luc Viatour')
- info.AddTranslator('Julien Lengrand-Lambert')
-
- wx.AboutBox(info)
-
- def on_exit(self, event):
- """
- Called when the IvolutionWindow is closed, or File/Exit is called.
- """
- # Clean up code for saving application state should be added here.
- self.notify(["Application", ["STOP"]]) # Asking the Facemovie to stop
- self.process_running = False
- self.Close(True) # Close the frame.
-
- # system methods
- def get_current_mode(self):
- """
- """
- if self.cropmode.GetValue():
- mode = "crop"
- else:
- mode = "conservative"
-
- return mode
-
- def get_current_sort(self):
- """
- """
- if self.namemode.GetValue():
- sort = "name"
- else:
- sort = "exif"
-
- return sort
-
- def set_parameters(self):
- """
- Retrieves all parameters needed for the algorithm to run
- """
- # Instantiating the face_params object that will be needed by the facemovie
- self.out_fo += "/" #FIXME: enhance that
- par_fo = os.path.join(self.root_fo, get_data("haarcascades"))
- self.face_params = FaceParams.FaceParams(par_fo,
- self.in_fo,
- self.out_fo,
- self.param,
- self.sort,
- self.mode,
- self.speed)
-
- def print_parameters(self):
- print "#########"
- print "Settings:"
- print "input folder : %s" % (self.in_fo)
- print "output folder : %s" % (self.out_fo)
-
- print "Face Type : %s" % (self.param)
- print "Speed chosen : %s" % (self.speed)
- print "Mode chosen : %s" % (self.mode)
- print "Sort method : %s" % (self.sort)
-
- print "#########"
-
- def setup_logger(self):
- """
- Configures our logger to save error messages
- Start logging in file here
- """
- personal_dir = "~/.ivolution"
- log_root = 'fm.log'
- log_file = os.path.join(os.path.expanduser(personal_dir), log_root)
-
- # create logger for 'facemovie'
- self.my_logger = logging.getLogger('FileLog')
-
- self.my_logger.setLevel(logging.DEBUG)
- # create file handler which logs even debug messages
-
- #fh = logging.StreamHandler()
- fh = logging.FileHandler(log_file)
-
- fh.setLevel(logging.DEBUG)
- # create console handler with a higher log level
- self.console_logger = logging.getLogger('ConsoleLog')
- self.console_logger.setLevel(logging.DEBUG) # not needed
-
- ch = logging.StreamHandler()
- #ch.setLevel(logging.DEBUG) # not needed
-
- # add the handlers to the logger
- self.my_logger.addHandler(fh)
-
- self.my_logger.info("######") # Separating different sessions
-
- formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
- # create formatter and add it to the handlers
- fh.setFormatter(formatter)
- #ch.setFormatter(formatter)
-
- self.console_logger.addHandler(ch)
-
- def update(self, message):
- """
- Trigerred by FacemovieThread.
- Uses the Observer pattern to inform the user about the progress of the current job.
- """
- if len(message) == 3:
- # notifications
- #self.console_logger.debug(message)
- self.my_logger.debug(message)
-
- if message[0] == "PROGRESS": # progress bar
- # big steps performed
- wx.MutexGuiEnter() # to avoid thread problems
- self.progressgauge.SetValue(self.gaugerange * float(message[2]))
- self.statusbar.SetStatusText(message[1], 0)
- wx.MutexGuiLeave()
-
- if float(message[2]) >= 1.0: # 100% of process
- self.my_logger.debug("Reached end of facemovie process")
- #self.console_logger.debug("Reached end of facemovie process")
- self.process_running = False
-
- elif message[0] == "STATUS": # status label
- if message[1] == "Error":
- wx.MutexGuiEnter() # to avoid thread problems
- self.statusbar.SetStatusText("Error detected", 0)
- self.progressgauge.SetValue(0)
- wx.MutexGuiLeave()
- self.process_running = False
-
- wx.MutexGuiEnter() # to avoid thread problems
- self.statusbar.SetStatusText(message[1], 1)
- wx.MutexGuiLeave()
- elif message[0] == "FILEADD":
- item = wx.ListItem()
- item.SetText(message[1])
- wx.MutexGuiEnter() # to avoid thread problems
- self.filelist.InsertItem(item)
- wx.MutexGuiLeave()
- elif message[0] == "FILEDONE":
- for i in range(self.filelist.GetItemCount()):
- if message[1] == self.filelist.GetItemText(i):
- if message[2] == 1:
- color = "green"
- else:
- color = "red"
- wx.MutexGuiEnter() # to avoid thread problems
- self.filelist.SetItemTextColour(i, color)
- wx.MutexGuiLeave()
-
- elif len(message) > 1: # system commands shall be ignored
- self.console_logger.debug("Unrecognized command")
- self.my_logger.debug("Unrecognized command")
- self.console_logger.debug(message)
- self.my_logger.debug(message)
diff --git a/ivolution/gui_wx/__init__.py b/ivolution/gui_wx/__init__.py
deleted file mode 100644
index e69de29..0000000