/// <summary> /// Constructor /// </summary> /// <param name="dispatcher">The event queue</param> /// <param name="model">The model</param> protected SlideToolBarButton(ControlEventQueue dispatcher, PresenterModel model) { this.m_EventQueue = dispatcher; this.m_Model = model; this.m_Adapter = new WorkspaceModelAdapter(this.m_EventQueue, this, this.m_Model); }
public ToggleSlideZoomMenuItem(ControlEventQueue dispatcher, PresenterModel model) { this.m_EventQueue = dispatcher; this.m_Model = model; this.m_ZoomChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_EventQueue, new PropertyEventHandler(this.HandleZoomChanged)); this.m_Adapter = new WorkspaceModelAdapter(dispatcher, this, model); this.Text = Strings.ZoomSlide; }
/// <summary> /// Constructor /// </summary> /// <param name="dispatcher">The event queue</param> /// <param name="model">The model</param> public QuickPollToolBarButton(ControlEventQueue dispatcher, PresenterModel model) : base(dispatcher, model) { this.m_QuickPollChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_EventQueue, new PropertyEventHandler(this.HandleQuickPollChanged)); base.InitializeRole(); this.Enabled = false; this.m_Adapter = new WorkspaceModelAdapter(this.m_EventQueue, this, this.m_Model); }
/// <summary> /// Constructor /// </summary> /// <param name="dispatcher">The event queue</param> /// <param name="model">The model</param> public UndoRedoToolBarButton(EventQueue dispatcher, PresenterModel model) { this.m_EventQueue = dispatcher; this.m_Model = model; // TODO: Dynamically change the ToolTipText depending on what type of change will be undone. this.ToolTipText = Strings.UndoTooltipText; this.m_Model.Undo.Update += new EventHandler(this.HandleUndoableChanged); this.m_WorkspaceModelAdapter = new WorkspaceModelAdapter(dispatcher, this, this.m_Model); }
public UndoMenuItem(ControlEventQueue dispatcher, PresenterModel model) { this.m_Model = model; this.m_EventQueue = dispatcher; this.Text = Strings.Undo; this.Shortcut = Shortcut.CtrlZ; this.ShowShortcut = true; this.m_Model.Undo.Update += new EventHandler(this.HandleUndoableChanged); this.m_WorkspaceModelAdapter = new WorkspaceModelAdapter(dispatcher, this, this.m_Model); }
/// <summary> /// Constructor for this menu item /// </summary> /// <param name="dispatcher">The event dispatcher</param> /// <param name="model">The model to work with</param> public AcceptingQuickPollSubmissionsMenuItem(ControlEventQueue dispatcher, PresenterModel model) : base(dispatcher, model) { this.Text = Strings.EnableQuickPolling; this.m_HandleAcceptingQPChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_EventQueue, new PropertyEventHandler(this.HandleAcceptingQPChanged)); using (Synchronizer.Lock(this.m_Model.Participant.SyncRoot)) { //Listen to to changes in Accepting QP for the current role, if it is an InstructorModel if (this.m_Role is InstructorModel) { using (Synchronizer.Lock(this.m_Model.Participant.Role.SyncRoot)) { ((InstructorModel)this.m_Role).Changed["AcceptingQuickPollSubmissions"].Add(this.m_HandleAcceptingQPChangedDispatcher.Dispatcher); } } } this.HandleAcceptingQPChanged(this, null); // Enable or disable based on there being a valid slide this.Enabled = false; this.m_Adapter = new WorkspaceModelAdapter(this.m_EventQueue, this, this.m_Model); }
/// <summary> /// Creates a new instance of a second monitor form /// </summary> /// <param name="model"> /// Presenter model to display the second monitor form on /// </param> public SecondMonitorForm(PresenterModel model) { // Assign the model this.m_Model = model; // Layout the control this.SuspendLayout(); // Set the parameters of the form this.AccessibleDescription = "secondMonitorForm"; this.AccessibleName = "secondMonitorForm"; this.BackColor = System.Drawing.Color.White; this.Enabled = false; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.ShowInTaskbar = false; this.Visible = false; this.DesktopBounds = Screen.PrimaryScreen.Bounds; this.Name = "SecondMonitorForm"; this.Text = "Classroom Presenter 3 Dual-Monitor Display"; // Create the second monitor view this.m_SecondMonitorSlideViewer = new SecondMonitorSlideViewer(this.m_Model); this.m_SecondMonitorSlideViewer.Dock = DockStyle.Fill; //Set the disposition to always be public using (Synchronizer.Lock(this.m_SecondMonitorSlideViewer.SlideDisplay.SyncRoot)) { this.m_SecondMonitorSlideViewer.SlideDisplay.SheetDisposition = Model.Presentation.SheetDisposition.SecondMonitor | Model.Presentation.SheetDisposition.All | Model.Presentation.SheetDisposition.Background | Model.Presentation.SheetDisposition.Public; } // Attach the traversal and rendering of the second monitor to the model this.m_WorkspaceModelAdapter = new WorkspaceModelAdapter(this.m_SecondMonitorSlideViewer.SlideDisplay.EventQueue, this.m_SecondMonitorSlideViewer, this.m_Model); // Add the control this.Controls.Add(this.m_SecondMonitorSlideViewer); this.ResumeLayout(); // Keep track of changes to the number of monitors and whether the second monitor is enabled this.m_Model.ViewerState.Changed["NumberOfScreens"].Add(new PropertyEventHandler(this.HandleViewerStateChanged)); this.m_Model.ViewerState.Changed["SecondMonitorEnabled"].Add(new PropertyEventHandler(this.HandleViewerStateChanged)); this.HandleViewerStateChanged(this.m_Model.ViewerState, null); }
/// <summary> /// Creates a new <see cref="ViewerPresentationLayout"/> instance and instantiates all of the child controls. /// </summary> /// <param name="model">The model whose <see cref="WorkspaceModel.CurrentDeckTraversal"/> property will /// be used to display the current slide and deck.</param> public ViewerPresentationLayout(PresenterModel model) { this.Name = "ViewerPresentationLayout"; this.m_Model = model; this.m_EventQueue = new ControlEventQueue(this); m_Model.Workspace.CurrentDeckTraversal.ListenAndInitialize(m_EventQueue, new Property <DeckTraversalModel> .EventHandler(this.HandleTraversalChanged)); // Create the film strip, docked to the right side of the container. this.m_DeckStrip = new DeckStrip(this.m_Model); /// Filmstrip docking this.m_DeckStrip.Dock = DockStyle.Right; this.m_MainSlideViewer = new MainSlideViewer(this.m_Model, true); // Make the deck strip resizable with a LinkedSplitter. // The splitter automatically sets its dock to be the same as the FilmStrip and // keeps z-order correct with respect to the FilmStrip and the MainSlideViewer. this.m_DeckStripSplitter = new LinkedSplitter(this.m_DeckStrip, this.m_MainSlideViewer); // Create the MainSlideViewer, which occupies the remaining space in the container. this.m_MainSlideViewer.Dock = DockStyle.Fill; #region RealTimeStylus Initialization // Create a new RealTimeStylus, which will process ink drawn on the MainSlideViewer. this.m_RealTimeStylus = new RealTimeStylus(this.m_MainSlideViewer, true); try { // Enable touch input for the real time stylus this.m_RealTimeStylus.MultiTouchEnabled = true; this.m_TouchGestureHandler = new TouchGestureHandler(this.m_Model, this.m_EventQueue); this.m_RealTimeStylus.SyncPluginCollection.Add(this.m_TouchGestureHandler); } catch { } // Make sure the TransformableDynamicRenderer and InkAnnotationCollector // find out whenever the current StylusModel changes. this.m_StylusInputSelector = new StylusInputSelector(this.m_Model, this.m_RealTimeStylus); this.m_RealTimeStylus.SyncPluginCollection.Add(this.m_StylusInputSelector); // Scale the ink to the inverse of the MainSlideViewer's transform. // This keeps the ink's coordinates correct when the MainSlideViewer's transform // is applied again later by the TransformableDynamicRenderer and InkAnnotationCollector. this.m_InkTransformFilter = new InkTransformFilter(this.m_MainSlideViewer.SlideDisplay); this.m_RealTimeStylus.SyncPluginCollection.Add(this.m_InkTransformFilter); // Create a *synchronous* TransformableDynamicRenderer, which will render ink received directly // from the RealTimeStylus on a high-priority thread. this.m_TransformableDynamicRenderer = new TransformableDynamicRendererLinkedToDisplay(this.m_MainSlideViewer, this.m_MainSlideViewer.SlideDisplay); this.m_TransformableDynamicRenderer.Enabled = true; this.m_RealTimeStylus.SyncPluginCollection.Add(this.m_TransformableDynamicRenderer); // Don't dynamically render ink on the main slide viewer twice. The MainSlideViewer's RealTimeInkSheetRenderer's // own TransformableDynamicRenderer would render the ink on a low-priority asynchronous thread, which is // fine for secondary slide viewers and the FilmStrip, but not fine for the MainSlideViewer. using (Synchronizer.Lock(this.m_MainSlideViewer.SlideDisplay.SyncRoot)) { this.m_MainSlideViewer.SlideDisplay.RenderLocalRealTimeInk = false; } // Create an InkAnnotationCollector and wrap it in an InkSheetAdapter, // which sends ink from the RealTimeStylus to the RealTimeInkSheetModel // of the MainSlideViewer's current slide. this.m_InkAnnotationCollector = new InkAnnotationCollector(); this.m_InkAnnotationCollector_InkSheetAdapter = new InkSheetAdapter(this.m_MainSlideViewer.SlideDisplay, this.m_InkAnnotationCollector); this.m_RealTimeStylus.AsyncPluginCollection.Add(this.m_InkAnnotationCollector); this.m_LassoPlugin = new LassoPlugin(this.m_MainSlideViewer, this.m_MainSlideViewer.SlideDisplay); this.m_LassoPlugin_InkSheetAdapter = new InkSheetAdapter(this.m_MainSlideViewer.SlideDisplay, this.m_LassoPlugin); this.m_RealTimeStylus.SyncPluginCollection.Add(this.m_LassoPlugin); this.m_EraserPlugin = new EraserPlugin(this.m_MainSlideViewer.SlideDisplay); this.m_EraserPlugin_InkSheetAdapter = new InkSheetAdapter(this.m_MainSlideViewer.SlideDisplay, this.m_EraserPlugin); this.m_RealTimeStylus.SyncPluginCollection.Add(this.m_EraserPlugin); // Now that all the plugins have been added, enable the RealTimeStylus. this.m_RealTimeStylus.Enabled = true; #endregion RealTimeStylus Initialization // Create a DeckTraversalModelAdapter, which causes the MainSlideViewer to always display the // current slide of the current deck of the PresenterModel's current DeckTraversalModel. this.m_WorkspaceModelAdapter = new WorkspaceModelAdapter(this.m_MainSlideViewer.SlideDisplay.EventQueue, this.m_MainSlideViewer, this.m_Model); // Create the Slide Preview control this.m_SlidePreview = new SlidePreview(this.m_Model, this.m_DeckStripSplitter); this.m_PreviewTraversalModelAdapter = new PreviewTraversalModelAdapter(this.m_SlidePreview.m_EventQueue, this.m_SlidePreview.m_PreviewSlideViewer, this.m_Model); // Create the Second Monitor Form, this displays the slide on the secondary display this.m_SecondMonitorForm = new SecondMonitorForm(this.m_Model); this.ParentChanged += new EventHandler(OnParentChanged); // Create the Role Synchronizer for the MainSlideViewer this.m_RoleSync = new RoleSynchronizer(this.m_MainSlideViewer, this.m_Model.Participant); #region Add Controls // Add the SlidePreview Control this.Controls.Add(this.m_SlidePreview); // Now, add the controls in reverse order of their docking priority. // The MainSlideViewer gets added first so its Fill dock-style will be effective. this.Controls.Add(this.m_MainSlideViewer); // Next, dock the FilmStripSplitter and the FilmStrip in reverse order, // so that the FilmStripSplitter will be farther away from the edge of the container. this.Controls.Add(this.m_DeckStripSplitter); this.Controls.Add(this.m_DeckStrip); #endregion Add Controls }