Esempio di raccolta di inchiostro RealTimeStylus
Questa applicazione illustra la raccolta e il rendering dell'inchiostro quando si usa la classe RealTimeStylus.
Progetto InkCollection
Questo esempio è costituito da una singola soluzione che contiene un progetto, InkCollection. L'applicazione definisce lo spazio dei nomi InkCollection
che contiene una singola classe, denominata anche InkCollection
. La classe eredita dalla classe Form e implementa l'interfaccia IStylusAsyncPlugin.
namespace InkCollection
{
public class InkCollection : Form, IStylusAsyncPlugin
{
//...
La classe InkCollection definisce un set di costanti private utilizzate per specificare vari spessori di inchiostro. La classe dichiara anche istanze private della classe RealTimeStylus, myRealTimeStylus
, la classe DynamicRenderer, myDynamicRenderer
e il renderer classe myRenderer
. Il DynamicRenderer esegue il rendering del Stroke attualmente raccolto. L'oggetto Renderer, myRenderer
, esegue il rendering degli oggetti Stroke già raccolti.
private const float ThinInkWidth = 10;
private const float MediumInkWidth = 100;
private const float ThickInkWidth = 200;
private RealTimeStylus myRealTimeStylus;
private DynamicRenderer myDynamicRenderer;
private Renderer myRenderer;
La classe dichiara inoltre un oggetto hashtable, myPackets
, utilizzato per archiviare i dati di pacchetto raccolti da uno o più oggetti Cursor. I valori di StylusID vengono usati come chiave di tabella hash per identificare in modo univoco i dati del pacchetto raccolti per un determinato oggetto Cursor.
Un'istanza privata dell'oggetto Ink , myInk
, archivia gli oggetti Stroke raccolti da myRealTimeStylus
.
private Hashtable myPackets;
private Ink myInk;
Evento di caricamento del modulo
Nell'gestore eventi Load per il form myDynamicRenderer
viene creata un'istanza utilizzando il DynamicRenderer che accetta un controllo come argomento e myRenderer
viene costruito con un costruttore senza argomenti.
private void InkCollection_Load(object sender, System.EventArgs e)
{
myDynamicRenderer = new DynamicRenderer(this);
myRenderer = new Renderer();
// ...
Prestare attenzione al commento che segue la creazione delle istanze dei renderer, perché myDynamicRenderer
usa i valori predefiniti per DrawingAttributes durante il rendering dell'inchiostro. Si tratta di un comportamento standard. Tuttavia, se si desidera dare all'inchiostro reso da myDynamicRenderer
un aspetto diverso da quello reso da myRenderer
, è possibile modificare la proprietà DrawingAttributes su myDynamicRenderer
. A tale scopo, rimuovere il commento dalle righe seguenti prima di compilare ed eseguire l'applicazione.
// myDynamicRenderer.DrawingAttributes.PenTip = PenTip.Rectangle;
// myDynamicRenderer.DrawingAttributes.Height = (.5F)*MediumInkWidth;
// myDynamicRenderer.DrawingAttributes.Transparency = 128;
Successivamente, l'applicazione crea l'oggetto RealTimeStylus usato per ricevere notifiche di stilo e aggiunge l'oggetto DynamicRenderer alla coda di notifica del plug-in sincrono. In particolare, myRealTimeStylus
aggiunge myDynamicRenderer
alla proprietà SyncPluginCollection.
myRealTimeStylus = new RealTimeStylus(this, true);
myRealTimeStylus.SyncPluginCollection.Add(myDynamicRenderer);
Il modulo viene quindi aggiunto alla coda asincrona di notifica del plug-in. In particolare, InkCollection
viene aggiunto alla proprietà AsyncPluginCollection. Infine, myRealTimeStylus
e myDynamicRenderer
sono abilitati e myPackets e myInk sono istanziati.
myRealTimeStylus.AsyncPluginCollection.Add(this);
myRealTimeStylus.Enabled = true;
myDynamicRenderer.Enabled = true;
myPackets = new Hashtable();
myInk = new Ink();
}
Oltre ad associare i gestori di menu per modificare il colore e le dimensioni dell'inchiostro, è necessario un ulteriore blocco di codice breve prima di implementare l'interfaccia. L'esempio deve gestire l'evento Paint del form. Nel gestore eventi, l'applicazione deve aggiornare myDynamicRenderer
perché è possibile che un oggetto Stroke venga raccolto quando si verifica l'evento Paint. In tal caso, la parte dell'oggetto Stroke già raccolta deve essere ridisegnata. Il renderer statico viene utilizzato per disegnare nuovamente oggetti Stroke già raccolti. Questi tratti si trovano nell'oggetto inchiostro perché vengono posizionati lì quando vengono disegnati, come illustrato nella sezione successiva.
private void InkCollection_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
myDynamicRenderer.Refresh();
myRenderer.Draw(e.Graphics, myInk.Strokes);
}
Implementazione dell'interfaccia IStylusAsyncPlugin
L'applicazione di esempio definisce i tipi di notifiche che ha interesse a ricevere nell'implementazione della proprietà DataInterest. La proprietà DataInterest definisce quindi le notifiche che l'oggetto RealTimeStylus inoltra al modulo. Per questo esempio, la proprietà DataInterest definisce l'interesse per le notifiche StylusDown, Packets, StylusUp, e Error tramite l'enumerazione DataInterestMask.
public DataInterestMask DataInterest
{
get
{
return DataInterestMask.StylusDown |
DataInterestMask.Packets |
DataInterestMask.StylusUp |
DataInterestMask.Error;
}
}
La notifica StylusDown si verifica quando la penna tocca la superficie del digitalizzatore. In questo caso, l'esempio alloca una matrice usata per archiviare i dati del pacchetto per l'oggetto dello stilo. Il StylusDownData dal metodo StylusDown viene aggiunto all'array e l'array viene inserito nella tabella hash utilizzando la proprietà Id dell'oggetto Stylus come chiave.
public void StylusDown(RealTimeStylus sender, StylusDownData data)
{
ArrayList collectedPackets = new ArrayList();
collectedPackets.AddRange(data.GetData());
myPackets.Add(data.Stylus.Id, collectedPackets);
}
La notifica pacchetti si verifica quando la penna si muove sulla superficie del digitalizzatore. In questo caso, l'applicazione aggiunge nuovi StylusDownData nell'array di pacchetti per l'oggetto Stylus . A tale scopo, viene usata la proprietà id dell'oggetto Stylus come chiave per recuperare la matrice di pacchetti per lo stilo dalla tabella hash. I nuovi dati del pacchetto vengono quindi inseriti nella matrice recuperata.
public void Packets(RealTimeStylus sender, PacketsData data)
{
((ArrayList)(myPackets[data.Stylus.Id])).AddRange(data.GetData());
}
La notifica StylusUp si verifica quando la penna lascia la superficie del digitalizzatore. Quando si verifica questa notifica, l'esempio recupera dalla tabella hash l'array di pacchetti relativo a questo oggetto Stylus, rimuovendolo poiché non è più necessario, aggiunge i nuovi dati del pacchetto e utilizza l'array di dati del pacchetto per creare un nuovo oggetto Stroke, stroke
.
public void StylusUp(RealTimeStylus sender, StylusUpData data)
{
ArrayList collectedPackets = (ArrayList)myPackets[data.Stylus.Id];
myPackets.Remove(data.Stylus.Id);
collectedPackets.AddRange(data.GetData());
int[] packets = (int[])(collectedPackets.ToArray(typeof(int)));
TabletPropertyDescriptionCollection tabletProperties =
myRealTimeStylus.GetTabletPropertyDescriptionCollection(data.Stylus.TabletContextId);
Stroke stroke = myInk.CreateStroke(packets, tabletProperties);
if (stroke != null)
{
stroke.DrawingAttributes.Color = myDynamicRenderer.DrawingAttributes.Color;
stroke.DrawingAttributes.Width = myDynamicRenderer.DrawingAttributes.Width;
}
}
Per un esempio che mostra un uso più affidabile della classeRealTimeStylus, incluso l'uso della creazione di plug-in personalizzati, vedere Esempio di plug-in RealTimeStylus.
Argomenti correlati