Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Surface Pen (tersedia untuk dibeli di Microsoft Store).
Ikhtisar
Optimalkan aplikasi Windows Anda untuk input pena guna menyediakan fungsionalitas perangkat pointer standar dan pengalaman Tinta Windows terbaik bagi pengguna Anda.
Nota
Topik ini berfokus pada platform Windows Ink. Untuk penanganan input pointer umum (mirip dengan mouse, sentuhan, dan touchpad), lihat Menangani input pointer.
Platform Windows Ink, bersama dengan perangkat pena, menyediakan cara alami untuk membuat catatan tulisan tangan digital, gambar, dan anotasi. Platform ini mendukung pengambilan input digitizer sebagai data tinta, menghasilkan data tinta, mengelola data tinta, merender data tinta sebagai goresan tinta pada perangkat output, dan mengonversi tinta menjadi teks melalui pengenalan tulisan tangan.
Selain menangkap posisi dasar dan pergerakan pena saat pengguna menulis atau menggambar, aplikasi Anda juga dapat melacak dan mengumpulkan berbagai jumlah tekanan yang digunakan selama stroke. Informasi ini, bersama dengan pengaturan untuk bentuk, ukuran, dan rotasi ujung pena, warna tinta, dan tujuan (tinta biasa, penghapusan, penyorotan, dan pemilihan), memungkinkan Anda untuk memberikan pengalaman pengguna yang sangat menyerupai tulisan atau gambar di kertas dengan pena, pensil, atau kuas.
Nota
Aplikasi Anda juga dapat mendukung input tinta dari perangkat berbasis pointer lainnya, termasuk digitizer sentuh dan perangkat mouse.
Platform tinta ini sangat fleksibel. Ini dirancang untuk mendukung berbagai tingkat fungsionalitas, tergantung pada kebutuhan Anda.
Untuk panduan Windows Ink UX, lihat kontrol Inking.
Komponen platform Tinta Windows
| Komponen | Deskripsi |
|---|---|
| InkCanvas | Kontrol UI XAML yang secara default menerima dan menampilkan semua input dari pena sebagai goresan tinta atau goresan penghapusan. Untuk informasi selengkapnya tentang cara menggunakan InkCanvas, lihat Mengenali goresan Tinta Windows sebagai teks dan Store dan mengambil data goresan Tinta Windows. |
| InkPresenter | Objek code-behind, dibuat bersama dengan kontrol InkCanvas (diekspos melalui properti InkCanvas.InkPresenter). Objek ini menyediakan semua fungsionalitas penintaan default yang diekspos oleh InkCanvas, bersama dengan sekumpulan API komprehensif untuk kustomisasi dan personalisasi tambahan. Untuk informasi selengkapnya tentang cara menggunakan InkPresenter, lihat Mengenali goresan Tinta Windows sebagai teks dan Menyimpan dan mengambil kembali data goresan Tinta Windows. |
| InkToolbar | Kontrol platform UI XAML yang berisi kumpulan tombol yang dapat disesuaikan dan dapat diperluas yang mengaktifkan fitur terkait tinta di InkCanvas terkait. Untuk informasi selengkapnya tentang cara menggunakan InkToolbar, lihat Tambahkan InkToolbar ke aplikasi penintaan aplikasi Windows. |
| IInkD2DRenderer | Memungkinkan penyajian goresan tinta ke konteks perangkat Direct2D yang ditunjuk dari aplikasi Universal Windows, alih-alih kontrol default InkCanvas. Ini memungkinkan penyesuaian penuh pengalaman penintaan. Untuk informasi selengkapnya, lihat sampel tinta Complex. |
Penintaan dasar dengan InkCanvas
Untuk menambahkan fungsionalitas penintaan dasar, cukup tempatkan InkCanvas kontrol platform UWP pada halaman yang sesuai di aplikasi Anda.
Secara default, InkCanvas mendukung input tinta hanya dari pena. Input dirender sebagai goresan tinta menggunakan pengaturan default untuk warna dan ketebalan (pena ballpoint hitam dengan ketebalan 2 piksel), atau diperlakukan sebagai penghapus goresan (ketika input berasal dari ujung penghapus atau ujung pena yang dimodifikasi dengan tombol hapus).
Nota
Apabila ujung atau tombol penghapus tidak ada, InkCanvas dapat dikonfigurasi untuk memproses input dari ujung pena sebagai gerakan menghapus.
Dalam contoh ini, InkCanvas melapisi gambar latar belakang.
Nota
InkCanvas memiliki properti Tinggi dan Lebar default nol, kecuali jika merupakan turunan dari elemen yang secara otomatis mengukur elemen turunannya, seperti kontrol StackPanel atau Grid .
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
<TextBlock x:Name="Header"
Text="Basic ink sample"
Style="{ThemeResource HeaderTextBlockStyle}"
Margin="10,0,0,0" />
</StackPanel>
<Grid Grid.Row="1">
<Image Source="Assets\StoreLogo.png" />
<InkCanvas x:Name="inkCanvas" />
</Grid>
</Grid>
Seri gambar ini menunjukkan bagaimana input pena dirender oleh kontrol InkCanvas ini.
|
|
|
|---|---|---|
| Kosong InkCanvas dengan gambar latar belakang. | InkCanvas yang memiliki goresan tinta. | InkCanvas memiliki satu coretan yang dihapus (perhatikan bagaimana penghapusan berlaku untuk seluruh coretan, bukan sebagian). |
Fungsionalitas penintaan yang didukung oleh kontrol InkCanvas disediakan oleh objek code-behind yang disebut InkPresenter.
Untuk penintaan dasar, Anda tidak perlu khawatir dengan InkPresenter. Namun, untuk menyesuaikan dan mengonfigurasi perilaku penintaan pada InkCanvas, Anda harus mengakses objek InkPresenter yang sesuai.
Kustomisasi dasar dengan InkPresenter
Objek InkPresenter dibuat dengan setiap InkCanvas kontrol.
Nota
InkPresenter tidak dapat dibuat secara langsung. Sebaliknya, ini diakses melalui InkPresenter dari properti InkCanvas.
Seiring dengan menyediakan semua perilaku penintaan default dari kontrol InkCanvas yang sesuai, InkPresenter menyediakan serangkaian API komprehensif untuk kustomisasi stroke tambahan dan manajemen input pena yang lebih halus (standar dan dimodifikasi). Ini termasuk properti stroke, jenis perangkat input yang didukung, dan apakah input diproses oleh objek atau diteruskan ke aplikasi untuk diproses.
Nota
Input tinta standar (dari ujung pena atau ujung/tombol penghapus) tidak dimodifikasi dengan penggunaan perangkat keras sekunder, seperti tombol pada batang pena, tombol mouse kanan, atau mekanisme serupa.
Secara default, tinta hanya didukung untuk input pena. Di sini, kami mengonfigurasi InkPresenter untuk menginterpretasikan data input dari pena dan mouse sebagai goresan tinta. Kami juga menetapkan beberapa atribut stroke tinta awal yang digunakan untuk merender goresan ke InkCanvas.
Untuk mengaktifkan penintaan mouse dan sentuhan, atur properti InputDeviceTypes dari InkPresenter ke kombinasi nilai CoreInputDeviceTypes yang Anda inginkan.
public MainPage()
{
this.InitializeComponent();
// Set supported inking device types.
inkCanvas.InkPresenter.InputDeviceTypes =
Windows.UI.Core.CoreInputDeviceTypes.Mouse |
Windows.UI.Core.CoreInputDeviceTypes.Pen;
// Set initial ink stroke attributes.
InkDrawingAttributes drawingAttributes = new InkDrawingAttributes();
drawingAttributes.Color = Windows.UI.Colors.Black;
drawingAttributes.IgnorePressure = false;
drawingAttributes.FitToCurve = true;
inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes);
}
Atribut goresan tinta dapat diatur secara dinamis untuk mengakomodasi preferensi pengguna atau persyaratan aplikasi.
Di sini, kami membiarkan pengguna memilih dari daftar warna tinta.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
<TextBlock x:Name="Header"
Text="Basic ink customization sample"
VerticalAlignment="Center"
Style="{ThemeResource HeaderTextBlockStyle}"
Margin="10,0,0,0" />
<TextBlock Text="Color:"
Style="{StaticResource SubheaderTextBlockStyle}"
VerticalAlignment="Center"
Margin="50,0,10,0"/>
<ComboBox x:Name="PenColor"
VerticalAlignment="Center"
SelectedIndex="0"
SelectionChanged="OnPenColorChanged">
<ComboBoxItem Content="Black"/>
<ComboBoxItem Content="Red"/>
</ComboBox>
</StackPanel>
<Grid Grid.Row="1">
<Image Source="Assets\StoreLogo.png" />
<InkCanvas x:Name="inkCanvas" />
</Grid>
</Grid>
Kami kemudian menangani perubahan pada warna yang dipilih dan memperbarui atribut goresan tinta yang sesuai.
// Update ink stroke color for new strokes.
private void OnPenColorChanged(object sender, SelectionChangedEventArgs e)
{
if (inkCanvas != null)
{
InkDrawingAttributes drawingAttributes =
inkCanvas.InkPresenter.CopyDefaultDrawingAttributes();
string value = ((ComboBoxItem)PenColor.SelectedItem).Content.ToString();
switch (value)
{
case "Black":
drawingAttributes.Color = Windows.UI.Colors.Black;
break;
case "Red":
drawingAttributes.Color = Windows.UI.Colors.Red;
break;
default:
drawingAttributes.Color = Windows.UI.Colors.Black;
break;
};
inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes);
}
}
Gambar-gambar ini menunjukkan bagaimana input pena diproses dan disesuaikan oleh InkPresenter.
InkCanvas dengan goresan tinta hitam bawaan.
InkCanvas dengan goresan tinta merah yang dipilih pengguna.
Untuk menyediakan fungsionalitas di luar penintaan dan penghapusan, seperti pemilihan goresan, aplikasi Anda harus mengidentifikasi input tertentu agar InkPresenter dapat melewati proses yang tidak diolah untuk penanganan oleh aplikasi Anda.
Input dilewatkan langsung untuk pemrosesan tingkat lanjut
Secara bawaan, InkPresenter memproses semua input sebagai goresan tinta atau goresan penghapus, termasuk input yang dimodifikasi oleh perangkat keras sekunder seperti tombol mouse kanan, tombol barrel pena, atau sejenisnya. Namun, pengguna biasanya mengharapkan beberapa fungsionalitas tambahan atau perilaku yang dimodifikasi dengan kelengkapan sekunder ini.
Dalam beberapa kasus, Anda mungkin juga perlu mengekspos fungsionalitas tambahan untuk pena tanpa fitur tambahan sekunder (fungsi yang biasanya tidak berhubungan dengan ujung pena), jenis perangkat input lainnya, atau modifikasi perilaku tertentu berdasarkan pilihan pengguna di UI aplikasi Anda.
Untuk mendukung hal ini, InkPresenter dapat dikonfigurasi untuk membiarkan input tertentu tidak diolah. Input yang tidak diproses ini kemudian diteruskan ke aplikasi Anda untuk diproses.
Contoh - Gunakan data yang tidak diolah untuk menerapkan pemilihan stroke
Platform Windows Ink tidak menyediakan dukungan bawaan untuk tindakan yang memerlukan input yang dimodifikasi, seperti pemilihan goresan. Untuk mendukung fitur seperti ini, Anda harus menyediakan solusi kustom di aplikasi Anda.
Contoh kode berikut (semua kode ada di file MainPage.xaml dan MainPage.xaml.cs) melalui cara mengaktifkan pemilihan goresan saat input dimodifikasi dengan tombol barel pena (atau tombol mouse kanan).
Pertama, kami menyiapkan UI di MainPage.xaml.
Di sini, kami menambahkan kanvas (di bawah InkCanvas) untuk menggambar goresan pilihan. Menggunakan lapisan terpisah untuk menggambar goresan pemilihan menyebabkan InkCanvas dan kontennya tetap tidak tersentuh.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0"> <TextBlock x:Name="Header" Text="Advanced ink customization sample" VerticalAlignment="Center" Style="{ThemeResource HeaderTextBlockStyle}" Margin="10,0,0,0" /> </StackPanel> <Grid Grid.Row="1"> <!-- Canvas for displaying selection UI. --> <Canvas x:Name="selectionCanvas"/> <!-- Inking area --> <InkCanvas x:Name="inkCanvas"/> </Grid> </Grid>Dalam MainPage.xaml.cs, kami mendeklarasikan beberapa variabel global untuk menyimpan referensi ke aspek UI pemilihan. Secara khusus, garis lasso pilihan dan persegi panjang pembatas yang menyoroti garis yang dipilih.
// Stroke selection tool. private Polyline lasso; // Stroke selection area. private Rect boundingRect;Selanjutnya, kami mengonfigurasi InkPresenter untuk menginterpretasikan data input dari pena dan mouse sebagai goresan tinta, dan atur beberapa atribut stroke tinta awal yang digunakan untuk merender goresan ke InkCanvas.
Yang terpenting, kami menggunakan properti InputProcessingConfiguration dari InkPresenter untuk menunjukkan bahwa input yang dimodifikasi harus diproses oleh aplikasi. Input yang dimodifikasi ditentukan dengan menetapkan InputProcessingConfiguration.RightDragAction nilai InkInputRightDragAction.LeaveUnprocessed. Ketika nilai ini diatur, InkPresenter meneruskan ke kelas InkUnprocessedInput , serangkaian peristiwa pointer untuk Anda tangani.
Kami menetapkan pendengar untuk peristiwa PointerPressed, PointerMoved, dan PointerReleased yang tidak diproses oleh InkPresenter. Semua fungsionalitas pemilihan diimplementasikan dalam handler untuk event ini.
Akhirnya, kami menetapkan pendengar untuk peristiwa StrokeStarted dan StrokesErased dari InkPresenter. Kami menggunakan handler untuk peristiwa ini untuk membersihkan UI pemilihan jika stroke baru dimulai atau stroke yang ada dihapus.
public MainPage() { this.InitializeComponent(); // Set supported inking device types. inkCanvas.InkPresenter.InputDeviceTypes = Windows.UI.Core.CoreInputDeviceTypes.Mouse | Windows.UI.Core.CoreInputDeviceTypes.Pen; // Set initial ink stroke attributes. InkDrawingAttributes drawingAttributes = new InkDrawingAttributes(); drawingAttributes.Color = Windows.UI.Colors.Black; drawingAttributes.IgnorePressure = false; drawingAttributes.FitToCurve = true; inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes); // By default, the InkPresenter processes input modified by // a secondary affordance (pen barrel button, right mouse // button, or similar) as ink. // To pass through modified input to the app for custom processing // on the app UI thread instead of the background ink thread, set // InputProcessingConfiguration.RightDragAction to LeaveUnprocessed. inkCanvas.InkPresenter.InputProcessingConfiguration.RightDragAction = InkInputRightDragAction.LeaveUnprocessed; // Listen for unprocessed pointer events from modified input. // The input is used to provide selection functionality. inkCanvas.InkPresenter.UnprocessedInput.PointerPressed += UnprocessedInput_PointerPressed; inkCanvas.InkPresenter.UnprocessedInput.PointerMoved += UnprocessedInput_PointerMoved; inkCanvas.InkPresenter.UnprocessedInput.PointerReleased += UnprocessedInput_PointerReleased; // Listen for new ink or erase strokes to clean up selection UI. inkCanvas.InkPresenter.StrokeInput.StrokeStarted += StrokeInput_StrokeStarted; inkCanvas.InkPresenter.StrokesErased += InkPresenter_StrokesErased; }Kami kemudian menentukan handler untuk peristiwa PointerPressed, PointerMoved, dan PointerReleased yang tidak diolah yang diteruskan oleh InkPresenter.
Semua fungsionalitas pemilihan diimplementasikan dalam handler ini, termasuk garis lasso dan kotak pembatas.
// Handle unprocessed pointer events from modified input. // The input is used to provide selection functionality. // Selection UI is drawn on a canvas under the InkCanvas. private void UnprocessedInput_PointerPressed( InkUnprocessedInput sender, PointerEventArgs args) { // Initialize a selection lasso. lasso = new Polyline() { Stroke = new SolidColorBrush(Windows.UI.Colors.Blue), StrokeThickness = 1, StrokeDashArray = new DoubleCollection() { 5, 2 }, }; lasso.Points.Add(args.CurrentPoint.RawPosition); selectionCanvas.Children.Add(lasso); } private void UnprocessedInput_PointerMoved( InkUnprocessedInput sender, PointerEventArgs args) { // Add a point to the lasso Polyline object. lasso.Points.Add(args.CurrentPoint.RawPosition); } private void UnprocessedInput_PointerReleased( InkUnprocessedInput sender, PointerEventArgs args) { // Add the final point to the Polyline object and // select strokes within the lasso area. // Draw a bounding box on the selection canvas // around the selected ink strokes. lasso.Points.Add(args.CurrentPoint.RawPosition); boundingRect = inkCanvas.InkPresenter.StrokeContainer.SelectWithPolyLine( lasso.Points); DrawBoundingRect(); }Untuk menyimpulkan penanganan aktivitas PointerReleased, kami membersihkan lapisan pemilihan semua konten (goresan lasso) dan kemudian menggambar persegi panjang pembatas tunggal di sekitar goresan tinta yang dicakup oleh area lasso.
// Draw a bounding rectangle, on the selection canvas, encompassing // all ink strokes within the lasso area. private void DrawBoundingRect() { // Clear all existing content from the selection canvas. selectionCanvas.Children.Clear(); // Draw a bounding rectangle only if there are ink strokes // within the lasso area. if (!((boundingRect.Width == 0) || (boundingRect.Height == 0) || boundingRect.IsEmpty)) { var rectangle = new Rectangle() { Stroke = new SolidColorBrush(Windows.UI.Colors.Blue), StrokeThickness = 1, StrokeDashArray = new DoubleCollection() { 5, 2 }, Width = boundingRect.Width, Height = boundingRect.Height }; Canvas.SetLeft(rectangle, boundingRect.X); Canvas.SetTop(rectangle, boundingRect.Y); selectionCanvas.Children.Add(rectangle); } }Terakhir, kami mendefinisikan handler untuk peristiwa StrokeStarted dan StrokesErased InkPresenter.
Keduanya hanya memanggil fungsi pembersihan yang sama untuk menghapus pilihan saat ini setiap kali stroke baru terdeteksi.
// Handle new ink or erase strokes to clean up selection UI. private void StrokeInput_StrokeStarted( InkStrokeInput sender, Windows.UI.Core.PointerEventArgs args) { ClearSelection(); } private void InkPresenter_StrokesErased( InkPresenter sender, InkStrokesErasedEventArgs args) { ClearSelection(); }Berikut adalah fungsi untuk menghapus semua UI pilihan dari kanvas pilihan ketika stroke baru dimulai atau stroke yang ada dihapus.
// Clean up selection UI. private void ClearSelection() { var strokes = inkCanvas.InkPresenter.StrokeContainer.GetStrokes(); foreach (var stroke in strokes) { stroke.Selected = false; } ClearDrawnBoundingRect(); } private void ClearDrawnBoundingRect() { if (selectionCanvas.Children.Any()) { selectionCanvas.Children.Clear(); boundingRect = Rect.Empty; } }
Penyajian tinta kustom
Secara bawaan, input tinta diproses pada utas latar belakang berlatensi rendah dan dirender sedang diproses, atau "basah," disebut saat digambar. Ketika goresan selesai (pena atau jari diangkat, atau tombol mouse dilepaskan), goresan diproses pada utas UI dan dirender "kering" ke lapisan InkCanvas (di atas konten aplikasi dan mengganti tinta basah).
Anda dapat mengambil alih perilaku default ini dan sepenuhnya mengontrol pengalaman penintaan dengan "pengeringan kustom" goresan tinta basah. Meskipun perilaku default biasanya cukup untuk sebagian besar aplikasi, ada beberapa kasus di mana pengeringan kustom mungkin diperlukan, ini termasuk:
- Manajemen yang lebih efisien untuk kumpulan goresan tinta yang besar atau kompleks.
- Dukungan panning dan zooming yang lebih efisien pada kanvas tinta besar
- Menggabungkan tinta dan objek lainnya, seperti bentuk atau teks, sambil mempertahankan urutan lapisan (z-order)
- Mengeringkan dan mengonversi tinta secara sinkron menjadi bentuk DirectX (misalnya, garis lurus atau bentuk yang dirasterisasi dan diintegrasikan ke dalam konten aplikasi alih-alih sebagai lapisan InkCanvas terpisah).
Pengeringan kustom memerlukan objek IInkD2DRenderer untuk mengelola input tinta dan merendernya ke konteks perangkat Direct2D dari aplikasi Universal Windows Anda, alih-alih kontrol InkCanvas default.
Dengan memanggil ActivateCustomDrying (sebelum InkCanvas dimuat), aplikasi membuat InkSynchronizer objek untuk menyesuaikan bagaimana goresan tinta dirender kering ke SurfaceImageSource atau VirtualSurfaceImageSource.
Baik SurfaceImageSource dan VirtualSurfaceImageSource menyediakan permukaan bersama DirectX untuk memungkinkan aplikasi Anda menggambar dan menyusun kontennya, meskipun VSIS menyediakan permukaan virtual yang lebih besar dibandingkan layar untuk pengguliran dan memperbesar tampilan yang efektif. Karena pembaruan visual pada permukaan ini disinkronkan dengan utas UI XAML, saat tinta dicetak pada salah satunya, tinta yang masih basah dapat dihapus dari InkCanvas secara bersamaan.
Anda juga dapat menyesuaikan pengeringan tinta pada SwapChainPanel, tetapi sinkronisasi dengan thread UI tidak terjamin dan mungkin ada penundaan antara saat tinta dirender ke SwapChainPanel Anda dan saat tinta dihapus dari InkCanvas.
Untuk contoh lengkap fungsionalitas ini, lihat sampel tinta Complex.
Nota
Pengeringan khusus dan InkToolbar
Jika aplikasi Anda mengambil alih perilaku penyajian tinta default InkPresenter dengan implementasi pengeringan kustom, goresan tinta yang dirender tidak lagi tersedia untuk InkToolbar dan perintah penghapusan bawaan InkToolbar tidak berfungsi seperti yang diharapkan. Untuk menyediakan fungsionalitas penghapusan, Anda harus menangani semua peristiwa penunjuk, melakukan pengujian hit pada setiap goresan, dan mengambil alih perintah "Hapus semua tinta" bawaan.
Artikel lain di bagian ini
| Topik | Deskripsi |
|---|---|
| Mengenali goresan tinta | Konversi goresan tinta menjadi teks menggunakan pengenalan tulisan tangan, atau ke bentuk menggunakan pengenalan kustom. |
| Menyimpan dan mengambil goresan tinta | Simpan data goresan tinta dalam file Graphics Interchange Format (GIF) menggunakan metadata Embedded Ink Serialized Format (ISF). |
| Tambahkan InkToolbar ke aplikasi penintaan Windows | Tambahkan InkToolbar default ke aplikasi penintaan aplikasi Windows, tambahkan tombol pena kustom ke InkToolbar, dan ikat tombol pena kustom ke definisi pena kustom. |
Artikel terkait
- Mulai: Mendukung tinta di aplikasi Windows Anda
- Menangani input pointer
- Mengidentifikasi perangkat input
- Spesifikasi Format Serial Tinta (ISF).
Antarmuka Pemrograman Aplikasi (API)
Samples
- Tutorial Memulai: Mendukung tinta di aplikasi Windows Anda
- Sampel tinta Simple (C#/C++)
- Sampel tinta kompleks (C++)
- Sampel Ink (JavaScript)
- Buku mewarnai sampel
- sampel catatan keluarga
input dasar - Sampel input latensi rendah
- sampel mode interaksi Pengguna
- Sampel visual fokus