comparison mde/content/ServiceContent.d @ 170:e45226d3deae

Context menu services not applicable to the current type can now be hidden. Added files missing from previous commits.
author Diggory Hardy <diggory.hardy@gmail.com>
date Mon, 29 Jun 2009 21:20:16 +0200
parents mde/content/Services.d@1125ba603af6
children 7f7b2011b759
comparison
equal deleted inserted replaced
169:bc1cf73dc835 170:e45226d3deae
1 /* LICENSE BLOCK
2 Part of mde: a Modular D game-oriented Engine
3 Copyright © 2007-2009 Diggory Hardy
4
5 This program is free software: you can redistribute it and/or modify it under the terms
6 of the GNU General Public License as published by the Free Software Foundation, either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 See the GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>. */
15
16 /** Content services.
17 *
18 * Each is a Content, so it can be used in a menu. Since the content being
19 * acted on is not passed when functions are called like this, it is set when
20 * a context menu is opened, which also allows the services to specify their
21 * compatibility with the content (type) passed (via BoolContent value and
22 * callbacks).
23 */
24 module mde.content.ServiceContent;
25
26 import mde.content.AStringContent;
27
28 /** Interface for ServiceContent and ServiceContentList. */
29 interface IServiceContent {
30 void setContent (Content cont);
31 }
32
33 /** A class for services acting on content.
34 *
35 * Provides services for any content usable as type T, where T is some content
36 * type.
37 *
38 * The (boolean) value is true to indicate this service can act on the passed
39 * content type, false if not. */
40 class ServiceContent(T : Content = AStringContent) : Content, IServiceContent, IBoolContent, IEventContent {
41 this (char[] symbol) {
42 super (symbol);
43 }
44
45 /** Pass the content this service should prepare for.
46 *
47 * Stores the reference, because it won't be passed later. */
48 override void setContent (Content cont) {
49 activeCont = cast(T)cont;
50 }
51
52 override bool opCall () {
53 return activeCont is null;
54 }
55 // Doesn't support directly setting the value
56 override void opAssign (bool val) {}
57
58 package:
59 T activeCont;
60 }
61
62 /** Aliases for common types */
63 alias ServiceContent!(AStringContent) AStringService;
64 alias ServiceContent!(IntContent) IntService; ///ditto
65
66 /** A generic way to handle a list of type IContent. */
67 class ServiceContentList : ContentList, IServiceContent, IBoolContent
68 {
69 this (char[] symbol) {
70 super (symbol);
71 }
72
73 void setContent (Content cont) {
74 foreach (child; list_) {
75 debug assert (cast(IServiceContent)child !is null);
76 (cast(IServiceContent)child).setContent (cont);
77 }
78 }
79
80 override bool opCall () {
81 foreach (child; list_) {
82 debug assert (cast(IBoolContent)child !is null);
83 if (!(cast(IBoolContent)child)())
84 return false;
85 }
86 return true;
87 }
88 // Doesn't support directly setting the value
89 override void opAssign (bool val) {}
90 }
91
92 /** Create all services.
93 *
94 * For now, all are under the menu.
95 *
96 * Currently all clipboard operations convert to/from a string.
97 * TODO: Possible extensions: multi-item clipboard displaying value in menu,
98 * copying without converting everything to/from a string. */
99 static this () {
100 // Create ContentLists so they have the correct type.
101 new ServiceContentList ("menus.services");
102 // Many use callbacks on a generic class type. For this, we should be sure of the type.
103 auto copy = new AStringService("menus.services.copy");
104 copy.addCallback ((IContent c) {
105 debug assert (cast(AStringService)c);
106 with (cast(AStringService)c) {
107 if (activeCont !is null)
108 clipboard = activeCont.toString(0);
109 }
110 });
111 auto paste = new AStringService("menus.services.paste");
112 paste.addCallback ((IContent c) {
113 debug assert (cast(AStringService)c);
114 with (cast(AStringService)c) {
115 if (activeCont !is null)
116 activeCont = clipboard;
117 }
118 });
119
120 new ServiceContentList("menus.services.calculator");
121 auto inc = new IntService("menus.services.calculator.increment");
122 inc.addCallback ((IContent c) {
123 debug assert (cast(IntService)c);
124 with (cast(IntService)c) {
125 if (activeCont !is null)
126 activeCont = activeCont()+1;
127 }
128 });
129 auto dec = new IntService("menus.services.calculator.decrement");
130 dec.addCallback ((IContent c) {
131 debug assert (cast(IntService)c);
132 with (cast(IntService)c) {
133 if (activeCont !is null)
134 activeCont = activeCont()-1;
135 }
136 });
137 }
138 private {
139 char[] clipboard;
140 }