Iniciar sesión

Ver la versión completa : [Cocoa]Observar la selección en un NSCollectionView



swapd0
24/04/2015, 14:59
Llevo varias horas con esto y no consigo que funcione.

A ver, tengo un NSCollectionView y lo relleno con varios objetos. Ademas tengo lo siguiente:


-(void)awakeFromNib
{
// los -1 es para que me envie de todo, ademas conecto todo esto para pillar algo, modo desesperado
[arrayController addObserver:self forKeyPath:@"selectionIndexes" options:-1 context:nil];
[arrayController addObserver:self forKeyPath:@"selectionIndex" options:-1 context:nil];
[arrayController addObserver:self forKeyPath:@"selection.name" options:-1 context:nil];
[arrayController addObserver:self forKeyPath:@"selection" options:-1 context:nil];
[arrayController addObserver:self forKeyPath:@"selectedObjects" options:-1 context:nil];

}


-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"observed change, path = %@, object = %@, change = %@", keyPath, object, change);
}



Cuando meto los elementos en el arrayController se llama al observador, no consigo hacer que no se llame pero bueno. Pero cuando selecciono los elementos del NSCollectionView no se llama al observador. ¿Que leches me falta?

He mirado en los foros y en todos pone ese código y parece que les funciona pero a mi no :(

^MiSaTo^
24/04/2015, 17:04
Pues como no pongas algo más de código va a ser dificil verlo.
¿Dónde estas añadiendo el observer? Supongo que tb habrás probado con más opciones no sólo con -1, ¿verdad?
¿Tienes algo más en el awakeFromNib? ¿No deberías llamar a super lo primero?

swapd0
24/04/2015, 17:26
El problema es que no hay mucho mas código.

Lo del -1 era por desesperacion, como el parámetro es una mascara de bits pues para ponerlos todos a 1.

Basicamente lo que tengo es:
-Una ventana con el NSCollectionView, con un array controller, la vista prototipo, etc.
-Una clase Drawing que tiene un nombre (NSString) y un "dibujo" (es un control que hereda del NSOpenGLView)

Funciona bien, cuando añado un elemento se añade al array, se actualiza el NSCollectionView y se llama al observador (aunque no me interesa que se llame al añadir elementos). Pero cuando selecciono un elemento que se supone que cambiara el objeto selectionIndexes y se llamara al observador, pero no hace nada. He probado enganchando el observador a distintas propiedades y hace lo mismo.

El observador esta enganchado al controlador de array que es de donde estan los objetos el NSCollectionView, he probado a ponerlo en el applicationDidFinishLaunching y no hay cambios.


-(void)awakeFromNib{
[arrayController addObserver:selfforKeyPath:@"selectionIndexes"options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOldcontext:nil];
}


-(void)observeValueForKeyPath: (NSString *)keyPath ofObject: (id)object change: (NSDictionary *)change context: (void *)context
{
NSLog(@"observed change, path = %@, object = %@, change = %@", keyPath, object, change);
}


- (void)applicationWillTerminate: (NSNotification *)aNotification
{
// Insert code here to tear down your application
[arrayControllerremoveObserver:selfforKeyPath:@"selectionIndexes"];
}


-(IBAction)newFontAction: (id)sender
{
char buffer[2];
for ( int i = 33; i < 127; ++i )
{
buffer[0] = (char)i;
buffer[1] = 0;
[arrayController addObject:[[Drawingalloc] initWithName:[NSStringstringWithUTF8String:buffer]]];
}
}


Lo que me fastidia es que esa solución es la que he visto por stackoverflow o por otros sitios y la gente dice que les funciona. O puede que digan eso para no seguir incordiando, no se.




Se me ha ocurrido usar un bind para conectar el los dibujos de cada elemento (Drawing) con el control para dibujar en openGL (uno separado que esta encima del NSCollectionView). Lo malo es que tendré que hacer el binding a mano y no con el IB.

swapd0
24/04/2015, 23:23
Jope que mierda. Si pongo esto en el applicationDidFinishLaunching y quito el addObserver.

[view bind:@"document" toObject:arrayController withKeyPath:@"selection" options:@{NSContinuouslyUpdatesValueBindingOption: @YES}];
Despues de ejecutar se llama al setDocument del view, ok, DPM, pero me llega un NSCollectionObjectProxy y no el objeto que contiene el arrayController (Drawing), si pongo como withKeyPath un selection.self, selection.representedObject u otra cosa similar no se llama al setDocument, y si pongo cualquier tontería como "aaa" lanza un error de que el objeto no es KVC-compilant para "aaa".

-----Actualizado-----

Hay algo mal en el NSCollectionView o en el NSArrayController porque si creo una etiqueta y le asigno en "Value" los siguientes parametros:
-Bind to : Array Controller
-Controller Key: selection
-Model Key Path: name (del objeto Drawing)

Cuando arranco la aplicación la etiqueta pone No Selection, cuando creo los dibujos sale con el nombre del ultimo dibujo creado, pero al hacer click en los distintos dibujos del NSCollectionView no cambia la etiqueta.

swapd0
25/04/2015, 15:33
Corregido.

Hay que hacer un bind del NSControllerView -> Selection Indexes desde el IB al arrayController.selectionIndexes

*****, la curva de aprendizaje del cocoa/osx hay dias que hace falta un piolet para subirla.

^MiSaTo^
25/04/2015, 15:57
Corregido.

Hay que hacer un bind del NSControllerView -> Selection Indexes desde el IB al arrayController.selectionIndexes

*****, la curva de aprendizaje del cocoa/osx hay dias que hace falta un piolet para subirla.

Acabo de ver el resto del hilo xD
De todos modos creo que deberías primero leerte tutoriales de Cocoa para lo básico y después ya ponerte a enredar con OpenGL y demás (que por cierto, para OpenGL no tienes ya la GLView?).

swapd0
25/04/2015, 18:20
Acabo de ver el resto del hilo xD
De todos modos creo que deberías primero leerte tutoriales de Cocoa para lo básico y después ya ponerte a enredar con OpenGL y demás (que por cierto, para OpenGL no tienes ya la GLView?).
Me he leído primero uno de Objective C 2.0, y he mirado un poco del cocoa y algunos videos, suficiente para trastear con los menus y el NSOutlineView pero con el NSCollectionView me he atascado. De todas formas tengo que repasar otra vez el Objective C porque hay cosas que no las tengo bien asimiladas y a ver si me leo alguno de los libros que tengo sobre el cocoa porque habia cosas que lo estaba haciendo mal.

Tengo hecho un scene graph en C++ y he creado un control que hereda del NSOpenGLView, mas que nada para pasarle un scene graph y que en el drawRect se encargue de dibujarlo. También captura los eventos del raton para seleccionar entidades (por hacer) y girar/mover la cámara.

^MiSaTo^
25/04/2015, 19:36
Pero es que SpriteKit ya te hace todo eso con la GLView ;) Por eso te lo decía.

swapd0
25/04/2015, 23:52
Es que estoy haciendo una aplicación, todo el código de librerías esta en C++ con dependencias con las STL y Boost, depues el entorno esta hecho con Cocoa.
He pensado en hacerlo con una librería portable (Qt, wxWidgets, etc) para el día que tenga que portarla a window o linux, pero despues de mucho pensar creo que mejor lo hago así porque me obliga a hacer el código mas independiente, ademas que cuando le coges el tranquillo se hacen cosas en un momento y en comparación con otros entornos se escribe muy poco código. También pensando en un futuro me sera mas fácil aprender iOS.