Sto cercando di fare una finestra personalizzata che sarebbe simile a questa (non importa il photoshop rapida):Come creare una finestra trasparente con pulsanti non rettangolari?
alt text http://i35.tinypic.com/20ff803.png
Il problema principale che ho è di non rendere la finestra trasparente (anche se immagino qualsiasi informazioni sono benvenute!), ma che voglio poter fare clic solo sulla parte visibile dei pulsanti. Ad esempio, se clicco appena fuori dalla parte superiore sinistra del pulsante "5", voglio che registri un clic sul pulsante "1" e non sul pulsante "5", anche se ho fatto clic sul riquadro di selezione del pulsante 5. E se clicco sul lato "angolo" in alto a sinistra del pulsante "1", voglio che faccia clic su ciò che è sotto la mia finestra e non sul pulsante. Devo anche essere in grado di ridimensionare questa finestra e le immagini nei pulsanti dovrebbero essere ridimensionate con esse.
Stavo pensando di utilizzare un NSWindow trasparente con NSButtons trasparenti contenenti PNG con alfa per ciascun pulsante ma penso che i pulsanti sovrapposti costituiranno un problema.
Ho anche sentito parlare di applicazioni come Bowtie, SweetFM e altri che utilizzano WebKit per visualizzare le loro interfacce. Se questa è una possibilità su almeno 10.3 sarebbe interessante, ma non so come funzionerebbe.
Ho cercato maschere, aree o qualcosa del genere, ma non ho ancora trovato nulla. Aggiornerò questo post come trovo più informazioni (se lo faccio!).
Eventuali suggerimenti su come procedere?
(Si noti che sto lavorando su 10.4 e idealmente ho bisogno di sostenere alcune vecchie versioni di Mac OS X anche.)
(Inoltre, ho trovato il "arrotondata finestra" esempio sui dev di Apple. Sito ma non funziona più su 10.4 quindi non sono sicuro che questa sia la strada da percorrere.)
Grazie in anticipo!
UPDATE:
(vedi aggiornamento 2, questo problema è stato risolto ora)
OK ora sto avendo un problema leggermente diverso (ma non indipendente). Quello che ho fatto finora è questo:
ho optato per fare un controllo personalizzato che sarò in grado di utilizzare per ciascuno dei miei pulsanti:
1- sottoclasse NSControl e sovrascrivere drawRect, mouseUp, mouseDragged e mouseDown . In questo modo posso ottenere il comportamento desiderato durante il trascinamento di un pulsante (sposta la finestra).
2- Caricare le immagini per ciascuno stato del pulsante (stessa forma ma una è scurita) in NSImages e disegnarle nella vista utilizzando compositeToPoint:fromRect:operation:
quando necessario. Le immagini sono 185 x 185 pixel file PNG con alpha esportati da Photoshop.
3- Diventa rappresentazione bitmap del NSImage:
NSBitmapImageRep *bitRep = [[NSBitmapImageRep imageRepWithData:[unpressedImage TIFFRepresentation]] retain];
O
NSBitmapImageRep *bitRep = [[unpressedImage representations] objectAtIndex:0];
Entrambi sembrano dare lo stesso risultato. Ho provato a comporre questo rep bitmap sulla mia finestra per vedere se l'immagine ha le stesse dimensioni e l'aspetto dell'originale e tutto sembra buono (vedrai perché l'ho fatto dopo questa enumerazione ...).
4- Nei metodi di eventi del mouse, io uso la rappresentazione bitmap per ottenere il componente alfa per un particolare punto:
NSPoint mouse = [self convertPoint:[theEvent locationInWindow] fromView:nil]; // Returns the correct x and y positions on the control (i.e: between 0 and 185 for each axis).
NSColor *colorUnderMouse = [[[unpressedImage representations] objectAtIndex:0] colorAtX:mouse.x y:mouse.y];
float alpha = [colorUnderMouse alphaComponent];
Poi stampare il valore alfa per la console, ma sto ottenendo risultati molto strani . Ottenere il componente alfa e il colore sotto il mouse sembra funzionare a prima vista (i colori e l'alfa restituiti si trovano nella mia bitmap) ma sembra che il colore non sia preso al punto giusto nello bitRep
, o l'immagine contenuta nel bitRep
è distorto (non è distorto quando compongo lo bitRep
sulla finestra, il che è molto strano). Ancora una volta ho ricontrollato che le coordinate xey del mouse erano comprese nell'intervallo (0,185) e che la dimensione dello NSBitmapImageRep
è 185 x 185.
Prima sembra che lo NSBitmapImageRep
sia ruotato orizzontalmente rispetto al mio NSImage
. Se capovolgo le mie coordinate i valori restituiti sembrano in gran parte OK (la maggior parte della forma sembra adattarsi ai valori restituiti) ma ci sono ancora parti dell'immagine che restituiscono valori errati.
Sono incompetente a questo punto e non ho mai lavorato con NSBitmapImageRep
prima forse mi sono semplicemente dimenticato di specificare alcune informazioni di formato sulla mia immagine che sarebbero il motivo per cui i valori sono disattivati. Qualcuno potrebbe chiarirlo per favore?
Grazie ancora!
UPDATE 2:
Ok non importa, ho trovato il problema. Ho usato il metodo setColor: atX: y: per disegnare un punto colorato sul bitRep prima di stamparlo sulla mia finestra e il problema era chiaro come giorno: la coordinata Y è invertita nel bitRep, ma l'immagine è stampata con il "orientamento. Ciò significa che il bitRep ha un sistema di coordinate dell'origine in alto a sinistra "stile Windows" mentre la finestra ha l'origine del sistema di coordinate cartesiane (in basso a sinistra). Semplicemente invertendo la mia coordinata Y ho risolto i problemi con cui avevo ottenuto il componente alfa e il colore.
Questo deve essere stato scritto da qualche parte nei documenti, mi dispiace di averti disturbato a causa della mia mancanza di ricerca ...!
Grazie, sarebbe una possibilità per il pulsante centrale, ma con i pulsanti esterni sarebbe più difficile e richiedere un sacco di codice di controllo dei limiti ... cosa succede se cambio le posizioni del mio pulsante per qualche motivo?(questo non è un progetto personale, quindi questo potrebbe essere soggetto a cambiamenti, purtroppo) Quindi dovrei riscrivere la maggior parte del mio codice di controllo vincolante ... Ci sarebbe un modo per farlo con una sorta di maschera? Dite "lascia passare il clic se la bitmap è trasparente a questo punto"? – Form
Non penso che tu possa farlo con una maschera come stai pensando (rilevamento della trasparenza, ecc.). Queste sono forme piuttosto semplici (cerchi parziali per i pulsanti esterni sotto un cerchio completo per l'interno). Puoi accedere alle coordinate e alle dimensioni correnti dei controlli nel codice e utilizzarli per calcolare i limiti di hit in modo da non dover codificare nulla. Usa il fatto che il pulsante centrale è in alto a tuo vantaggio. –
È possibile utilizzare il rilevamento trasparenza (alfa) e funziona molto bene e anche se il metodo che sto usando per ora è 10.4+ c'è un modo per farlo usando qualcos'altro che colorAtX: y: finché si ha accesso al bitmapRep, come ha sottolineato Mahboudz. – Form