mercoledì 29 ottobre 2014

Drag & Drop da programmi esterni

Oggi affrontiamo un caso alquanto complesso, cioè come importare o esportare dati di qualsiasi tipo (testo, immagini, suoni, ecc.), semplicemente trascinando l'icona rappresentativa dentro o fuori il nostro programma in livecode. Questa operazione la facciamo tutti i giorni quando copiamo o spostiamo i file, e in gergo si chiama Drag and drop.
 Al contrario di quello che abbiamo visto in questo post, nel caso di oggi ci dobbiamo interfacciare con altri programmi, non scritti da noi, o con il sistema operativo stesso.
Il drag and drop può essere suddiviso in due tipi di operazioni diverse: i dati entrano nel nostro programma oppure i dati escono dal nostro programma.

Dati in entrata

Ora esaminiamo il caso che i dati entrino nel nostro programma, per esempio l'utente trascina un'icona del desktop di un'immagine per importarla nel nostro programma.
L'oggetto che contiene il codice per l'importazione può essere qualsiasi cosa a parte una card o uno stack; questo ci permette di definire quali parti della finestra del nostro programma possano importare dati dall'esterno. Potremmo scegliere un elemento rettangolare opaco, come il seguente:

A questo punto dobbiamo capire cosa fare con i dati importati: se vogliamo importare un'immagine, dobbiamo controllare che ci sia un'immagine; se vogliamo importare dei testi, dobbiamo controllare che ci siano dei testi; se vogliamo importare altri tipi di file, basterà implementare dei controlli sul nome del file o sul percorso.
Quando l'utente prova a trascinare un'icona dentro al nostro programma, attiva il messaggio DragEnter. Questo messaggio ci può essere utile per fare dei controlli e impostare il tipo di azione che vogliamo imporre. Quando l'utente usa il drag end drop abbiamo il simbolo dell'icona che cambia a seconda del tipo di DragAction vogliamo fare: move, copy, link, none.
nonemovecopylink
Se impostiamo come DragAction l'azione none, rifiutiamo il drag and drop e appare l'icona del divieto. Il drag and drop quindi non avverrà.
Nell'esempio che analizzeremo, cercheremo di importare le immagini, anche più d'una alla volta.
Prima di tutto controlliamo che i dati siano delle immagini nel messaggio DragEnter:

on dragEnter
   if "image" is in keys(the dragData) or "files" is in keys(the dragData) then
      set the foregroundcolor of the target to "green"
      set the dragAction to "copy"
   else
      set the dragAction to "none"
   end if
end dragEnter

on dragLeave
  set the foreGroundColor of the target to empty
end dragLeave


Abbiamo imposto che se l'insieme dei dati che trasciniamo col mouse contiene delle immagini, allora si prosegue, il quadrato che ha il codice per importare diventerà col bordo verde. Inoltre se il mouse abbandona il quadrato senza rilasciare i dati, il quadrato ritorna nero (messaggio dragLeave).
L'analisi dei dati trasportati avviene controllando dragData, questo speciale contenitore di dati è un array che può contenere varie voci:
  • text:  se i dati contengono del testo
  • html: contiene i testi formattati come html
  • rtf: contiene il testo in fromato RTF  The styled text being dragged, in the same format as the RTFText
  • unicode:  testo formato unicode
  • image: i dati dell'immagine (JPEG, GIF, BMP)
  • files: percorso completo dei file, comprensivi del nome, uno per riga.
  • styles: testo con la formattazione Livecoe
  • private: un sistema interno che potete impostare voi, valido solo fra applicazioni Livecode.
generalmente se trasciniamo l'icona dal desktop, abbiamo il percorso del file (files) non l'immagine.

Ora dobbiamo mettere il codice per far apparire le immagini dentro al programma, quando l'utente rilascia le icone nella zona corretta; ecco il codice:

on dragDrop
   put "gif,jpg,bmp" into immagini   
   if "files" is in keys(the dragData) then
      # è una lista di immagini
      repeat for each line theLine in the dragData["files"]
         set itemdel to "."
         put the last item of theLine into testfile
         set itemdel to ","
         if lower(testfile) is among the items of immagini then         
            import paint from file theLine      
         end if
      end repeat
   else
      #è un'immagine portata da un programma
      create image
      put the dragData["image"] into last image
   end if
   set the foreGroundColor of the target to empty
end dragDrop


Come vedete anche qui ho messo un piccolo controllo per vedere se le immagini sono proprio immagini, basandomi semplicemente sull'estensione.
Se tutto è stato fatto a dovere, otterrete una cosa del genere:

Dati in uscita

Per i dati in uscita basta usare il messaggio DragStart, ad esempio per un campo di testo potete mettere:

on dragStart
    set the dragData to the selectedText of me
end dragStart