How to display backspace, shift, etc symbols in onscreen keyboard in WPF - wpf

TL;DR;
1.In WPF how can I display key symbols (e.g. backspace, as well as custom symbols that I will invent) so that they seamlessly sit alongside letters and numbers on other keys?
2.How can I apply a glow effect to the text on these keys so that letters, numbers, and symbols (e.g. backspace) glow in the same way?
Longer version;
I am writing an onscreen keyboard in WPF using a Border for the outline of each key and a TextBlock to display the text, for example the 'A' key might be defined as;
<Border>
<Border.Tag>
<KeyValue Key="A" Function="{x:Null}" />
</Border.Tag>
<TextBlock Text="A" />
</Border>
A function key, such as backspace, might be;
<Border>
<Border.Tag>
<KeyValue Key="{x:Null}" Function="{x:Static Functions.Backspace}" />
</Border.Tag>
<TextBlock Text="BACKSPACE" />
</Border>
For special keys such as Return, Backspace, Shift, Caps Lock, etc, I would prefer to display a symbol, for example ⏎ rather than "Return"/"Enter". I also have custom keys which will need a custom character that does not exist in the unicode character list.
I found that Unicode includes definitions for the standard characters (check out the below link which is very useful if you don't scroll down too far and crash your browser);
http://unicode-table.com/en/search/?q=return
This gives me ⏎ = U+23CE or ⏎ for return, for example.
My issues:
I will be using a font which may not include these extended characters. This article suggests that only the core characters in unicode are covered by most fonts;
http://www.typography.com/faq/question.php?faqID=41
I want to use custom symbols (which I will invent) so unicode characters couldn't meet my requirements completely anyway.
I am not sure where to start if I go down the route of creating vector graphics for the symbols. They will need to support a glow animation which will occur on all keys (letters, numbers and symbols) and will be triggered when a key is 'pressed'. BitmapEffects was obsoleted after .Net 3.5 as it software rendered. The article below suggests using the DropShadowEffect - how should I create the symbols so that I can use the same approach for making the keys glow?
OuterGlowBitmapEffect Alternative Without BitmapEffects
Thanks for reading and for any help you offer.
Julius
EDITTED to include a clearer example of how key values are stored in the key Tags.

It depends how your handling the key press event.
if you are binding to a command then you can use the command parameter to control what the key value actually is and thus breaking it from what is displayed.
Alternatively, if doing this in an event handler - use a button property, such as Tag which you can inspect in your handler.
Then replace your text box button contents with something else that can represent your custom keys, an image would work - a path would be better since that will support the same effects applied to your text box.

For the visual stuff I would look at adding icon images.
<Geometry x:Key="appbar_user_path">
F1 M 24,12C 27.5,12 29,14 28.4952,18.1979C 28.9462,18.4566 29.25,18.9428 29.25,19.5C 29.25,20.1818 28.7951,20.7574 28.1723,20.9397C 27.9121,21.8672 27.508,22.6882 27,23.3449L 27,26.5C 28.6667,26.8333 30,27 32,28C 34,29 34.6667,29.9167 36,31.25L 36,36L 12,36L 12,31.25C 13.3333,29.9167 14,29 16,28C 18,27 19.3333,26.8333 21,26.5L 21,23.3449C 20.492,22.6882 20.0879,21.8672 19.8277,20.9397C 19.2049,20.7574 18.75,20.1818 18.75,19.5C 18.75,18.9428 19.0538,18.4566 19.5048,18.1979C 19,14 20.5,12 24,12 Z
</Geometry>
For the On-Screen-Keyboard, I think you'll want to dig into TextCompositionManager and Help with the WPF TextCompositionManager events
static void SendTextCompenstation( string key )
{
var textcomp = new TextComposition( InputManager.Current, UiControl, key );
TextCompositionManager.StartComposition( textcomp );
}

Related

WPF RichTextBox automatically merges two adjacent Runs

I have a RichTextBox containing two Runs:
<RichTextBox>
<RichTextBox.Document>
<FlowDocument>
<FlowDocument.Blocks>
<Paragraph Name="par">
<Run Text="First"/>
<Run Text="Second"/>
</Paragraph>
</FlowDocument.Blocks>
</FlowDocument>
</RichTextBox.Document>
</RichTextBox>
When I iterate through the Inlines of the par, I see three Runs: "First", " "(space) and "Second". It's ok. But if I delete second " " Run (using Backspace key, for example) and then iterate through the Inlines of the par, I see only one "FirstSecond" Run. RichTextBox merges two remaining Runs into single Run. However, if "First" and "Second" Runs have different TextFont or TextWeight values, RichTextBox won't merge them and I'll see two distinct Runs: "First" and "Second".
Now my question: How can I preserve adjacent Runs from being merged automatically by RichTextBox?
I would like to get the behaviour similar to the one when Runs have different TextFont or TextWeight values, but visually their formats should be equal. I've tried to set different Tag values for the different Runs, but it didn't help. Maybe, there is some "logical" format, that doesn't influence the appearance of the Runs, but warns RichTextBox to distinguish them.
Though I haven't found a clear solution, there is a workaround. Run has the Typography property, which, in its turn, has the Int32 AnnotationAlternates property. This property defines the fine tuning of the outlook for the specific characters of the specific fonts. If this property isn't used as intended, it can be used as a "logical" format for a Run. As written in MSDN:
If the value of AnnotationAlternates is greater than zero and the
selected font does not support annotation alternates, the default form
of the letter is displayed.
In my application I use Segoe UI font, which, as it turns out, doesn't support annotation alternates, so this workaround works for me. If you use font that supports annotation alternates, you can try to use rather big values of the AnnotationAlternates property, maybe, it won't influence the appearance of the text.

How to render whitespaces as dots in WPF RichTextBox?

I need the way to render regular space, nonbreaking space and some other formatting characters (like left-to-right mark) like MS Word renders them, when you choose to show non-printable characters.
I tried two approaches:
1) Replace characters with rarely used characters.
It works, but in this case we loose "nonbreaking" behavior of nonbreakable space (and LTR and RTL marks also stop working)
2) Use the custom font
It allows to preserve special behavior of nonbreaking space and LTR/RTL marks, but for some strange reason WPF renders nonbreaking space with usual space glyph.
WinForms RichTextBox renders text with the same font correctly.
This problem could be solved with applying different font with different space glyph for spaces and nonbreaking spaces, but LTR and RTL marks are not rendered at all even if I add glyph for them.
Have you any ideas how I could render that characters with visible glyph preserving their "LTR", "RTL", "nonbreaking" behavior?
I didn't try anything similar until now, but I can think of two options:
Warning -> I didn't try it out
The first method:
Create a subclass of UIElement
Get the Style with ControlTemplate for the Richtextbox and add it to App.xaml
Add an instance of your subclassed UIElement within the inner Panel of the Scrollviewer from the RichTextBox ControlTemplate
Make the RTBox available to a dependency property in your class via DataBinding in the ControlTemplate (if possible) or any other way that does the job
In your UIElement subclass, you iterate through characters of the document
Draw a symbol in your Adorner for each space and LineBreak you encounter
Get the Rect of a character at a specific position with the RichTextBox. Use this rect for placing the symbols.
The advantage of this Method is that you have a clean separation and don't need to subclass the RTFBox, but you won't be able manipulate the width of the spacing to make room for larger symbols. Also, other developers need to know that they need that Style in order to gain that functionality.
The second method:
Create a Custom Adorner
Decorate the RTBox with the custom Adorner
From the Adorner, you should be able to access the Child RTBox
In your UIElement subclass, you iterate through characters of the document
Draw a symbol in your UIElement for each space and LineBreak you encounter
I remember that there is a possibility to get the Rect of a character at a specific position with the RichTextBox. Use this rect for placing the symbols.
It's also without subclassing the RTBox. You also can't adjust the spacing. In contrast to method 1, other developers will immediatly recognize that this functionality has been added. The one disadvantage is that you will have to handle scrolling too.
You can try insert near LTR/RTL visible glyph instead of replace that.
Store all of the values as their special characters. It sounds like your printing functions need to handle a) what kind of output the user wants, b) interpret your data array/massive string of characters and spit out the values with regard to what the user wants to see. You don't give too many details on how your things are stored but this would be a very reasonable way to go about things.

Xlib: draw a text input box and read text as it is typed

I am trying to implement a text box where a user can type, use arrow keys, backspace, delete, etc. I would like to be able to know what is in this text box without the user needing to submit anything. I suppose I could catch keypress events, find a way to display a cursor, and basically build a min-text-editor by hand--but maybe that would be reinventing the wheel?
What I am after is rather scrabble-like. You have several letters in the top part of a window and a text box in the bottom. Each time you type a letter it disappears from the top pane so that you know when you've used them all up. I want to be able to edit that text with the arrow keys, 'cause rather than the 7 letters scrabble would give me I hope to be doing this with paragraphs.
I have the window displaying, and the source file processed and displayed as a list of allowable letters... I just want to update the list of allowable letters while the user types in their sentence. Can Xlib do this? Is there something else that might be more suitable? Thanks!
Can Xlib do this?Why yes, Xlib can do a lot of things. What you describe seems simple enough by using X's event processing and drawing functions.
Xlib is pretty crufty, though, and IMO you should only use it if you need closeness to the X protocol. (Even then there are newer replacements like XCB. But I digress.)
You might find it easier to work with a modern toolkit, like GTK+ or Qt.
For example, this might be expressed as a GtkEntry with a "key-press-event" handler.

How can we extract actual font family from a CompositeFontFamily applied to a run in WPF RichTextBox

