Mercurial > projects > mde
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 } |