Wpf and emoticons

How to display emoticons/emoji in a Wpf TextBox/TextBlock?

I made a test project to show how to do this (you can download it at the end of this post).
It is all about playing with Inlines in the TextBox’s FlowDocument and in the TextBlock.
The main code is this:

private static int FindFirstEmoticon(string text, int startIndex, out string emoticonFound)
{
  InitEmoticons();
  emoticonFound = string.Empty;
  int minIndex = -1;
  foreach (string e in m_Emoticons.Keys) {
    int index = text.IndexOf(e, startIndex);
    if (index >= 0) {
      if (minIndex < 0 || index < minIndex) {
        minIndex = index;
        emoticonFound = e;
      }
    }
  }
  return minIndex;
} // FindFirstEmoticon

public static void ParseText(FrameworkElement element)
{
  InitEmoticons();
  TextBlock textBlock = null;
  RichTextBox textBox = element as RichTextBox;
  if (textBox == null)
    textBlock = element as TextBlock;

  if (textBox == null && textBlock == null)
    return;

  if (textBox != null){
    FlowDocument doc = textBox.Document;
    for (int blockIndex=0; blockIndex < doc.Blocks.Count; blockIndex++){
      Block b = doc.Blocks.ElementAt(blockIndex);
      Paragraph p = b as Paragraph;
      if (p != null) {          
        ProcessInlines(textBox, p.Inlines);
      }
    }
  }else{
    ProcessInlines(null, textBlock.Inlines);
  }
} // ParseText

private static void ProcessInlines(RichTextBox textBox, InlineCollection inlines)
{
  for (int inlineIndex=0; inlineIndex < inlines.Count; inlineIndex++){
    Inline i = inlines.ElementAt(inlineIndex);
    if (i is Run) {
      Run r = i as Run;
      string text = r.Text;
      string emoticonFound = string.Empty;
      int index = FindFirstEmoticon(text, 0, out emoticonFound);
      if (index >= 0) {
        TextPointer tp = i.ContentStart;
        bool reposition = false;                
        while (!tp.GetTextInRun(LogicalDirection.Forward).StartsWith(emoticonFound)) 
          tp = tp.GetNextInsertionPosition(LogicalDirection.Forward);
        TextPointer end = tp;
        for (int j=0; j<emoticonFound.Length; j++)
          end = end.GetNextInsertionPosition(LogicalDirection.Forward);
        TextRange tr = new TextRange(tp, end);
        if (textBox != null)
          reposition = textBox.CaretPosition.CompareTo(tr.End) == 0;
        tr.Text = string.Empty;

        string imageFile = m_Emoticons[emoticonFound];
        Image image = new Image();
        BitmapImage bimg = new BitmapImage();
        bimg.BeginInit();
        bimg.UriSource = new Uri(imageFile, UriKind.Relative);
        bimg.EndInit();
        image.Source = bimg;
        image.Width = 24;

        InlineUIContainer iui = new InlineUIContainer(image, tp);
        iui.BaselineAlignment = BaselineAlignment.TextBottom;

        if (textBox != null && reposition)
          textBox.CaretPosition = tp.GetNextInsertionPosition(LogicalDirection.Forward);
      }
    }
  }
} // ProcessInlines

The code parses the current content of the TextBox/TextBlock and replaces the emoticons text (initialized int the InitEmoticons method) with the correct image.
If the element passed is a TextBox it also repositions the cursor in the correct position.

You can download the test project here.

WhatsApp su Windows?

E’ possibile utilizzare WhatsApp su pc Windows?
Per ora sembra di no a meno di non emulare un intero sistema Android.
Esiste però una libreria ben fatta e stabile scritta in Python che permette di interfacciarsi col servizio di messaggistica di WhatsApp.
La libreria si chiama Yowsup ed è utilizzata da Wazapp (un client WhatsApp per Nokia N9).

Ho provato quindi ad utilizzare la libreria scrivendo una interfaccia grafica in WPF.
E’ venuta bene?

Forse lo rilascerò (cambiandogli nome ed icona, ovviamente) una volta testato per bene. 😉

Acer: l’assistenza che funziona

Recentemente ho avuto un problema col mio Acer Iconia Tab A500.
Il tablet non si accendeva più entrando subito in modalitò APX (e cercando di ripristinarne il software facendo un full reflash mi sono convinto che si sia danneggiata la NAND perché il processo falliva al partizionamento dello spazio).
Visto che era ancora in garanzia mi sono rivolto all’assistenza Acer Italia, convinto di dover aspettare un mesetto prima di riavere il mio tablet riparato.

Invece, fortunatamente, non è andata così! 🙂
Il tutto è stato risolto in dieci giorni dalla mia prima email di segnalazione all’arrivo del tablet riparato.

L’assistenza Acer si è rivelata rapida ed efficiente.
Ecco il semplice processo che mi ha portato a riavere l’A500 riparato e perfettamente funzionante:

  • Contatto l’assistenza tramite il portale segnalando il mio problema
  • Ricevo in risposta una etichetta UPS da stampare per spedire il tablet (ovviamente a spese loro)
  • Chiamo UPS e prenoto il ritiro del pacco (eseguito lo stesso giorno)
  • La mattina successiva il tablet è già al centro assistenza
  • Due giorni dopo ricevo l’email che il mio tablet è in riparazione
  • Poche ore dopo mi viene comunicato che i tablet è stato riparato (sostituita mainboard) ed è pronto per la spedizione
  • Il giorno dopo è stato spedito
  • Non trovandomi a casa all’ora della consegna ho richiesto ad UPS un cambio di indirizzo per la consegna
  • La mattina dopo avevo tra le mani il table riparato.

Complimenti Acer (ed anche a UPS perché il cambio di indirizzo l’ho fatto alle ore 21 e il mattino seguente verso le 10 il pacco era stato già consegnato al nuovo indirizzo), ottima assistenza.

Rilasciato Lone Wolf per Maemo5

Dopo lungo tempo dal primo post, ieri ho rilasciato Lone Wolf per Maemo5 (Nokia N900).
Il progetto partecipa alla “2012 Coding Competition” organizzata da maemo.org

Fino ad ora ho preparato i primi quattro libri della serie, ma sono a buon punto anche con il quinto, che rilascerò a breve (tempo permettendo).

Il programma può essere installato dal repository extra-devel, oppure potete scaricare direttamenbte il file deb da qui.

Ecco alcuni screenshots aggiornati alla versione attuale:

I risultati della competizione dovrebbero essere resi noti entro l’11 settembre.
Lone Wolf meriterà un premio? 🙂