public static Message ForSheet(SheetModel sheet, SheetCollection collection) { if (sheet is ImageSheetModel) { //If it's an instructor note, return null. if (sheet.Disposition == SheetDisposition.Instructor) return null; else return new ImageSheetMessage((ImageSheetModel)sheet, collection); } if(sheet is RealTimeInkSheetModel) return new RealTimeInkSheetInformationMessage((RealTimeInkSheetModel) sheet, collection); if(sheet is InkSheetModel) return new InkSheetInformationMessage((InkSheetModel) sheet, collection); if(sheet is TextSheetModel) return new TextSheetMessage((TextSheetModel) sheet, collection); if( sheet is QuickPollSheetModel ) { Message poll; using( Synchronizer.Lock( sheet.SyncRoot ) ) { poll = new QuickPollInformationMessage( ((QuickPollSheetModel)sheet).QuickPoll ); } poll.InsertChild( new QuickPollSheetMessage( (QuickPollSheetModel)sheet, collection ) ); return poll; } throw new ArgumentException("Unknown sheet type: " + sheet.GetType().ToString()); }
/// <summary> /// Performs a deep copy of the given SheetModel and resets the disposition to remote. /// This seems to be a little more complicated than it needs to be because the disposition is read only. /// If the given sheetmodel is an InkSheet or an editable sheet, it is copied, otherwise, it returns itself. /// </summary> /// <param name="s">The SheetModel to copy</param> /// <returns>A deep copy of an InkSheet or an Editable Sheet, otherwise, itself</returns> public static SheetModel SheetDeepRemoteCopyHelper(SheetModel s) { using (Synchronizer.Lock(s.SyncRoot)) { SheetModel t = null; // Only copy InkSheetModels if (s is InkSheetModel || s is EditableSheetModel) { if (s is RealTimeInkSheetModel) { // Make a deep copy of the SheetModel t = new RealTimeInkSheetModel(Guid.NewGuid(), s.Disposition | SheetDisposition.Remote, s.Bounds, ((RealTimeInkSheetModel)s).Ink.Clone()); using (Synchronizer.Lock(t.SyncRoot)) { ((RealTimeInkSheetModel)t).CurrentDrawingAttributes = ((RealTimeInkSheetModel)s).CurrentDrawingAttributes; } } else if (s is InkSheetModel) { // Make a deep copy of the SheetModel t = new InkSheetModel(Guid.NewGuid(), s.Disposition | SheetDisposition.Remote, s.Bounds, ((InkSheetModel)s).Ink.Clone()); } else if (s is EditableSheetModel) { t = (EditableSheetModel)((EditableSheetModel)s).CloneToRemote(); } // This is a new object so add it to the local references // TODO CMPRINCE: Make this a callback or something UW.ClassroomPresenter.Network.Messages.Message.AddLocalRef(t.Id, t); return(t); } } return(s); }
/// <summary> /// Adds the sheets to the SheetCollection such /// that ink is always on top of text which is always on top of images /// </summary> /// <param name="value"></param> /// <returns></returns> public void Add(SheetModel value) { if (List.Count == 0) { List.Add(value); } else { int i = 0; SheetModel sheet = (SheetModel)List[i]; while (sheet.CompareTo(value) < 1) { i++; if (i < List.Count) { sheet = (SheetModel)List[i]; } else { break; } } List.Insert(i, value); } }
/// <summary> /// Performs a deep copy of the given SheetModel. /// If the given sheetmodel is an InkSheet or an editable sheet, it is copied, otherwise, it returns itself. /// </summary> /// <param name="s">The SheetModel to copy</param> /// <returns>A deep copy of an InkSheet or an Editable Sheet, otherwise, itself</returns> public static SheetModel SheetDeepCopyHelper(SheetModel s) { using (Synchronizer.Lock(s.SyncRoot)) { SheetModel t = null; // Only copy InkSheetModels if (s is InkSheetModel || s is EditableSheetModel) { if (s is RealTimeInkSheetModel) { // Make a deep copy of the SheetModel // t = new RealTimeInkSheetModel(Guid.NewGuid(), SheetDisposition.All, s.Bounds, ((RealTimeInkSheetModel)s).Ink.Clone()); t = new RealTimeInkSheetModel(Guid.NewGuid(), s.Disposition, s.Bounds, ((RealTimeInkSheetModel)s).Ink.Clone()); using (Synchronizer.Lock(t.SyncRoot)) { ((RealTimeInkSheetModel)t).CurrentDrawingAttributes = ((RealTimeInkSheetModel)s).CurrentDrawingAttributes; } } else if (s is InkSheetModel) { // Make a deep copy of the SheetModel t = new InkSheetModel(Guid.NewGuid(), s.Disposition, s.Bounds, ((InkSheetModel)s).Ink.Clone()); } else if (s is EditableSheetModel) { t = (EditableSheetModel)((EditableSheetModel)s).Clone(); } // This is a new object so add it to the local references // TODO CMPRINCE: Make this a callback or something UW.ClassroomPresenter.Network.Messages.Message.AddLocalRef(t.Id, t); return t; } } return s; }
public SSSheetNetworkService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector) { this.m_Sender = sender; this.m_Presentation = presentation; this.m_Deck = deck; this.m_Slide = slide; this.m_Sheet = sheet; this.m_Selector = selector; }
/// <summary> /// Construct the sheet model /// </summary> /// <param name="sender">The event queue for async event handling</param> /// <param name="srcSheet">The source sheet model</param> /// <param name="dstSheet">The destination sheet model</param> /// <param name="selector">Unknown</param> public SheetMatch( EventQueue sender, SheetModel srcSheet, SheetModel dstSheet/*, SheetMessage.SheetCollection selector*/ ) { this.m_Sender = sender; this.m_SourceSheet = srcSheet; this.m_DestSheet = dstSheet; this.m_BoundsChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleBoundsChanged)); this.m_SourceSheet.Changed["Bounds"].Add(this.m_BoundsChangedDispatcher.Dispatcher); }
protected SheetUndoService(UndoModel undo, DeckModel deck, SlideModel slide, SheetModel sheet) { this.m_Undo = undo; this.m_Deck = deck; this.m_Slide = slide; this.m_Sheet = sheet; this.m_Sheet.Changed["Bounds"].Add(new PropertyEventHandler(this.HandleSheetChanged)); }
public SheetMessage(SheetModel sheet, SheetCollection collection) : base(sheet.Id) { this.AddLocalRef( sheet ); this.Disposition = sheet.Disposition; this.SheetCollectionSelector = collection; using(Synchronizer.Lock(sheet.SyncRoot)) { this.Bounds = sheet.Bounds; } this.Height = sheet.Height; }
/// <summary> /// Construct a listener for a generic sheet /// </summary> /// <param name="sender">The event queue</param> /// <param name="presentation">The presentation</param> /// <param name="deck">The deck</param> /// <param name="slide">The slide</param> /// <param name="sheet">The sheet</param> /// <param name="selector">The collection that this is part of</param> public SheetWebService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector) { this.m_Sender = sender; this.m_Presentation = presentation; this.m_Deck = deck; this.m_Slide = slide; this.m_Sheet = sheet; this.m_Selector = selector; // this.m_BoundsChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleBoundsChanged)); // this.m_Sheet.Changed["Bounds"].Add(this.m_BoundsChangedDispatcher.Dispatcher); }
/// <summary> /// Construct the InkSheetWebService, this class listens for strokes to finish /// and sends them across the network /// </summary> /// <param name="sender">The queue to use</param> /// <param name="presentation">The presentation model</param> /// <param name="deck">The deck model</param> /// <param name="slide">The slide model</param> /// <param name="sheet">The sheet model</param> /// <param name="selector">The sheet collection we are part of</param> public InkSheetWebService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector) : base(sender, presentation, deck, slide, sheet, selector) { // Keep track of our sheet this.m_Sheet = (InkSheetModel)sheet; // Get the slide ID using (Synchronizer.Lock(slide.SyncRoot)) { m_SlideID = slide.Id; } // Set Events this.m_Sheet.InkAdded += new StrokesEventHandler(this.HandleInkAdded); // this.m_Sheet.InkDeleting += new StrokesEventHandler(this.HandleInkDeleting); }
public static SheetRenderer ForStaticSheet( SlideDisplayModel display, SheetModel sheet ) { // TODO: Make this pluggable by dynamically loading available renderers, mapped by the types they support. if(sheet is InkSheetModel) { return new InkSheetRenderer(display, (InkSheetModel) sheet); } else if(sheet is ImageSheetModel) { return new ImageSheetRenderer(display, (ImageSheetModel) sheet); } else if(sheet is TextSheetModel) { return new TextSheetRenderer(display, (TextSheetModel) sheet); } else if( sheet is QuickPollSheetModel ) { return new QuickPollSheetRenderer( display, (QuickPollSheetModel)sheet ); } else { return null; } }
public static SheetMatch ForSheet(EventQueue sender, SheetModel src, SheetModel dst ) { // FIXME: Create SheetNetworkService classes for sheets other than InkSheetModels. if(src is RealTimeInkSheetModel) { return new RealTimeInkSheetMatch(sender, (RealTimeInkSheetModel)src, (RealTimeInkSheetModel)dst); } else if(src is InkSheetModel) { return new InkSheetMatch(sender, (InkSheetModel)src, (InkSheetModel)dst); } else if(src is ImageSheetModel) { return null; } else if(src is TextSheetModel) { return null; } else if( src is QuickPollSheetModel ) { return null; } else { return null; } }
public PresentItBox(SheetModel sheet, MainSlideViewer viewer) { InitializeComponent(); slide_display_ = viewer.SlideDisplay; slide_ = viewer.Slide; viewer_ = viewer; sheet_ = sheet; ///add event listeners ///we need to change how we transform our textbox every time the slidedisplay transform changes. pixel_transform_listener_ = new EventQueue.PropertyEventDispatcher(slide_display_.EventQueue, new PropertyEventHandler(this.HandleTransformChanged)); ///add the dispatcher, not the actual method we want to execute slide_display_.Changed["PixelTransform"].Add(pixel_transform_listener_.Dispatcher); ///set the location and size of our controls relative to the slide by ///using the sheet information. using (Synchronizer.Lock(sheet_.SyncRoot)) { slide_coordinates_ = new Point(sheet.Bounds.Location.X, sheet.Bounds.Location.Y); slide_size_ = sheet.Bounds.Size; } }
/// <summary> /// Construct the appropriate sheet web service /// </summary> /// <param name="sender">The queue</param> /// <param name="presentation">The presentation</param> /// <param name="deck">The deck</param> /// <param name="slide">The slide</param> /// <param name="sheet">The sheet</param> /// <param name="selector">The sheet collection type</param> /// <returns>A sheet web service appropriate for the sheet model</returns> public static SheetWebService ForSheet(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector) { if (sheet is InkSheetModel) { return new InkSheetWebService( sender, presentation, deck, slide, sheet, selector ); } else { return new SheetWebService( sender, presentation, deck, slide, sheet, selector ); } }
private bool isBackgroundSheet(SheetModel sm) { using(Synchronizer.Lock(sm.SyncRoot)) { return ((sm.Disposition & SheetDisposition.Background) != 0); } }
private bool determineIfDisplay(SheetModel sm) { using(Synchronizer.Lock(this.m_SlideDisplay.SyncRoot)) { using(Synchronizer.Lock(sm.SyncRoot)) { return ((sm.Disposition & this.m_SlideDisplay.SheetDisposition) != 0); } } }
/// <summary> /// Performs a deep copy of the given SheetModel. /// If the given sheetmodel is not an InkSheet, then returns itself. /// </summary> /// <param name="s">The SheetModel to copy</param> /// <returns>The given sheetmodel if not an InkSheetModel, otherwise a deep copy of the InkSheetModel</returns> protected SheetModel InkSheetDeepCopyHelper( SheetModel s ) { using( Synchronizer.Lock( s.SyncRoot ) ) { InkSheetModel t; // Only copy InkSheetModels if( s is InkSheetModel ) { if( s is RealTimeInkSheetModel ) { // Make a deep copy of the SheetModel t = new RealTimeInkSheetModel( Guid.NewGuid(), s.Disposition | SheetDisposition.Remote, s.Bounds, ((RealTimeInkSheetModel)s).Ink.Clone() ); using( Synchronizer.Lock( t.SyncRoot ) ) { ((RealTimeInkSheetModel)t).CurrentDrawingAttributes = ((RealTimeInkSheetModel)s).CurrentDrawingAttributes; } } else { // Make a deep copy of the SheetModel t = new InkSheetModel( Guid.NewGuid(), s.Disposition, s.Bounds, ((InkSheetModel)s).Ink.Clone() ); } // This is a new object so add it to the local references Message.AddLocalRef(t.Id, t); return t; } } return s; }
public void SendSheetInformation( SheetModel sheet, SheetMessage.SheetCollection selector, Group receivers ) { // TODO: Also pass the index so the sheet can be inserted into the correct index on the remote side. Message message, deck, slide; message = new PresentationInformationMessage( this.m_Presentation ); message.Group = receivers; message.InsertChild( deck = new DeckInformationMessage( this.m_Deck ) ); deck.InsertChild( slide = new SlideInformationMessage( this.m_Slide ) ); Message sm = SheetMessage.RemoteForSheet(sheet, selector); //if sm is null that means that the sheet is an instructor note and shouldn't be sent. if (sm != null) { slide.InsertChild(sm); } using( Synchronizer.Lock( this.m_Slide.SyncRoot ) ) { message.Tags = new MessageTags(); message.Tags.SlideID = this.m_Slide.Id; } if (sheet is ImageSheetModel && ((ImageSheetModel)sheet).Image != null) { using (Synchronizer.Lock(sheet.SyncRoot)) { this.m_Sender.Send( message ); } } else this.m_Sender.Send(message); }
public bool Contains(SheetModel value) { return List.Contains(value); }
/// <summary> /// To move a sheet to the top, all we need to do is remove and add it. /// this is due to the virtue of the Add method, which inserts a sheet /// in the frontmost position of its allowed ordering, based on the indexing /// heirarchy. /// </summary> /// <param name="value"></param> public void MoveToTop(SheetModel value) { List.Remove(value); this.Add(value); }
/// <summary> /// Adds the sheets to the SheetCollection such /// that ink is always on top of text which is always on top of images /// </summary> /// <param name="value"></param> /// <returns></returns> public void Add(SheetModel value) { if (List.Count == 0) { List.Add(value); } else { int i = 0; SheetModel sheet = (SheetModel)List[i]; while (sheet.CompareTo(value) < 1) { i++; if (i < List.Count) sheet = (SheetModel)List[i]; else break; } List.Insert(i, value); } }
public void Remove(SheetModel value) { List.Remove(value); }
public int IndexOf(SheetModel value) { return(List.IndexOf(value)); }
public int IndexOf(SheetModel value) { return List.IndexOf(value); }
public void Insert(int index, SheetModel value) { List.Insert(index, value); }
protected SheetRenderer(SlideDisplayModel display, SheetModel sheet) { this.m_SlideDisplay = display; this.m_Sheet = sheet; }
public static Message RemoteForSheet( SheetModel sheet, SheetCollection collection) { SheetModel newModel = null; if( sheet is ImageSheetModel ) newModel = sheet; else if( sheet is RealTimeInkSheetModel ) { using( Synchronizer.Lock( sheet.SyncRoot ) ) { newModel = new RealTimeInkSheetModel( sheet.Id, sheet.Disposition | SheetDisposition.Remote, sheet.Bounds ); using( Synchronizer.Lock( newModel.SyncRoot ) ) ((RealTimeInkSheetModel)newModel).CurrentDrawingAttributes = ((RealTimeInkSheetModel)sheet).CurrentDrawingAttributes; } } else if( sheet is InkSheetModel ) newModel = sheet; else if( sheet is TextSheetModel ) newModel = sheet; else if( sheet is QuickPollSheetModel ) newModel = sheet; return SheetMessage.ForSheet( newModel, collection ); }
protected Guid SendStudentSubmission() { Guid newSlideGuid = Guid.Empty; UW.ClassroomPresenter.Network.Messages.Message pres, deck, slide, sheet; // Add the presentation if( this.Presentation == null ) return Guid.Empty; pres = new PresentationInformationMessage( this.Presentation ); pres.Group = Groups.Group.Submissions; //Add the current deck model that corresponds to this slide deck at the remote location deck = new DeckInformationMessage( this.Deck ); deck.Group = Groups.Group.Submissions; pres.InsertChild( deck ); // Add the Slide Message newSlideGuid = Guid.NewGuid(); slide = new StudentSubmissionSlideInformationMessage( this.Slide, newSlideGuid, Guid.NewGuid() ); slide.Group = Groups.Group.Submissions; deck.InsertChild( slide ); // Find the correct user ink layer to send RealTimeInkSheetModel m_Sheet = null; using( Synchronizer.Lock( this.Slide.SyncRoot ) ) { foreach( SheetModel s in this.Slide.AnnotationSheets ) { if( s is RealTimeInkSheetModel && (s.Disposition & SheetDisposition.Remote) == 0 ) { m_Sheet = (RealTimeInkSheetModel)s; break; } } } // Find the existing ink on the slide Microsoft.Ink.Ink extracted; using( Synchronizer.Lock( m_Sheet.Ink.Strokes.SyncRoot ) ) { // Ensure that each stroke has a Guid which will uniquely identify it on the remote side foreach( Microsoft.Ink.Stroke stroke in m_Sheet.Ink.Strokes ) { if( !stroke.ExtendedProperties.DoesPropertyExist( InkSheetMessage.StrokeIdExtendedProperty ) ) stroke.ExtendedProperties.Add( InkSheetMessage.StrokeIdExtendedProperty, Guid.NewGuid().ToString() ); } // Extract all of the strokes extracted = m_Sheet.Ink.ExtractStrokes( m_Sheet.Ink.Strokes, Microsoft.Ink.ExtractFlags.CopyFromOriginal ); } // Find the Realtime ink on the slide RealTimeInkSheetModel newSheet = null; using( Synchronizer.Lock( m_Sheet.SyncRoot ) ) { newSheet = new RealTimeInkSheetModel( Guid.NewGuid(), m_Sheet.Disposition | SheetDisposition.Remote, m_Sheet.Bounds ); using( Synchronizer.Lock( newSheet.SyncRoot ) ) { newSheet.CurrentDrawingAttributes = m_Sheet.CurrentDrawingAttributes; } } // Add the Sheet Message for the existing sheet = new InkSheetStrokesAddedMessage( newSheet, (Guid)slide.TargetId, SheetMessage.SheetCollection.AnnotationSheets, extracted ); sheet.Group = Groups.Group.Submissions; slide.InsertChild( sheet ); // Add the Sheet Message for the real-time ink sheet = SheetMessage.ForSheet( newSheet, SheetMessage.SheetCollection.AnnotationSheets ); sheet.Group = Groups.Group.Submissions; slide.AddOldestPredecessor( sheet ); // Send the message this.m_Sender.Send( pres ); return newSlideGuid; }
public static SheetNetworkService ForSheet(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector) { if(sheet is RealTimeInkSheetModel) { return new RealTimeInkSheetNetworkService(sender, presentation, deck, slide, ((RealTimeInkSheetModel) sheet), selector); } else if(sheet is InkSheetModel) { return new InkSheetNetworkService(sender, presentation, deck, slide, ((InkSheetModel) sheet), selector); } else if(sheet is ImageSheetModel) { return new ImageSheetNetworkService(sender, presentation, deck, slide, ((ImageSheetModel)sheet), selector); } else if(sheet is TextSheetModel) { return new TextSheetNetworkService(sender, presentation, deck, slide, ((TextSheetModel)sheet), selector); } else if(sheet is QuickPollSheetModel) { return new QuickPollSheetNetworkService( sender, presentation, deck, slide, ((QuickPollSheetModel)sheet), selector ); } else { return null; } }
public bool Contains(SheetModel value) { return(List.Contains(value)); }
public SheetRemovedMessage(SheetModel sheet, SheetCollection collection) : base(sheet, collection) { }