A composite font family is a collection of FontFamilies. On applying the composite font to a run, appropriate font from its font-collection is applied depending on text.
How can we get which actual font is being used in a run on which a composite font has been applied?
EDIT2: Suppose I have a run
<Run Text="Some text with different unicode characters not available in applied FontFamily" FontFamily="Global User Interface"/>
Now if I check run.FontFamily it returns "Global User Interface", but actual font applied is one from the FontFamily collection of this composite font. So I want to find out which font it is?
EDIT1: One way I can think of is - to find it the way WPF applies a font. For each language, the composite font specifies a set of fonts corresponding to specified range of characters. So we can find each of the character in a run of text, then lookup the font corresponding to this character in the fontfamilymap for current language.
Is this the right way? Are there any cases where it may fail?
Is it the only way? Is there any API\straightforward way instead?
Thanks

Detect whether a font supports variants (like superscript and subscript)

WPF has the Typography.Variants attached property that lets you do superscript and subscript. However, it only works for some fonts. For other fonts, the variant is utterly ignored, and the text is shown normally. (Code sample and screenshot here)
Since it silently falls back to a no-op, I have no idea that anything went wrong; but my user will see lousy behavior.
Is there any way that I can programmatically detect whether a given font supports Typography.Variants? If so, I could provide more meaningful behavior if the user selected a non-variant-supporting font for something that needs superscripts/subscripts.
I looked at GlyphTypeface, since it's the one you use to query whether a font can be embedded, but I didn't see anything there about variants. I also didn't see anything obvious on FontFamily, and the only thing I could find on Typography was the Variants attached property itself (and its getters and setters).
As far as I can tell, WPF provides no information about the available GSUB tables (which tell you this information). Everything is hidden deep within private classes of PresentationCore.
One way would be to use the advanced text services of WPF to create a TextFormatter, and then retrieve the GlyphRuns created by a piece of text with the variants on, and one with the variants off, and then compare the glyph indexes used.
Another way would be to physically examine a font's data through GlyphTypeFace.GetFontStream(). The TrueType font format is not very complicated, so you'll probably find some information on the net on how to parse the binary font data to find information on the GSUB tables.
Note that simply asking wither a variant is supported is also a little ambiguous. A font can say it supports a variant, but nothing requires it to actually provide any meaningful substitutions. Most Adobe fonts provide only a few alphabetical lowercase characters for things like superscript and subscript (not even the entire Latin alphabet, mind you). Which is pretty useless, IMHO, since you can't ask WPF to fake subscripts or superscripts like Word and other word processors do.
Still, it would have been nice if you could simply ask TypeFace.GetSupportedOpenTypeFeatures().

Resources