Speciální případy tahání či házení - MujMAC.cz - Apple, Mac OS X, Apple iPod

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Seriály

Více seriálů



Software

Speciální případy tahání či házení

16. ledna 2007, 14.00 | Dnes se seznámíme s některými speciálními případy, v nichž by bylo z různých důvodů buď nemožné, nebo přinejmenším nepraktické používat nízkoúrovňovou podporu, s níž jsme pracovali dosud.

V minulých dílech našeho seriálu, ve kterém se věnujeme programování ve standardním vývojovém prostředí Mac OS X Cocoa, jsme se zabývali programováním našich vlastních views; konkrétně jsme se učili implementovat v nich tažení objektů pomocí myši. Naučili jsme se zajistit tažení jak z pohledu zdroje, jehož objekty myší "vytáhneme", tak i z pohledu view cílového, do nějž tažené objekty vhodíme.

Dnes se seznámíme s některými speciálními případy, v nichž by bylo z různých důvodů buď nemožné, nebo přinejmenším nepraktické používat nízkoúrovňovou podporu, se kterou jsme pracovali dosud.

Služby vyšší úrovně

Mnohé třídy z knihoven Cocoa nabízejí samy podporu tažení a vhazování na daleko vyšší úrovni (a tedy mnohem pohodlnější), než je ta, s níž jsme se dosud seznámili. Snad nejčistším příkladem zde může být třída NSImageView: stačí nastavit příznak, že lze její obsah měnit – to můžeme pomocí standardní zprávy setEditable:YES, nebo dokonce přímo v Interface Builderu:

a hned bude možné do objektu vhazovat obrázky.

Podobně je tomu s na služby velmi bohatou třídou NSTextView: opět, určíme-li, že obsah objektu je editovatelný, můžeme jej bez další námahy využívat jako zdroj i jako cíl tažení textových dat.

Tabulky a "outlines"

Za samostatnou zmínku určitě stojí třída NSTableView a její dědic NSOutlineView. Ty sice nejsou na tak vysoké úrovni, aby mohly podporovat drag&drop bez implementace jakýchkoli metod, jen na základě nastavení nějakého přepínače (jako tomu je u textu či NSImageView), ale přesto nabízejí podporu pro tažení na poměrně vysoké úrovni. Pojďme si ukázat, jak nám mohou služby těchto tříd usnadnit práci.

Chceme-li umožnit tažení zvolených objektů z tabulky (nebo outline view), není zapotřebí se starat o kompletní protokol NSDraggingSource; namísto toho postačí pouze implementovat v jejím datovém zdroji jednu jedinou metodu tableView:writeRowsWithIndexes:toPasteboard:. Její obsah by mohl vypadat kupříkladu takto:

-(BOOL)tableView:(NSTableView*)tv
  writeRowsWithIndexes:(NSIndexSet*)rows
  toPasteboard:(NSPasteboard*)pboard {
  NSString *typeName=@"cz.ocs.MyPasteboardType";
  [pboard declareTypes:[NSArray arrayWithObject:typeName] owner:nil];
  [pboard setData:
    [NSArchiver archivedDataWithRootObject:
      [[self arrangedObjects] objectsAtIndexes:rows]]
    forType:PBoardDBObjectType];
  return YES;
}

Tabulka se o vše ostatní postará již automaticky sama. Výše uvedený kód ovšem předpokládá, že je použit ve standardním kontroléru (NSArrayController – kontroléry v Cocoa jsme se zabývali nedávno); nesmíme tedy zapomenout kontrolér, k němuž bude tabulka připojena prostřednictvím vazeb ("bindings"), zároveň k tabulce připojit jako její datový zdroj. Jak již víme, v Cocoa je drobná chybka, kvůli níž musíme implementovat dvojici prázdných metod:

-(int)numberOfRowsInTableView:(NSTableView*)aTableView {return 0;}
-(id)tableView:(NSTableView*)aTableView
  objectValueForTableColumn:(NSTableColumn*)aTableColumn
  row:(int)rowIndex {return nil;}

Pro přijímání tažených objektů toho musíme implementovat malinko více, avšak pořád je to o něco snazší, než kdybychom měli protokol NSDraggingDestination implementovat přímo; tabulka zde totiž plně automaticky zpracuje umístění taženého objektu mezi její řádky (a "outline" se v analogických metodách dokonce postará i o otevírání/zavírání skrytých částí, chceme-li objekt vhodit do nich).

Nejprve musíme cílový objekt zaregistrovat pomocí služby registerForDraggedTypes:; to již známe, a je to zcela stejné jako při přímém použití protokolu NSDraggingDestination. Pak je zapotřebí implementovat dvojici metod:

-(NSDragOperation)tableView:(NSTableView*)tv
  validateDrop:(id<NSDraggingInfo>)info
  proposedRow:(int)row
  proposedDropOperation:(NSTableViewDropOperation)operation {
  ...
}

a

-(BOOL)tableView:(NSTableView*)tv
  acceptDrop:(id<NSDraggingInfo>)info
  row:(int)row
  dropOperation:(NSTableViewDropOperation)operation {
  ...
}

Tyto metody funkčně odpovídají již známým metodám draggingUpdated: a performDragOperation:; nesou však daleko více informací: argument row je číslo řádky, jíž se vhazování týká, a operation je jedna z možností NSTableViewDropOn – vhození přímo na danou řádku, ta se tedy zvýrazní celá a předpokládá se, že vhozená data změní její obsah – či NSTableViewDropAbove – vhození nad danou řádku, předpokládá se tedy, že vhozená data se vloží do tabulky (pro vhození pod poslední řádku slouží také tato hodnota spolu s číslem, odpovídajícím počtu řádek v tabulce).

Pokud nám cílový řádek a typ vhození tak, jak je navrhne sama tabulka v prvé metodě, nevyhovují (např. proto, že tabulka má dodržovat třídění řádků podle abecedy apod.), můžeme je změnit – stačí, pošleme-li tabulce zprávu setDropRow:dropOperation: s požadovanými argumenty.

Pro "outline" je to takřka stejné, jen samozřejmě namísto čísel řádků využíváme obecných identifkátorů:

-(NSDragOperation)outlineView:(NSOutlineView*)ov
  validateDrop:(id<NSDraggingInfo>)info
  proposedItem:item proposedChildIndex:(int)index {
  ...
  if (...) [ov setDropItem:anotherItem dropChildIndex:anotherIndex];
  ...
}
-(BOOL)outlineView:(NSOutlineView*)ov
  acceptDrop:(id<NSDraggingInfo>)info item:item childIndex:(int)index {
  ...
}

Hodnotou argumentu index může být také speciální konstanta NSOutlineViewDropOnItemIndex – v tomto případě budeme vhazovat přímo na samotný řádek, reprezentovaný itemem.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Tipy a Triky  

 » Rubriky  » Začínáme s  

 » Rubriky  » Software  

 

 

 

Nejčtenější články
Nejlépe hodnocené články
Apple kurzy

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: