keera-posture-0.1.3: src/Controller/Conditions/Calibration.hs
-- | Performs the calibration by runing the person finder for a few seconds or
-- until a person is recognized.
module Controller.Conditions.Calibration (calibrate) where
-- External imports
import Control.Concurrent
import qualified Control.Exception as E
import Control.Exception.Extra
import Control.Monad
import Data.Maybe
import Graphics.UI.Gtk hiding (Image)
-- Internal imports
import CombinedEnvironment
import Model.Model (Status(..))
import Hails.MVC.Model.ProtectedModel.Reactive
import Paths
import I18N.Strings
import AI.CV.PostureProcessors
-- The following function is executed in a separate thread so that the
-- notification viewers are updated and the system remains responsive.
calibrate :: CEnv -> IO()
calibrate cenv = void $ forkOS $ do
let pm = model cenv
setStatus pm StatusCallibrating
-- Remember if the system was enabled and restore the same state later.
enabled <- getter notificationEnabledField pm
setter notificationEnabledField pm False
-- This value is completely random. It simply works, but there must be a
-- better way.
threadDelay 1000000
-- What for the detector to die
waitForDetector pm
E.handle (anyway (do setter calibrationParamsField pm (Nothing :: Maybe (Int, Int, Int, Int))
wrongCam pm
showCalibrationResults cenv Nothing
)) $ do
-- Run for a few seconds or until once face is detected
cam <- getter cameraField pm
res <- runFinder cam
setter calibrationParamsField pm res
-- If calibration went ok, reset the previous notification status
when (isJust res) $ setter notificationEnabledField pm enabled
-- TODO: Place the image in the pixbuf
showCalibrationResults cenv res
-- TODO: Enable the buttons
-- Maybe this should appear somewhere else? But careful with the previous handle
setStatus pm StatusIdle
-- | Present the calibration results (adapting the images and labels in the
-- dialog)
--
-- cvs is (Just _) if calibration went ok, otherwise it's Nothing
showCalibrationResults :: CEnv -> Maybe (Int, Int, Int, Int) -> IO()
showCalibrationResults cenv cvs = onViewAsync $ do
let ui = mainWindowBuilder $ view cenv
lblT <- calibrationTitleLbl ui
lblE <- calibrationExplanationLbl ui
calImg <- calibrationImage ui
if isJust cvs
then do fn <- getDataFileName "calibration-ok.png"
imageSetFromFile calImg fn
labelSetMarkup lblT title3
labelSetText lblE explanation3
else do fn <- getDataFileName "calibration-wrong.png"
imageSetFromFile calImg fn
labelSetMarkup lblT title2
labelSetText lblE explanation2
-- Showing the capture on the screen
-- when (isJust img && length cvs == 1) $
-- imageSetFromPixbuf calImg (fromJust img)
btn1 <- calibrationCloseBtn ui
btn2 <- calibrationRecalibrateBtn ui
widgetSetSensitive btn1 True
widgetSetSensitive btn2 True