PageRenderTime 61ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/cwxeditor_src/cwx/editor/gui/dwt/cardwindow.d

https://bitbucket.org/k4nagatsuki/cwxeditor
D | 1457 lines | 1421 code | 35 blank | 1 comment | 489 complexity | d052d30671d688cb739b9b75acd20663 MD5 | raw file
Possible License(s): LGPL-2.1
  1. module cwx.editor.gui.dwt.cardwindow;
  2. import cwx.card;
  3. import cwx.summary;
  4. import cwx.utils;
  5. import cwx.usecounter;
  6. import cwx.types;
  7. import cwx.xml;
  8. import cwx.skin;
  9. import cwx.path;
  10. import cwx.motion;
  11. import cwx.menu;
  12. import cwx.types;
  13. import cwx.system;
  14. import cwx.editor.gui.dwt.smalldialogs;
  15. import cwx.editor.gui.dwt.images;
  16. import cwx.editor.gui.dwt.dskin;
  17. import cwx.editor.gui.dwt.cardlist;
  18. import cwx.editor.gui.dwt.dutils;
  19. import cwx.editor.gui.dwt.dprops;
  20. import cwx.editor.gui.dwt.eventwindow;
  21. import cwx.editor.gui.dwt.customtext;
  22. import cwx.editor.gui.dwt.castcarddialog;
  23. import cwx.editor.gui.dwt.effectcarddialog;
  24. import cwx.editor.gui.dwt.infocarddialog;
  25. import cwx.editor.gui.dwt.xmlbytestransfer;
  26. import cwx.editor.gui.dwt.commons;
  27. import cwx.editor.gui.dwt.sbshell;
  28. import cwx.editor.gui.dwt.undo;
  29. import cwx.editor.gui.dwt.cardpane;
  30. import cwx.editor.gui.dwt.loader;
  31. import cwx.editor.gui.dwt.dmenu;
  32. import cwx.editor.gui.dwt.areatable;
  33. import std.algorithm;
  34. import std.array;
  35. import std.utf;
  36. import std.string;
  37. import std.datetime;
  38. import std.typetuple;
  39. import std.path;
  40. import org.eclipse.swt.all;
  41. import java.lang.all;
  42. public:
  43. interface ICardWindow {
  44. @property
  45. bool canCreateCast();
  46. @property
  47. bool canCreateSkill();
  48. @property
  49. bool canCreateItem();
  50. @property
  51. bool canCreateBeast();
  52. @property
  53. bool canCreateInfo();
  54. void createCast();
  55. void createSkill();
  56. void createItem();
  57. void createBeast();
  58. void createInfo();
  59. }
  60. enum CardWindowKind {
  61. Main,
  62. Cast,
  63. Skill,
  64. Item,
  65. Beast,
  66. Info,
  67. Hand,
  68. ImportSource,
  69. ImportSourceHand,
  70. }
  71. /// ??????????????
  72. class CardWindow(CardWindowKind CWKind, PCardOwner, CardOwner, ToCardOwner, bool WithArea, Cards ...)
  73. : TopLevelPanel, TCPD, ICardWindow {
  74. private:
  75. static const bool EditMode = is (ToCardOwner == void);
  76. static const bool UseCast = IndexOf!(CastCard, Cards) >= 0;
  77. static const bool UseSkill = IndexOf!(SkillCard, Cards) >= 0;
  78. static const bool UseItem = IndexOf!(ItemCard, Cards) >= 0;
  79. static const bool UseBeast = IndexOf!(BeastCard, Cards) >= 0;
  80. static const bool UseInfo = IndexOf!(InfoCard, Cards) >= 0;
  81. template Pane(Card) {
  82. mixin ("alias " ~ Card.stringof ~ "Pane!(PCardOwner, CardOwner, ToCardOwner) Pane;");
  83. }
  84. template CTypes(int Index, Cards ...) {
  85. static if (is(Cards[0] : CastCard)) {
  86. static const CAST = Index;
  87. } else static if (is(Cards[0] : SkillCard)) {
  88. static const SKILL = Index;
  89. } else static if (is(Cards[0] : ItemCard)) {
  90. static const ITEM = Index;
  91. } else static if (is(Cards[0] : BeastCard)) {
  92. static const BEAST = Index;
  93. } else static if (is(Cards[0] : InfoCard)) {
  94. static const INFO = Index;
  95. } else static assert (0);
  96. static if (Cards.length > 1) {
  97. mixin CTypes!(Index + 1, Cards[1 .. $]);
  98. }
  99. }
  100. mixin CTypes!(0, Cards);
  101. template PTypes(Cards ...) {
  102. static if (Cards.length > 1) {
  103. alias TypeTuple!(Pane!(Cards[0]),
  104. PTypes!(Cards[1 .. $])) PTypes;
  105. } else {
  106. alias TypeTuple!(Pane!(Cards[0])) PTypes;
  107. }
  108. }
  109. PTypes!(Cards) _pane;
  110. static if (1 < Cards.length || WithArea) {
  111. CTabFolder _tabf;
  112. CTabItem[Cards.length] _tab;
  113. } else {
  114. Composite _tabf;
  115. }
  116. static if (WithArea) {
  117. AreaTable _areas;
  118. CTabItem _aTab;
  119. }
  120. Props _prop;
  121. SBShell _sbshl;
  122. Composite _win;
  123. Composite _comp;
  124. PCardOwner _summ;
  125. CardOwner _owner;
  126. Commons _comm;
  127. CViewMode _viewMode = CViewMode.INIT;
  128. MenuItem _lifeM;
  129. MenuItem _listM;
  130. MenuItem _tblM;
  131. ToolItem _lifeT;
  132. ToolItem _listT;
  133. ToolItem _tblT;
  134. TCPD[] _tcpd;
  135. static if (!EditMode) {
  136. ToCardOwner _toc;
  137. }
  138. static if (EditMode) {
  139. void create(int Index)() { mixin(S_TRACE);
  140. static if (1 < Cards.length) {
  141. if (_tabf && !_tabf.isDisposed()) { mixin(S_TRACE);
  142. _tabf.setSelection(_tab[Index]);
  143. }
  144. }
  145. _pane[Index].create();
  146. }
  147. }
  148. static if (EditMode) {
  149. void open(int Index)(bool shellActivate) { mixin(S_TRACE);
  150. static if (is(CardOwner : Summary)) {
  151. static if (1 < Cards.length) {
  152. _comm.openBindCardWin(shellActivate);
  153. _tabf.setSelection(_tab[Index]);
  154. } else { mixin(S_TRACE);
  155. static if (UseCast && CAST == Index) {
  156. _comm.openCastWin(shellActivate);
  157. } else static if(UseSkill && SKILL == Index) { mixin(S_TRACE);
  158. _comm.openSkillWin(shellActivate);
  159. } else static if(UseItem && ITEM == Index) { mixin(S_TRACE);
  160. _comm.openItemWin(shellActivate);
  161. } else static if(UseBeast && BEAST == Index) { mixin(S_TRACE);
  162. _comm.openBeastWin(shellActivate);
  163. } else static if(UseInfo && INFO == Index) { mixin(S_TRACE);
  164. _comm.openInfoWin(shellActivate);
  165. } else static assert (0);
  166. }
  167. } else { mixin(S_TRACE);
  168. _tabf.setSelection(_tab[Index]);
  169. }
  170. }
  171. }
  172. void __refresh() { mixin(S_TRACE);
  173. foreach (f; _pane) { mixin(S_TRACE);
  174. f.refresh();
  175. }
  176. refreshTitle();
  177. }
  178. static if (EditMode && is (CardOwner == Summary)) {
  179. void addScenario() { mixin(S_TRACE);
  180. _comm.addScenario(_prop);
  181. }
  182. class DropScenario : DropTargetAdapter {
  183. override void dragEnter(DropTargetEvent e){ mixin(S_TRACE);
  184. e.detail = DND.DROP_LINK;
  185. }
  186. override void drop(DropTargetEvent e) { mixin(S_TRACE);
  187. auto arr = cast(FileNames) e.data;
  188. if (arr && arr.array.length > 0) { mixin(S_TRACE);
  189. _comm.addScenario(_prop, arr.array);
  190. }
  191. }
  192. }
  193. }
  194. @property
  195. Shell dlgParShl() { mixin(S_TRACE);
  196. if (_win && !_win.isDisposed()) return _win.getShell();
  197. return _comm.mainWin.shell.getShell();
  198. }
  199. static if (UseCast && !EditMode) {
  200. void openHand() { mixin(S_TRACE);
  201. auto sels = _pane[CAST].selectedCards;
  202. foreach (sel; sels) { mixin(S_TRACE);
  203. _comm.openAddHands(_prop, _summ, sel, _toc, true);
  204. }
  205. }
  206. }
  207. public:
  208. static if (EditMode) {
  209. static if (is (CardOwner == Summary)) {
  210. this (Commons comm, Props prop, Composite parent) { mixin(S_TRACE);
  211. _comm = comm;
  212. _prop = prop;
  213. if (parent) { mixin(S_TRACE);
  214. construct(comm, prop, null, parent);
  215. } else { mixin(S_TRACE);
  216. initPane!(0)();
  217. }
  218. }
  219. void reconstruct(Composite parent) { mixin(S_TRACE);
  220. if (_win && !_win.isDisposed()) return;
  221. construct(_comm, _prop, _summ, parent);
  222. if (_owner) refresh(_owner);
  223. }
  224. } else {
  225. this(Commons comm, Props prop, PCardOwner summ, Composite parent) { mixin(S_TRACE);
  226. construct(comm, prop, summ, parent);
  227. }
  228. }
  229. void construct(Commons comm, Props prop, PCardOwner summ, Composite parent) { mixin(S_TRACE);
  230. _viewMode = CViewMode.INIT;
  231. construct1(comm, prop, parent);
  232. static if (is (CardOwner == Summary)) {
  233. auto shell = cast(Shell) _win;
  234. if (shell) { mixin(S_TRACE);
  235. shell.addShellListener(new class ShellAdapter {
  236. override void shellClosed(ShellEvent e) { mixin(S_TRACE);
  237. (cast(Shell) e.widget).setVisible(false);
  238. e.doit = false;
  239. _prop.var.cardWin.visible = false;
  240. }
  241. });
  242. }
  243. }
  244. static if (is (CardOwner == CastCard) && is (PCardOwner == Summary)) {
  245. _comm.refCast.add(&__refOwner);
  246. _comm.delCast.add(&__delOwner);
  247. _win.addDisposeListener(new class DisposeListener {
  248. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  249. _comm.refCast.remove(&__refOwner);
  250. _comm.delCast.remove(&__delOwner);
  251. }
  252. });
  253. }
  254. construct2();
  255. _comm.refScenarioName.add(&refreshTitle);
  256. _comm.refScenarioPath.add(&refreshTitle);
  257. _win.addDisposeListener(new class DisposeListener {
  258. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  259. _comm.refScenarioName.remove(&refreshTitle);
  260. _comm.refScenarioPath.remove(&refreshTitle);
  261. }
  262. });
  263. }
  264. void initPane(int Index)() { mixin(S_TRACE);
  265. assert (!_pane[Index]);
  266. _pane[Index] = new typeof(_pane[Index])(_comm, _prop, _summ, _tabf, SWT.BORDER);
  267. static if (Index + 1 < Cards.length) {
  268. initPane!(Index + 1)();
  269. }
  270. }
  271. void newPane(int Index)() { mixin(S_TRACE);
  272. if (_pane[Index]) { mixin(S_TRACE);
  273. _pane[Index].reconstruct(_tabf, SWT.BORDER);
  274. } else { mixin(S_TRACE);
  275. _pane[Index] = new typeof(_pane[Index])(_comm, _prop, _summ, _tabf, SWT.BORDER);
  276. _pane[Index].construct();
  277. }
  278. static if (Index + 1 < Cards.length) {
  279. newPane!(Index + 1)();
  280. }
  281. }
  282. } else {
  283. void newPane(int Index)() { mixin(S_TRACE);
  284. if (_pane[Index]) { mixin(S_TRACE);
  285. _pane[Index].reconstruct(_tabf, SWT.BORDER);
  286. } else { mixin(S_TRACE);
  287. static if (UseCast && Index == CAST) {
  288. _pane[Index] = new typeof(_pane[Index])(_comm, _prop, _summ, _tabf, SWT.BORDER, _toc, &openHand);
  289. } else { mixin(S_TRACE);
  290. _pane[Index] = new typeof(_pane[Index])(_comm, _prop, _summ, _tabf, SWT.BORDER, _toc);
  291. }
  292. _pane[Index].construct();
  293. }
  294. static if (Index + 1 < Cards.length) {
  295. newPane!(Index + 1)();
  296. }
  297. }
  298. this (Commons comm, Props prop,
  299. Composite parent, PCardOwner summ, CardOwner owner, ToCardOwner toc) { mixin(S_TRACE);
  300. _toc = toc;
  301. construct1(comm, prop, parent);
  302. static if (is (CardOwner == CastCard)) {
  303. _comm.closeAdds.add(&__closeAdds);
  304. _win.addDisposeListener(new class DisposeListener {
  305. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  306. _comm.closeAdds.remove(&__closeAdds);
  307. }
  308. });
  309. }
  310. static if (is (CardOwner == Summary)) {
  311. _win.addDisposeListener(new class DisposeListener {
  312. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  313. _comm.closeAdds.call(_summ);
  314. }
  315. });
  316. }
  317. _summ = summ;
  318. construct2();
  319. refreshAll(summ, owner);
  320. }
  321. }
  322. private void construct1(Commons comm, Props prop, Composite parent) { mixin(S_TRACE);
  323. _comm = comm;
  324. _prop = prop;
  325. Shell shell = null;
  326. auto parShl = cast(Shell) parent;
  327. Composite contPane;
  328. if (parShl) { mixin(S_TRACE);
  329. _sbshl = new SBShell(parShl, SWT.SHELL_TRIM);
  330. shell = _sbshl.shell;
  331. shell.setImages(_prop.images.icon);
  332. _win = shell;
  333. contPane = _sbshl.contentPane;
  334. } else { mixin(S_TRACE);
  335. _win = new Composite(parent, SWT.NONE);
  336. contPane = _win;
  337. }
  338. _win.setData(new TLPData(this));
  339. contPane.setLayout(new FillLayout);
  340. _comp = new Composite(contPane, SWT.NONE);
  341. _comp.setLayout(windowGridLayout(1, true));
  342. if (shell) { mixin(S_TRACE);
  343. { mixin(S_TRACE);
  344. auto bar = new Menu(shell, SWT.BAR);
  345. auto mf = createMenu(_comm, bar, MenuID.File);
  346. createMenuItem(_comm, mf, MenuID.CloseWin, &shell.close, null);
  347. auto me = createMenu(_comm, bar, MenuID.Edit);
  348. static if (EditMode) {
  349. createMenuItem(_comm, me, MenuID.Undo, &undo, &canUndo);
  350. createMenuItem(_comm, me, MenuID.Redo, &redo, &canRedo);
  351. new MenuItem(me, SWT.SEPARATOR);
  352. appendMenuTCPD(_comm, me, this, true, true, true, true, true);
  353. new MenuItem(me, SWT.SEPARATOR);
  354. createMenuItem(_comm, me, MenuID.Up, &up, &canUp);
  355. createMenuItem(_comm, me, MenuID.Down, &down, &canDown);
  356. } else { mixin(S_TRACE);
  357. createMenuItem(_comm, me, MenuID.Import, &doImport, &canDoImport);
  358. new MenuItem(me, SWT.SEPARATOR);
  359. appendMenuTCPD(_comm, me, this, false, true, false, false, false);
  360. }
  361. auto mv = createMenu(_comm, bar, MenuID.View);
  362. static if (EditMode) {
  363. createMenuItem(_comm, mv, MenuID.Refresh, &__refresh, () => _summ !is null);
  364. new MenuItem(mv, SWT.SEPARATOR);
  365. }
  366. _lifeM = createMenuItem(_comm, mv, MenuID.ShowCardProp, &showCardLife, null, SWT.RADIO);
  367. _listM = createMenuItem(_comm, mv, MenuID.ShowCardImage, &showCardList, null, SWT.RADIO);
  368. _tblM = createMenuItem(_comm, mv, MenuID.ShowCardDetail, &showCardTable, null, SWT.RADIO);
  369. static if (EditMode) {
  370. auto mt = createMenu(_comm, bar, MenuID.Card);
  371. static if (is (CardOwner == Summary)) {
  372. createMenuItem(_comm, mt, MenuID.OpenImportSource, &addScenario, () => _summ !is null);
  373. new MenuItem(mt, SWT.SEPARATOR);
  374. }
  375. static if (UseCast) createMenuItem(_comm, mt, MenuID.NewCast, &create!(CAST), () => _summ !is null);
  376. static if (UseSkill) createMenuItem(_comm, mt, MenuID.NewSkill, &create!(SKILL), () => _summ !is null);
  377. static if (UseItem) createMenuItem(_comm, mt, MenuID.NewItem, &create!(ITEM), () => _summ !is null);
  378. static if (UseBeast) createMenuItem(_comm, mt, MenuID.NewBeast, &create!(BEAST), () => _summ !is null);
  379. static if (UseInfo) createMenuItem(_comm, mt, MenuID.NewInfo, &create!(INFO), () => _summ !is null);
  380. }
  381. shell.setMenuBar(bar);
  382. }
  383. { mixin(S_TRACE);
  384. auto bar = new ToolBar(_comp, SWT.FLAT);
  385. _comm.put(bar);
  386. static if (EditMode) {
  387. static if (is (CardOwner == Summary)) {
  388. createToolItem(_comm, bar, MenuID.OpenImportSource, &addScenario, () => _summ !is null);
  389. new ToolItem(bar, SWT.SEPARATOR);
  390. }
  391. }
  392. static if (EditMode) {
  393. createToolItem(_comm, bar, MenuID.Refresh, &__refresh, () => _summ !is null);
  394. new ToolItem(bar, SWT.SEPARATOR);
  395. createToolItem(_comm, bar, MenuID.Up, &up, &canUp);
  396. createToolItem(_comm, bar, MenuID.Down, &down, &canDown);
  397. new ToolItem(bar, SWT.SEPARATOR);
  398. static if (UseCast) createToolItem(_comm, bar, MenuID.NewCast, &create!(CAST), () => _summ !is null);
  399. static if (UseSkill) createToolItem(_comm, bar, MenuID.NewSkill, &create!(SKILL), () => _summ !is null);
  400. static if (UseItem) createToolItem(_comm, bar, MenuID.NewItem, &create!(ITEM), () => _summ !is null);
  401. static if (UseBeast) createToolItem(_comm, bar, MenuID.NewBeast, &create!(BEAST), () => _summ !is null);
  402. static if (UseInfo) createToolItem(_comm, bar, MenuID.NewInfo, &create!(INFO), () => _summ !is null);
  403. } else { mixin(S_TRACE);
  404. createToolItem(_comm, bar, MenuID.Import, &doImport, &canDoImport);
  405. }
  406. new ToolItem(bar, SWT.SEPARATOR);
  407. _lifeT = createToolItem(_comm, bar, MenuID.ShowCardProp, &showCardLife, null, SWT.RADIO);
  408. _listT = createToolItem(_comm, bar, MenuID.ShowCardImage, &showCardList, null, SWT.RADIO);
  409. _tblT = createToolItem(_comm, bar, MenuID.ShowCardDetail, &showCardTable, null, SWT.RADIO);
  410. }
  411. } else { mixin(S_TRACE);
  412. static if (WithArea) {
  413. putMenuAction(MenuID.EditSummary, () => _areas.editSummary(_areas.panel.getShell()), () => _summ !is null);
  414. putMenuAction(MenuID.EditScene, () => _areas.openAreaScene(true), () => _areas.canOpenAreaScene);
  415. putMenuAction(MenuID.EditEvent, () => _areas.openAreaEvent(true), () => _areas.canOpenAreaEvent);
  416. putMenuAction(MenuID.ChangeVH, () => _areas.changeVHSide(), () => _areas.canChangeVH);
  417. }
  418. static if (EditMode) {
  419. appendMenuTCPD(_comm, this, this, true, true, true, true, true);
  420. putMenuAction(MenuID.Refresh, &__refresh, () => _summ !is null);
  421. static if (is (CardOwner == Summary)) {
  422. putMenuAction(MenuID.OpenImportSource, &addScenario, () => _summ !is null);
  423. }
  424. putMenuAction(MenuID.Undo, &undo, &canUndo);
  425. putMenuAction(MenuID.Redo, &redo, &canRedo);
  426. static if (UseCast) {
  427. putMenuAction(MenuID.NewCast, &create!(CAST), () => _summ !is null);
  428. putMenuAction(MenuID.OpenHand, &editHand, &canEditHand);
  429. }
  430. static if (UseSkill) putMenuAction(MenuID.NewSkill, &create!(SKILL), () => _summ !is null);
  431. static if (UseItem) putMenuAction(MenuID.NewItem, &create!(ITEM), () => _summ !is null);
  432. static if (UseBeast) putMenuAction(MenuID.NewBeast, &create!(BEAST), () => _summ !is null);
  433. static if (UseInfo) putMenuAction(MenuID.NewInfo, &create!(INFO), () => _summ !is null);
  434. putMenuAction(MenuID.Up, &up, &canUp);
  435. putMenuAction(MenuID.Down, &down, &canDown);
  436. putMenuAction(MenuID.FindID, &replaceID, &canReplaceID);
  437. putMenuAction(MenuID.EditProp, &edit, &canEdit);
  438. putMenuAction(MenuID.ReNumbering, &reNumbering, &canReNumbering);
  439. static if (is(CardOwner:CastCard)) {
  440. putMenuAction(MenuID.RemoveRef, &removeRef, &canRemoveRef);
  441. }
  442. } else { mixin(S_TRACE);
  443. appendMenuTCPD(_comm, this, this, false, true, false, false, false);
  444. putMenuAction(MenuID.ShowProp, &edit, &canEdit);
  445. static if (UseCast) {
  446. putMenuAction(MenuID.OpenHand, &editHand, &canEditHand);
  447. }
  448. putMenuAction(MenuID.Import, &doImport, &canDoImport);
  449. }
  450. static if (UseSkill || UseItem || UseBeast) {
  451. putMenuAction(MenuID.EditEventAtTimeOfUsing, &editUseEvent, &canEditUseEvent);
  452. }
  453. putMenuChecked(MenuID.ShowCardProp, &showCardLife, &isViewLife, null);
  454. putMenuChecked(MenuID.ShowCardImage, &showCardList, &isViewList, null);
  455. putMenuChecked(MenuID.ShowCardDetail, &showCardTable, &isViewTable, null);
  456. }
  457. static if (1 < Cards.length || WithArea) {
  458. _tabf = new CTabFolder(_comp, SWT.BORDER);
  459. _tabf.addSelectionListener(new SelChanged);
  460. } else { mixin(S_TRACE);
  461. _tabf = new Composite(_comp, SWT.NONE);
  462. _tabf.setLayout(zeroGridLayout(1, true));
  463. }
  464. _tabf.setLayoutData(new GridData(GridData.FILL_BOTH));
  465. static if (EditMode && is (CardOwner == Summary)) {
  466. auto drop = new DropTarget(_comp, DND.DROP_DEFAULT | DND.DROP_LINK);
  467. drop.setTransfer([FileTransfer.getInstance()]);
  468. drop.addDropListener(new DropScenario);
  469. }
  470. }
  471. static if (1 < Cards.length || WithArea) {
  472. private class SelChanged : SelectionAdapter {
  473. override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
  474. refreshStatusLine();
  475. _comm.refreshToolBar();
  476. }
  477. }
  478. }
  479. static if (EditMode) {
  480. void reNumberingAll() { mixin(S_TRACE);
  481. foreach (f; _pane) { mixin(S_TRACE);
  482. f.reNumbering(0, 1);
  483. }
  484. }
  485. }
  486. void showCardLife() { mixin(S_TRACE);
  487. if (_viewMode != CViewMode.LIFE) { mixin(S_TRACE);
  488. _viewMode = CViewMode.LIFE;
  489. if (_win && !_win.isDisposed()) { mixin(S_TRACE);
  490. if (_listM) { mixin(S_TRACE);
  491. _lifeM.setSelection(true);
  492. _lifeT.setSelection(true);
  493. _listM.setSelection(false);
  494. _listT.setSelection(false);
  495. _tblM.setSelection(false);
  496. _tblT.setSelection(false);
  497. }
  498. foreach (i, f; _pane) { mixin(S_TRACE);
  499. f.showCardLife();
  500. }
  501. }
  502. static if (EditMode && is (CardOwner == Summary)) {
  503. _prop.var.etc.cardLife = true;
  504. _prop.var.etc.cardDetails = false;
  505. }
  506. refreshStatusLine();
  507. }
  508. }
  509. void showCardList() { mixin(S_TRACE);
  510. if (_viewMode != CViewMode.CARD) { mixin(S_TRACE);
  511. _viewMode = CViewMode.CARD;
  512. if (_win && !_win.isDisposed()) { mixin(S_TRACE);
  513. if (_listM) { mixin(S_TRACE);
  514. _lifeM.setSelection(false);
  515. _lifeT.setSelection(false);
  516. _listM.setSelection(true);
  517. _listT.setSelection(true);
  518. _tblM.setSelection(false);
  519. _tblT.setSelection(false);
  520. }
  521. foreach (i, f; _pane) { mixin(S_TRACE);
  522. f.showCardList();
  523. }
  524. }
  525. static if (EditMode && is (CardOwner == Summary)) {
  526. _prop.var.etc.cardLife = false;
  527. _prop.var.etc.cardDetails = false;
  528. }
  529. refreshStatusLine();
  530. }
  531. }
  532. void showCardTable() { mixin(S_TRACE);
  533. if (_viewMode != CViewMode.TABLE) { mixin(S_TRACE);
  534. _viewMode = CViewMode.TABLE;
  535. if (_win && !_win.isDisposed()) { mixin(S_TRACE);
  536. if (_listM) { mixin(S_TRACE);
  537. _lifeM.setSelection(false);
  538. _lifeT.setSelection(false);
  539. _listM.setSelection(false);
  540. _listT.setSelection(false);
  541. _tblM.setSelection(true);
  542. _tblT.setSelection(true);
  543. }
  544. foreach (i, f; _pane) { mixin(S_TRACE);
  545. f.showCardTable();
  546. }
  547. }
  548. static if (EditMode && is (CardOwner == Summary)) {
  549. _prop.var.etc.cardLife = false;
  550. _prop.var.etc.cardDetails = true;
  551. }
  552. refreshStatusLine();
  553. }
  554. }
  555. void setStatusLine(string status) { mixin(S_TRACE);
  556. auto w = _win;
  557. if (w.isDisposed()) { mixin(S_TRACE);
  558. w = null;
  559. }
  560. _comm.setStatusLine(w, status);
  561. }
  562. static if (EditMode && is(CardOwner : Summary)) {
  563. CastCardPane!(PCardOwner, CardOwner, ToCardOwner) openCast(bool shellActivate) { mixin(S_TRACE);
  564. static if (UseCast) {
  565. open!(CAST)(shellActivate);
  566. return _pane[CAST];
  567. } else { mixin(S_TRACE);
  568. throw new Exception("can not open cast");
  569. }
  570. }
  571. SkillCardPane!(PCardOwner, CardOwner, ToCardOwner) openSkill(bool shellActivate) { mixin(S_TRACE);
  572. static if (UseSkill) {
  573. open!(SKILL)(shellActivate);
  574. return _pane[SKILL];
  575. } else { mixin(S_TRACE);
  576. throw new Exception("can not open skill");
  577. }
  578. }
  579. ItemCardPane!(PCardOwner, CardOwner, ToCardOwner) openItem(bool shellActivate) { mixin(S_TRACE);
  580. static if (UseItem) {
  581. open!(ITEM)(shellActivate);
  582. return _pane[ITEM];
  583. } else { mixin(S_TRACE);
  584. throw new Exception("can not open item");
  585. }
  586. }
  587. BeastCardPane!(PCardOwner, CardOwner, ToCardOwner) openBeast(bool shellActivate) { mixin(S_TRACE);
  588. static if (UseBeast) {
  589. open!(BEAST)(shellActivate);
  590. return _pane[BEAST];
  591. } else { mixin(S_TRACE);
  592. throw new Exception("can not open beast");
  593. }
  594. }
  595. InfoCardPane!(PCardOwner, CardOwner, ToCardOwner) openInfo(bool shellActivate) { mixin(S_TRACE);
  596. static if (UseInfo) {
  597. open!(INFO)(shellActivate);
  598. return _pane[INFO];
  599. } else { mixin(S_TRACE);
  600. throw new Exception("can not open info");
  601. }
  602. }
  603. static if (UseCast) {
  604. @property
  605. CastCardPane!(PCardOwner, CardOwner, ToCardOwner) paneCast() { mixin(S_TRACE);
  606. return _pane[CAST];
  607. }
  608. }
  609. static if (UseSkill) {
  610. @property
  611. SkillCardPane!(PCardOwner, CardOwner, ToCardOwner) paneSkill() { mixin(S_TRACE);
  612. return _pane[SKILL];
  613. }
  614. }
  615. static if (UseItem) {
  616. @property
  617. ItemCardPane!(PCardOwner, CardOwner, ToCardOwner) paneItem() { mixin(S_TRACE);
  618. return _pane[ITEM];
  619. }
  620. }
  621. static if (UseBeast) {
  622. @property
  623. BeastCardPane!(PCardOwner, CardOwner, ToCardOwner) paneBeast() { mixin(S_TRACE);
  624. return _pane[BEAST];
  625. }
  626. }
  627. static if (UseInfo) {
  628. @property
  629. InfoCardPane!(PCardOwner, CardOwner, ToCardOwner) paneInfo() { mixin(S_TRACE);
  630. return _pane[INFO];
  631. }
  632. }
  633. }
  634. void createCast() { mixin(S_TRACE);
  635. if (!_summ) return;
  636. static if (EditMode && UseCast) {
  637. create!(CAST)();
  638. } else { mixin(S_TRACE);
  639. throw new Exception("can not create cast");
  640. }
  641. }
  642. void createSkill() { mixin(S_TRACE);
  643. if (!_summ) return;
  644. static if (EditMode && UseSkill) {
  645. create!(SKILL)();
  646. } else { mixin(S_TRACE);
  647. throw new Exception("can not create skill");
  648. }
  649. }
  650. void createItem() { mixin(S_TRACE);
  651. if (!_summ) return;
  652. static if (EditMode && UseItem) {
  653. create!(ITEM)();
  654. } else { mixin(S_TRACE);
  655. throw new Exception("can not create item");
  656. }
  657. }
  658. void createBeast() { mixin(S_TRACE);
  659. if (!_summ) return;
  660. static if (EditMode && UseBeast) {
  661. create!(BEAST)();
  662. } else { mixin(S_TRACE);
  663. throw new Exception("can not create beast");
  664. }
  665. }
  666. void createInfo() { mixin(S_TRACE);
  667. if (!_summ) return;
  668. static if (EditMode && UseInfo) {
  669. create!(INFO)();
  670. } else { mixin(S_TRACE);
  671. throw new Exception("can not create info");
  672. }
  673. }
  674. @property
  675. bool canCreateCast() {return EditMode && UseCast;}
  676. @property
  677. bool canCreateSkill() {return EditMode && UseSkill;}
  678. @property
  679. bool canCreateItem() {return EditMode && UseItem;}
  680. @property
  681. bool canCreateBeast() {return EditMode && UseBeast;}
  682. @property
  683. bool canCreateInfo() {return EditMode && UseInfo;}
  684. @property
  685. private bool isViewLife() { mixin(S_TRACE);
  686. return _viewMode == CViewMode.LIFE;
  687. }
  688. @property
  689. private bool isViewList() { mixin(S_TRACE);
  690. return _viewMode == CViewMode.CARD;
  691. }
  692. @property
  693. private bool isViewTable() { mixin(S_TRACE);
  694. return _viewMode == CViewMode.TABLE;
  695. }
  696. static if (!EditMode || !is(CardOwner : Summary)) {
  697. private static class ColResize : ControlAdapter {
  698. bool procRefColWidth = false;
  699. Commons comm;
  700. TableColumn[] cols;
  701. override void controlResized(ControlEvent e) { mixin(S_TRACE);
  702. if (procRefColWidth) return;
  703. procRefColWidth = true;
  704. scope (exit) procRefColWidth = false;
  705. auto c = cast(TableColumn) e.widget;
  706. int width = c.getWidth();
  707. foreach (col; cols) { mixin(S_TRACE);
  708. if (c !is col) { mixin(S_TRACE);
  709. col.setWidth(width);
  710. }
  711. }
  712. }
  713. }
  714. }
  715. private void construct2() { mixin(S_TRACE);
  716. newPane!(0)();
  717. static if (WithArea) {
  718. if (!_areas) { mixin(S_TRACE);
  719. _areas = new AreaTable(_comm, _prop, !EditMode, _toc);
  720. }
  721. _areas.construct(_tabf, null);
  722. }
  723. static if (!EditMode || !is(CardOwner : Summary)) {
  724. ColResize[CardTableColumn] colR;
  725. void addTable(TableColumn[CardTableColumn] columns) { mixin(S_TRACE);
  726. foreach (i, col; columns) { mixin(S_TRACE);
  727. if (i !in colR) { mixin(S_TRACE);
  728. colR[i] = new ColResize;
  729. colR[i].comm = _comm;
  730. }
  731. colR[i].cols ~= col;
  732. col.addControlListener(colR[i]);
  733. }
  734. }
  735. }
  736. foreach (i, f; _pane) { mixin(S_TRACE);
  737. static if (1 < Cards.length || WithArea) {
  738. _tab[i] = new CTabItem(_tabf, SWT.NONE);
  739. static if (UseCast) {
  740. if (i == CAST) { mixin(S_TRACE);
  741. _tab[i].setText(_prop.msgs.cwCast);
  742. _tab[i].setImage(_prop.images.casts);
  743. }
  744. }
  745. static if (UseSkill) {
  746. if (i == SKILL) { mixin(S_TRACE);
  747. _tab[i].setText(_prop.msgs.skill);
  748. _tab[i].setImage(_prop.images.skill);
  749. }
  750. }
  751. static if (UseItem) {
  752. if (i == ITEM) { mixin(S_TRACE);
  753. _tab[i].setText(_prop.msgs.item);
  754. _tab[i].setImage(_prop.images.item);
  755. }
  756. }
  757. static if (UseBeast) {
  758. if (i == BEAST) { mixin(S_TRACE);
  759. _tab[i].setText(_prop.msgs.beast);
  760. _tab[i].setImage(_prop.images.beast);
  761. }
  762. }
  763. static if (UseInfo) {
  764. if (i == INFO) { mixin(S_TRACE);
  765. _tab[i].setText(_prop.msgs.info);
  766. _tab[i].setImage(_prop.images.info);
  767. }
  768. }
  769. _tab[i].setControl(_pane[i].pane);
  770. } else { mixin(S_TRACE);
  771. _pane[i].pane.setLayoutData(new GridData(GridData.FILL_BOTH));
  772. }
  773. _tcpd ~= f;
  774. static if (!EditMode || !is(CardOwner : Summary)) {
  775. addTable(f.columns);
  776. }
  777. }
  778. static if (WithArea) {
  779. _aTab = new CTabItem(_tabf, SWT.NONE, 0);
  780. _aTab.setText(_prop.msgs.areasTabName);
  781. _aTab.setImage(_prop.images.menu(MenuID.TableView));
  782. _aTab.setControl(_areas.panel);
  783. _tcpd ~= _areas;
  784. }
  785. auto shell = cast(Shell) _win;
  786. static if (1 < Cards.length || WithArea) {
  787. _tabf.setSelection(0);
  788. }
  789. bool life = _prop.var.etc.cardLife;
  790. bool detail = _prop.var.etc.cardDetails;
  791. if (!life && detail) { mixin(S_TRACE);
  792. showCardTable();
  793. } else if (life) { mixin(S_TRACE);
  794. showCardLife();
  795. } else { mixin(S_TRACE);
  796. showCardList();
  797. }
  798. if (shell) { mixin(S_TRACE);
  799. scope wp = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
  800. int width = _prop.var.cardWin.width == SWT.DEFAULT ? wp.x : _prop.var.cardWin.width;
  801. static if (EditMode && is (CardOwner == Summary)) {
  802. shell.setMaximized(_prop.var.cardWin.maximized);
  803. shell.setMinimized(_prop.var.cardWin.minimized);
  804. int x = _prop.var.cardWin.x == SWT.DEFAULT ? shell.getBounds().x : _prop.var.cardWin.x + shell.getParent().getBounds().x;
  805. int y = _prop.var.cardWin.y == SWT.DEFAULT ? shell.getBounds().y : _prop.var.cardWin.y + shell.getParent().getBounds().y;
  806. intoDisplay(x, y, width, _prop.var.cardWin.height);
  807. shell.setBounds(x, y, width, _prop.var.cardWin.height);
  808. shell.addControlListener(new SizeL);
  809. } else { mixin(S_TRACE);
  810. shell.setSize(width, _prop.var.cardWin.height);
  811. }
  812. }
  813. }
  814. private class SizeL : ControlAdapter {
  815. private void saveCardWin() { mixin(S_TRACE);
  816. auto shell = cast(Shell) _win;
  817. if (shell) { mixin(S_TRACE);
  818. if (!shell.getMaximized() && !shell.getMinimized()) { mixin(S_TRACE);
  819. _prop.var.cardWin.width = shell.getSize().x;
  820. _prop.var.cardWin.height = shell.getSize().y;
  821. _prop.var.cardWin.x = shell.getBounds().x - shell.getParent().getBounds().x;
  822. _prop.var.cardWin.y = shell.getBounds().y - shell.getParent().getBounds().y;
  823. }
  824. _prop.var.cardWin.maximized = shell.getMaximized();
  825. _prop.var.cardWin.minimized = shell.getMinimized();
  826. }
  827. }
  828. override void controlMoved(ControlEvent e) { mixin(S_TRACE);
  829. saveCardWin();
  830. }
  831. override void controlResized(ControlEvent e) { mixin(S_TRACE);
  832. saveCardWin();
  833. }
  834. }
  835. static if (!EditMode && is(CardOwner == CastCard)) {
  836. private void __closeAdds(Summary importable) { mixin(S_TRACE);
  837. if (_summ is importable) { mixin(S_TRACE);
  838. _comm.close(_win);
  839. }
  840. }
  841. }
  842. @property
  843. override
  844. Composite shell() { mixin(S_TRACE);
  845. return _win;
  846. }
  847. @property
  848. CardOwner owner() { mixin(S_TRACE);
  849. return _owner;
  850. }
  851. @property
  852. PCardOwner summary() { mixin(S_TRACE);
  853. return _summ;
  854. }
  855. static if (EditMode && is (CardOwner == CastCard) && is (PCardOwner == Summary)) {
  856. private void __refOwner(CastCard c) { mixin(S_TRACE);
  857. if (_owner is c) { mixin(S_TRACE);
  858. __refresh();
  859. refreshTitle();
  860. }
  861. }
  862. private void __delOwner(CastCard c) { mixin(S_TRACE);
  863. if (_owner is c) { mixin(S_TRACE);
  864. _comm.close(_win);
  865. }
  866. }
  867. }
  868. @property
  869. override
  870. Image image() { mixin(S_TRACE);
  871. final switch (CWKind) {
  872. case CardWindowKind.Main: return _prop.images.menu(MenuID.CardView);
  873. case CardWindowKind.Cast: return _prop.images.menu(MenuID.CastView);
  874. case CardWindowKind.Skill: return _prop.images.menu(MenuID.SkillView);
  875. case CardWindowKind.Item: return _prop.images.menu(MenuID.ItemView);
  876. case CardWindowKind.Beast: return _prop.images.menu(MenuID.BeastView);
  877. case CardWindowKind.Info: return _prop.images.menu(MenuID.InfoView);
  878. case CardWindowKind.Hand: return _prop.images.menu(MenuID.OpenHand);
  879. case CardWindowKind.ImportSource: return _prop.images.menu(MenuID.OpenImportSource);
  880. case CardWindowKind.ImportSourceHand: return _prop.images.menu(MenuID.OpenImportSource);
  881. }
  882. }
  883. @property
  884. override
  885. string title() { mixin(S_TRACE);
  886. auto shl = cast(Shell) _win;
  887. if (shl) { mixin(S_TRACE);
  888. static if (CWKind == CardWindowKind.Main) {
  889. if (_summ) { mixin(S_TRACE);
  890. return .tryFormat(_prop.msgs.mainCardWindowName, _summ.scenarioName, _summ.scenarioPath);
  891. } else { mixin(S_TRACE);
  892. return _prop.msgs.mainCardWindowNameNoSummary;
  893. }
  894. } else static if (CWKind == CardWindowKind.Cast || CWKind == CardWindowKind.Skill || CWKind == CardWindowKind.Item || CWKind == CardWindowKind.Beast || CWKind == CardWindowKind.Info) {
  895. if (_summ) { mixin(S_TRACE);
  896. return .tryFormat(_prop.msgs.cardWindowName, .objName!(Cards[0])(_prop), _summ.scenarioName, _summ.scenarioPath);
  897. } else { mixin(S_TRACE);
  898. return .tryFormat(_prop.msgs.cardWindowNameNoSummary, .objName!(Cards[0])(_prop));
  899. }
  900. } else static if (CWKind == CardWindowKind.Hand) {
  901. static if (CWKind == CardWindowKind.Hand) {
  902. return .tryFormat(_prop.msgs.handCardWindowName, owner.id, owner.name);
  903. } else { mixin(S_TRACE);
  904. assert (0);
  905. }
  906. } else static if (CWKind == CardWindowKind.ImportSource) {
  907. assert (_summ !is null);
  908. return .tryFormat(_prop.msgs.importSourceWindowName, _summ.scenarioName, _summ.scenarioPath);
  909. } else static if (CWKind == CardWindowKind.ImportSourceHand) {
  910. return .tryFormat(_prop.msgs.handCardWindowName, owner.id, owner.name);
  911. } else static assert (0);
  912. }
  913. static if (CWKind == CardWindowKind.Main) {
  914. return _prop.msgs.mainCardTabName;
  915. } else static if (CWKind == CardWindowKind.Cast || CWKind == CardWindowKind.Skill || CWKind == CardWindowKind.Item || CWKind == CardWindowKind.Beast || CWKind == CardWindowKind.Info) {
  916. return .tryFormat(_prop.msgs.cardTabName, .objName!(Cards[0])(_prop));
  917. } else static if (CWKind == CardWindowKind.Hand) {
  918. return .tryFormat(_prop.msgs.handCardTabName, owner.id, owner.name);
  919. } else static if (CWKind == CardWindowKind.ImportSource) {
  920. assert (_summ !is null);
  921. return .tryFormat(_prop.msgs.importSourceTabName, _summ.scenarioName, _summ.scenarioPath);
  922. } else static if (CWKind == CardWindowKind.ImportSourceHand) {
  923. return .tryFormat(_prop.msgs.handCardTabName, owner.id, owner.name);
  924. } else static assert (0);
  925. }
  926. @property
  927. override
  928. void delegate(string) statusText() {return _sbshl ? &_sbshl.statusLine : null;}
  929. void refreshTitle() { mixin(S_TRACE);
  930. if (_win && !_win.isDisposed()) _comm.setTitle(shell, title);
  931. }
  932. static if (EditMode) {
  933. static if (is (PCardOwner == Summary) && is (CardOwner == Summary)) {
  934. void refresh(Summary summ) { mixin(S_TRACE);
  935. refreshAll(summ, summ);
  936. }
  937. } else {
  938. void refresh(PCardOwner summ, CardOwner owner) { mixin(S_TRACE);
  939. refreshAll(summ, owner);
  940. }
  941. }
  942. }
  943. private void refreshAll(PCardOwner summ, CardOwner owner) { mixin(S_TRACE);
  944. _owner = owner;
  945. _summ = summ;
  946. foreach (f; _pane) { mixin(S_TRACE);
  947. f.refreshAll(summ, owner);
  948. }
  949. static if (WithArea) {
  950. _areas.summary = summ;
  951. }
  952. if (_win && !_win.isDisposed()) { mixin(S_TRACE);
  953. refreshTitle();
  954. }
  955. }
  956. private void refreshStatusLine() { mixin(S_TRACE);
  957. if (!_win || _win.isDisposed()) return;
  958. static if (1 < Cards.length || WithArea) {
  959. int i = selectionCardIndex;
  960. string s = "";
  961. static if (WithArea) if (_tabf.getSelectionIndex() == areaIndex) s = _areas.statusLine;
  962. static if (UseCast) if (i == CAST) s = _pane[CAST].statusLine;
  963. static if (UseSkill) if (i == SKILL) s = _pane[SKILL].statusLine;
  964. static if (UseItem) if (i == ITEM) s = _pane[ITEM].statusLine;
  965. static if (UseBeast) if (i == BEAST) s = _pane[BEAST].statusLine;
  966. static if (UseInfo) if (i == INFO) s = _pane[INFO].statusLine;
  967. _comm.setStatusLine(_tabf, s);
  968. } else { mixin(S_TRACE);
  969. _comm.setStatusLine(_comp, _pane[0].statusLine);
  970. }
  971. }
  972. override {
  973. void cut(SelectionEvent se) { mixin(S_TRACE);
  974. static if (EditMode) {
  975. foreach (c; _tcpd) { mixin(S_TRACE);
  976. if (c.canDoTCPD) { mixin(S_TRACE);
  977. c.cut(se);
  978. }
  979. }
  980. }
  981. }
  982. void copy(SelectionEvent se) { mixin(S_TRACE);
  983. foreach (c; _tcpd) { mixin(S_TRACE);
  984. if (c.canDoTCPD) { mixin(S_TRACE);
  985. c.copy(se);
  986. }
  987. }
  988. }
  989. void paste(SelectionEvent se) { mixin(S_TRACE);
  990. static if (EditMode) {
  991. foreach (c; _tcpd) { mixin(S_TRACE);
  992. if (c.canDoTCPD) { mixin(S_TRACE);
  993. c.paste(se);
  994. }
  995. }
  996. }
  997. }
  998. void del(SelectionEvent se) { mixin(S_TRACE);
  999. static if (EditMode) {
  1000. foreach (c; _tcpd) { mixin(S_TRACE);
  1001. if (c.canDoTCPD) { mixin(S_TRACE);
  1002. c.del(se);
  1003. }
  1004. }
  1005. }
  1006. }
  1007. void clone(SelectionEvent se) { mixin(S_TRACE);
  1008. static if (EditMode) {
  1009. foreach (c; _tcpd) { mixin(S_TRACE);
  1010. if (c.canDoTCPD) { mixin(S_TRACE);
  1011. c.clone(se);
  1012. }
  1013. }
  1014. }
  1015. }
  1016. bool canDoTCPD() { mixin(S_TRACE);
  1017. return EditMode;
  1018. }
  1019. @property
  1020. bool canDoT() { mixin(S_TRACE);
  1021. foreach (c; _tcpd) { mixin(S_TRACE);
  1022. if (c.canDoTCPD) return c.canDoT;
  1023. }
  1024. return false;
  1025. }
  1026. @property
  1027. bool canDoC() { mixin(S_TRACE);
  1028. foreach (c; _tcpd) { mixin(S_TRACE);
  1029. if (c.canDoTCPD) return c.canDoC;
  1030. }
  1031. return false;
  1032. }
  1033. @property
  1034. bool canDoP() { mixin(S_TRACE);
  1035. foreach (c; _tcpd) { mixin(S_TRACE);
  1036. if (c.canDoTCPD) return c.canDoP;
  1037. }
  1038. return false;
  1039. }
  1040. @property
  1041. bool canDoD() { mixin(S_TRACE);
  1042. foreach (c; _tcpd) { mixin(S_TRACE);
  1043. if (c.canDoTCPD) return c.canDoD;
  1044. }
  1045. return false;
  1046. }
  1047. @property
  1048. bool canDoClone() { mixin(S_TRACE);
  1049. foreach (c; _tcpd) { mixin(S_TRACE);
  1050. if (c.canDoTCPD) return c.canDoClone;
  1051. }
  1052. return false;
  1053. }
  1054. }
  1055. private Ret selectPane(Ret, string Method, bool Area = true)() { mixin(S_TRACE);
  1056. static if (is(Ret:void)) {
  1057. static immutable R = "";
  1058. } else {
  1059. static immutable R = "r = ";
  1060. Ret r;
  1061. }
  1062. static if (1 < Cards.length || WithArea) {
  1063. int i = selectionCardIndex;
  1064. static if (WithArea && Area) {
  1065. if (i == areaIndex) mixin(R ~ "_areas." ~ Method ~ "();");
  1066. }
  1067. static if (UseCast) {
  1068. if (i == CAST) mixin(R ~ "_pane[CAST]." ~ Method ~ "();");
  1069. }
  1070. static if (UseSkill) {
  1071. if (i == SKILL) mixin(R ~ "_pane[SKILL]." ~ Method ~ "();");
  1072. }
  1073. static if (UseItem) {
  1074. if (i == ITEM) mixin(R ~ "_pane[ITEM]." ~ Method ~ "();");
  1075. }
  1076. static if (UseBeast) {
  1077. if (i == BEAST) mixin(R ~ "_pane[BEAST]." ~ Method ~ "();");
  1078. }
  1079. static if (UseInfo) {
  1080. if (i == INFO) mixin(R ~ "_pane[INFO]." ~ Method ~ "();");
  1081. }
  1082. } else { mixin(S_TRACE);
  1083. mixin(R ~ "_pane[0]." ~ Method ~ "();");
  1084. }
  1085. static if (!is(Ret:void)) {
  1086. return r;
  1087. }
  1088. }
  1089. void edit() { mixin(S_TRACE);
  1090. selectPane!(void, "edit")();
  1091. }
  1092. @property
  1093. bool canEdit() { mixin(S_TRACE);
  1094. return selectPane!(bool, "canEdit")();
  1095. }
  1096. static if (UseCast) {
  1097. void editHand() { mixin(S_TRACE);
  1098. static if (1 < Cards.length || WithArea) {
  1099. int i = selectionCardIndex;
  1100. static if (UseCast) {
  1101. if (i == CAST) _pane[CAST].edit();
  1102. }
  1103. } else { mixin(S_TRACE);
  1104. _pane[0].editHand();
  1105. }
  1106. }
  1107. @property
  1108. bool canEditHand() { mixin(S_TRACE);
  1109. static if (1 < Cards.length || WithArea) {
  1110. int i = selectionCardIndex;
  1111. static if (UseCast) {
  1112. if (i == CAST) return _pane[CAST].canEdit;
  1113. }
  1114. return false;
  1115. } else { mixin(S_TRACE);
  1116. return _pane[0].canEdit;
  1117. }
  1118. }
  1119. }
  1120. static if (EditMode) {
  1121. void reNumbering() { mixin(S_TRACE);
  1122. selectPane!(void, "reNumbering")();
  1123. }
  1124. @property
  1125. bool canReNumbering() { mixin(S_TRACE);
  1126. return selectPane!(bool, "canReNumbering")();
  1127. }
  1128. bool canUndo() { mixin(S_TRACE);
  1129. return selectPane!(bool, "canUndo")();
  1130. }
  1131. bool canRedo() { mixin(S_TRACE);
  1132. return selectPane!(bool, "canRedo")();
  1133. }
  1134. void undo() { mixin(S_TRACE);
  1135. selectPane!(void, "undo")();
  1136. }
  1137. void redo() { mixin(S_TRACE);
  1138. selectPane!(void, "redo")();
  1139. }
  1140. bool canUp() { mixin(S_TRACE);
  1141. return selectPane!(bool, "canUp")();
  1142. }
  1143. bool canDown() { mixin(S_TRACE);
  1144. return selectPane!(bool, "canDown")();
  1145. }
  1146. void up() { mixin(S_TRACE);
  1147. selectPane!(void, "up")();
  1148. }
  1149. void down() { mixin(S_TRACE);
  1150. selectPane!(void, "down")();
  1151. }
  1152. void replaceID() {
  1153. selectPane!(void, "replaceID")();
  1154. }
  1155. @property
  1156. bool canReplaceID() {
  1157. return selectPane!(bool, "canReplaceID")();
  1158. }
  1159. } else {
  1160. void doImport() { mixin(S_TRACE);
  1161. selectPane!(void, "doImport")();
  1162. }
  1163. @property
  1164. bool canDoImport() { mixin(S_TRACE);
  1165. return selectPane!(bool, "canDoImport")();
  1166. }
  1167. }
  1168. static if (is(CardOwner:CastCard) && EditMode) {
  1169. void removeRef() { mixin(S_TRACE);
  1170. selectPane!(void, "removeRef", false)();
  1171. }
  1172. @property
  1173. bool canRemoveRef() { mixin(S_TRACE);
  1174. return selectPane!(bool, "canRemoveRef", false)();
  1175. }
  1176. }
  1177. static if (UseSkill || UseItem || UseBeast) {
  1178. void editUseEvent() { mixin(S_TRACE);
  1179. static if (1 < Cards.length || WithArea) {
  1180. int i = selectionCardIndex;
  1181. static if (UseSkill) {
  1182. if (i == SKILL) _pane[SKILL].editUseEvent();
  1183. }
  1184. static if (UseItem) {
  1185. if (i == ITEM) _pane[ITEM].editUseEvent();
  1186. }
  1187. static if (UseBeast) {
  1188. if (i == BEAST) _pane[BEAST].editUseEvent();
  1189. }
  1190. } else { mixin(S_TRACE);
  1191. _pane[0].editUseEvent();
  1192. }
  1193. }
  1194. @property
  1195. bool canEditUseEvent() { mixin(S_TRACE);
  1196. static if (1 < Cards.length || WithArea) {
  1197. int i = selectionCardIndex;
  1198. static if (UseSkill) {
  1199. if (i == SKILL) return _pane[SKILL].canEdit;
  1200. }
  1201. static if (UseItem) {
  1202. if (i == ITEM) return _pane[ITEM].canEdit;
  1203. }
  1204. static if (UseBeast) {
  1205. if (i == BEAST) return _pane[BEAST].canEdit;
  1206. }
  1207. return false;
  1208. } else { mixin(S_TRACE);
  1209. return _pane[0].canEdit;
  1210. }
  1211. }
  1212. }
  1213. bool isSelected() { mixin(S_TRACE);
  1214. return selectPane!(bool, "isSelected")();
  1215. }
  1216. @property
  1217. private int selectionCardIndex() { mixin(S_TRACE);
  1218. static if (1 < Cards.length || WithArea) {
  1219. int i = _tabf.getSelectionIndex();
  1220. static if (WithArea) i++;
  1221. return i;
  1222. } else {
  1223. return 0;
  1224. }
  1225. }
  1226. static if (WithArea) {
  1227. @property
  1228. private int areaIndex() { return 0; }
  1229. }
  1230. private bool openCWXPathEff(int C)(string path, bool shellActivate) { mixin(S_TRACE);
  1231. auto cate = cpcategory(path);
  1232. if (std.string.endsWith(cate, "view")) { mixin(S_TRACE);
  1233. .forceFocus(_pane[C].widget, shellActivate);
  1234. return true;
  1235. }
  1236. auto index = cpindex(path);
  1237. bool isId = std.string.endsWith(cate, ":id") != 0;
  1238. alias typeof(_pane[C].cards()[0]) CType;
  1239. CType card;
  1240. if (isId) { mixin(S_TRACE);
  1241. card = _pane[C].card(index);
  1242. if (!card) return false;
  1243. index = .cCountUntil!("a is b")(_pane[C].cards, card);
  1244. } else { mixin(S_TRACE);
  1245. if (index >= _pane[C].cards.length) return false;
  1246. card = _pane[C].cards[index];
  1247. }
  1248. path = cpbottom(path);
  1249. if (cpempty(path) || (is(CType : MotionOwner) && "motion" == cpcategory(path))) { mixin(S_TRACE);
  1250. if (!cphasattr(path, "nofocus")) .forceFocus(_pane[C].widget, shellActivate);
  1251. _pane[C].select(index);
  1252. _comm.refreshToolBar();
  1253. static if (EditMode) {
  1254. if (cphasattr(path, "opendialog")) { mixin(S_TRACE);
  1255. auto dlg = _pane[C].edit();
  1256. if (!dlg) return false;
  1257. if (!cpempty(path)) { mixin(S_TRACE);
  1258. return dlg.openCWXPath(path, shellActivate);
  1259. }
  1260. }
  1261. }
  1262. return true;
  1263. }
  1264. static if (is(PCardOwner : Summary)) {
  1265. static if (UseCast && C == CAST) {
  1266. cate = cpcategory(path);
  1267. switch (cate) {
  1268. case "skillcard", "itemcard", "beastcard",
  1269. "skillcard:id", "itemcard:id", "beastcard:id",
  1270. "skillcardview", "itemcardview", "beastcardview": { mixin(S_TRACE);
  1271. if (!cphasattr(path, "nofocus")) forceFocus(_pane[C].widget, shellActivate);
  1272. return _comm.openHands(_prop, _summ, card, shellActivate).openCWXPath(path, shellActivate);
  1273. } break;
  1274. default: break;
  1275. }
  1276. } else static if (!UseInfo || C != INFO) {
  1277. if (cpcategory(path) == "event") { mixin(S_TRACE);
  1278. if (!cphasattr(path, "nofocus")) forceFocus(_pane[C].widget, shellActivate);
  1279. return _comm.openUseEvents(_prop, _summ, card, shellActivate).openCWXPath(path, shellActivate);
  1280. }
  1281. }
  1282. }
  1283. return false;
  1284. }
  1285. override
  1286. bool openCWXPath(string path, bool shellActivate) { mixin(S_TRACE);
  1287. auto cate = cpcategory(path);
  1288. switch (cate) {
  1289. case "castcard", "castcard:id", "castcardview": { mixin(S_TRACE);
  1290. static if (UseCast) {
  1291. return openCWXPathEff!(CAST)(path, shellActivate);
  1292. }
  1293. } break;
  1294. case "skillcard", "skillcard:id", "skillcardview": { mixin(S_TRACE);
  1295. static if (UseSkill) {
  1296. return openCWXPathEff!(SKILL)(path, shellActivate);
  1297. }
  1298. } break;
  1299. case "itemcard", "itemcard:id", "itemcardview": { mixin(S_TRACE);
  1300. static if (UseItem) {
  1301. return openCWXPathEff!(ITEM)(path, shellActivate);
  1302. }
  1303. } break;
  1304. case "beastcard", "beastcard:id", "beastcardview": { mixin(S_TRACE);
  1305. static if (UseBeast) {
  1306. return openCWXPathEff!(BEAST)(path, shellActivate);
  1307. }
  1308. } break;
  1309. case "infocard", "infocard:id", "infocardview": { mixin(S_TRACE);
  1310. static if (UseInfo) {
  1311. return openCWXPathEff!(INFO)(path, shellActivate);
  1312. }
  1313. } break;
  1314. default: break;
  1315. }
  1316. return false;
  1317. }
  1318. @property
  1319. override
  1320. string[] openedCWXPath() { mixin(S_TRACE);
  1321. string[] r;
  1322. static if (EditMode) {
  1323. static if (1 < Cards.length || WithArea) {
  1324. string[] last;
  1325. foreach (i, pane; _pane) { mixin(S_TRACE);
  1326. if (selectionCardIndex == i) { mixin(S_TRACE);
  1327. last = pane.openedCWXPath;
  1328. } else { mixin(S_TRACE);
  1329. r ~= pane.openedCWXPath;
  1330. }
  1331. }
  1332. r ~= last;
  1333. } else { mixin(S_TRACE);
  1334. r ~= _pane[0].openedCWXPath;
  1335. }
  1336. }
  1337. return r;
  1338. }
  1339. }
  1340. alias CardWindow!(CardWindowKind.ImportSourceHand, Summary, CastCard, Summary, false, SkillCard, ItemCard, BeastCard) AddHandCardWindow;
  1341. alias CardWindow!(CardWindowKind.Hand, Summary, CastCard, void, false, SkillCard, ItemCard, BeastCard) HandCardWindow;
  1342. alias CardWindow!(CardWindowKind.Main, Summary, Summary, void, false, CastCard, SkillCard, ItemCard, BeastCard, InfoCard) MainCardWindow;
  1343. alias CardWindow!(CardWindowKind.Cast, Summary, Summary, void, false, CastCard) CastCardWindow;
  1344. alias CardWindow!(CardWindowKind.Skill, Summary, Summary, void, false, SkillCard) SkillCardWindow;
  1345. alias CardWindow!(CardWindowKind.Item, Summary, Summary, void, false, ItemCard) ItemCardWindow;
  1346. alias CardWindow!(CardWindowKind.Beast, Summary, Summary, void, false, BeastCard) BeastCardWindow;
  1347. alias CardWindow!(CardWindowKind.Info, Summary, Summary, void, false, InfoCard) InfoCardWindow;
  1348. private class DelTemp : DisposeListener {
  1349. private Summary _cc;
  1350. this (Summary cc) { mixin(S_TRACE);
  1351. _cc = cc;
  1352. }
  1353. override void widgetDisposed(DisposeEvent dse) { mixin(S_TRACE);
  1354. try { mixin(S_TRACE);
  1355. _cc.delTemp();
  1356. } catch (Exception e) {
  1357. debugln(e);
  1358. }
  1359. }
  1360. }
  1361. class AddCard {
  1362. private:
  1363. alias CardWindow!(CardWindowKind.ImportSource, Summary, Summary, Summary, true, CastCard, SkillCard, ItemCard, BeastCard, InfoCard) ACW;
  1364. static class AddS {
  1365. Commons comm;
  1366. Props prop;
  1367. Composite parent;
  1368. Summary toc;
  1369. void delegate(Object[]) addScenario;
  1370. this (Commons comm, Props prop,
  1371. Composite parent, Summary toc, void delegate(Object[]) addScenario) { mixin(S_TRACE);
  1372. this.comm = comm;
  1373. this.prop = prop;
  1374. this.parent = parent;
  1375. this.toc = toc;
  1376. this.addScenario = addScenario;
  1377. }
  1378. void addS(Summary[] ccs) { mixin(S_TRACE);
  1379. ACW[] r;
  1380. foreach (i, cc; ccs) { mixin(S_TRACE);
  1381. if (cc) { mixin(S_TRACE);
  1382. auto shl = cast(Shell) parent;
  1383. auto pane = shl && !comm.singleWindowMode(prop) ? parent : comm.sidePane;
  1384. auto acw = new ACW(comm, prop, pane, cc, cc, toc);
  1385. acw.shell.addDisposeListener(new DelTemp(cc));
  1386. r ~= acw;
  1387. }
  1388. }
  1389. addScenario(cast(Object[]) r);
  1390. }
  1391. }
  1392. this() {}
  1393. static Composite pane(Composite parent) { mixin(S_TRACE);
  1394. auto shl = cast(Shell) parent;
  1395. if (shl) { mixin(S_TRACE);
  1396. return topShell(shl);
  1397. } else { mixin(S_TRACE);
  1398. return parent;
  1399. }
  1400. }
  1401. static LoadOption loadOption(in Props prop) { mixin(S_TRACE);
  1402. LoadOption opt;
  1403. opt.cardOnly = false; // ????????????????????????
  1404. opt.textOnly = false;
  1405. opt.doubleIO = prop.var.etc.doubleIO;
  1406. opt.expandXMLs = false;
  1407. return opt;
  1408. }
  1409. public:
  1410. static void openScenario(Commons comm, Props prop, Composite parent, void delegate(string) status,
  1411. Summary summ, Summary toc, void delegate(Object[]) addScenario) { mixin(S_TRACE);
  1412. parent = pane(parent);
  1413. auto addS = new AddS(comm, prop, parent, toc, addScenario);
  1414. loadScenarios(prop, loadOption(prop), comm.mainShell, status, prop.msgs.dlgTitAddScenario, &addS.addS);
  1415. }
  1416. static void openScenario(Commons comm, Props prop, Composite parent, void delegate(string) status,
  1417. Summary summ, Summary toc, string[] files, void delegate(Object[]) addScenario) { mixin(S_TRACE);
  1418. parent = pane(parent);
  1419. auto addS = new AddS(comm, prop, parent, toc, addScenario);
  1420. loadScenariosFromFile(prop, loadOption(prop), comm.mainShell, status, files, &addS.addS);
  1421. }
  1422. }