-
Notifications
You must be signed in to change notification settings - Fork 2
/
MBLayoutItemFactory.m
340 lines (276 loc) · 14.6 KB
/
MBLayoutItemFactory.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
/*
Copyright (C) 2010 Quentin Mathe
Author: Quentin Mathe <quentin.mathe@gmail.com>
Date: September 2010
License: Modified BSD (see COPYING)
*/
#import <IconKit/IconKit.h>
#import "MBLayoutItemFactory.h"
#import "ETModelRepository.h"
#import "MBPackageEditorController.h"
#import "MBRepositoryController.h"
@implementation MBLayoutItemFactory
- (ETOutlineLayout *) outlineLayoutForBrowser
{
ETOutlineLayout *layout = [ETOutlineLayout layoutWithObjectGraphContext: [self objectGraphContext]];
[layout setDisplayedProperties: A(@"displayName", @"typeDescription")];
[layout setDisplayName: @"Type" forProperty: @"typeDescription"];
[[layout columnForProperty: @"typeDescription"] setWidth: 100];
[[layout columnForProperty: @"displayName"] setWidth: 400];
return layout;
}
- (ETLayoutItem *) buttonWithIconNamed: (NSString *)aName target: (id)aTarget action: (SEL)anAction
{
return [self buttonWithImage: [[IKIcon iconWithIdentifier: aName] image] target: aTarget action: anAction];
}
- (NSSize) defaultEditorSize
{
return NSMakeSize(800, 500);
}
- (NSSize) defaultEditorBodySize
{
NSSize size = [self defaultEditorSize];
size.height -= [self defaultIconAndLabelBarHeight];
return size;
}
- (ETLayoutItemGroup *) editorWithPackageDescription: (ETPackageDescription *)aPackageDesc
{
MBPackageEditorController *controller = AUTORELEASE([[MBPackageEditorController alloc]
initWithObjectGraphContext: [self objectGraphContext]]);
ETLayoutItemGroup *topbar = [self editorTopbarWithController: controller];
ETLayoutItemGroup *body = [self editorBodyWithPackageDescription: aPackageDesc controller: controller];
ETLayoutItemGroup *editor = [self itemGroupWithItems: A(topbar, body)];
[editor setAutoresizingMask: ETAutoresizingFlexibleWidth | ETAutoresizingFlexibleHeight];
[editor setController: controller];
[editor setRepresentedObject: aPackageDesc]; /* For MBAppController template lookup needs */
[editor setShouldMutateRepresentedObject: NO];
[editor setLayout: [ETColumnLayout layoutWithObjectGraphContext: [self objectGraphContext]]];
[editor setSize: [self defaultEditorSize]];
return editor;
}
- (ETLayoutItemGroup *) editorBodyWithPackageDescription: (ETPackageDescription *)aPackageDesc controller: (id)aController
{
ETLayoutItemGroup *sourceList = [self sourceListWithPackageDescription: aPackageDesc controller: aController];
ETLayoutItemGroup *entityView = [self entityViewWithEntityDescription: [[aPackageDesc contentArray] firstObject]
controller: aController];
ETLayoutItemGroup *body = [self itemGroupWithRepresentedObject: aPackageDesc];
NSLog(@"Entities %@", [aPackageDesc contentArray]);
[body setAutoresizingMask: ETAutoresizingFlexibleWidth | ETAutoresizingFlexibleHeight];
[body setSize: [self defaultEditorBodySize]]; // FIXME: Avoid negative size if -setSize: is not called
[body setLayout: [ETLineLayout layoutWithObjectGraphContext: [self objectGraphContext]]];
[body addItems: A(sourceList, entityView)];
return body;
}
- (ETLayoutItem *) viewPopUpWithController: (MBPackageEditorController *)aController
{
NSArray *choices = A(_(@"Properties"), _(@"Operations"), _(@"Instances"));
ETLayoutItem *popUpItem = [self popUpMenuWithItemTitles: choices
representedObjects: nil
target: aController
action: @selector(changePresentedContent:)];
[aController setViewPopUpItem: popUpItem];
return popUpItem;
}
- (ETLayoutItem *) modelLayerPopUpWithController: (MBPackageEditorController *)aController
{
NSArray *choices = A(_(@"Model (M1)"), _(@"Metamodel (M2)"), _(@"Meta-metamodel (M3)"));
ETLayoutItem *popUpItem = [self popUpMenuWithItemTitles: choices
representedObjects: nil
target: aController
action: @selector(changePresentedModelLayer:)];
[(NSPopUpButton *)[popUpItem view] selectItemWithTitle: _(@"Metamodel (M2)")];
[aController setModelLayerPopUpItem: popUpItem];
return popUpItem;
}
- (ETLayoutItemGroup *) editorTopbarWithController: (id)aController
{
ETLayoutItemGroup *itemGroup = [self itemGroup];
ETLayoutItem *addPropertyItem = [self buttonWithIconNamed: @"list-add"
target: aController
action: @selector(addProperty:)];
ETLayoutItem *removeItem = [self buttonWithIconNamed: @"list-remove"
target: aController
action: @selector(remove:)];
ETLayoutItem *searchFieldItem = [self searchFieldWithTarget: aController
action: @selector(searchPackageDescription:)];
//ETLayoutItemGroup *searchItemGroup = [self itemGroupWithItem: searchFieldItem];
[itemGroup setWidth: [self defaultEditorSize].width];
[itemGroup setHeight: [self defaultIconAndLabelBarHeight]];
[itemGroup setLayout: [ETLineLayout layoutWithObjectGraphContext: [self objectGraphContext]]];
[[itemGroup layout] setSeparatorTemplateItem: [self flexibleSpaceSeparator]];
[itemGroup addItems:
A([self barElementFromItem: addPropertyItem withLabel: _(@"Add Property")],
[self barElementFromItem: removeItem withLabel: _(@"Remove")],
[self barElementFromItem: [self modelLayerPopUpWithController: aController] withLabel: _(@"Model Layer")],
[self barElementFromItem: [self viewPopUpWithController: aController] withLabel: _(@"Entity View")],
[self barElementFromItem: searchFieldItem withLabel: _(@"Filter")])];
return itemGroup;
}
- (ETLayoutItemGroup *) sourceListWithPackageDescription: (ETPackageDescription *)aPackageDesc controller: (id)aController
{
ETLayoutItemGroup *itemGroup = [self itemGroupWithRepresentedObject: aPackageDesc];
ETController *controller =
AUTORELEASE([[ETController alloc] initWithObjectGraphContext: [self objectGraphContext]]);
ETUTI *entityDescType = [ETUTI typeWithClass: [ETEntityDescription class]];
ETItemTemplate *metamodelTemplate = [ETItemTemplate templateWithItem: [self item]
objectClass: [ETEntityDescription class]
objectGraphContext: [self objectGraphContext]];
ETItemTemplate *modelTemplate = [ETItemTemplate templateWithItem: [self item]
objectClass: [ETAdaptiveModelObject class]
objectGraphContext: [self objectGraphContext]];
/* The current object type is controlled by -[MBPackageEditorController updatePresentedModelLayer] */
[controller setTemplate: metamodelTemplate
forType: entityDescType];
[controller setTemplate: modelTemplate
forType: [ETUTI typeWithClass: [ETAdaptiveModelObject class]]];
[controller setCurrentObjectType: entityDescType];
[itemGroup setController: controller];
[itemGroup setAutoresizingMask: ETAutoresizingFlexibleHeight];
[itemGroup setHeight: [self defaultEditorBodySize].height];
[itemGroup setWidth: 250];
[itemGroup setSource: itemGroup];
[itemGroup setLayout: [ETTableLayout layoutWithObjectGraphContext: [self objectGraphContext]]];
[[itemGroup layout] setDisplayedProperties: A(@"name")];
[[[itemGroup layout] columnForProperty: @"name"] setWidth: 250];
[itemGroup setHasVerticalScroller: YES];
[itemGroup reload];
[aController setSourceListItem: itemGroup];
[aController startObserveObject: itemGroup
forNotificationName: ETItemGroupSelectionDidChangeNotification
selector: @selector(sourceListSelectionDidChange:)];
return itemGroup;
}
- (ETLayoutItemGroup *) entityViewWithEntityDescription: (ETEntityDescription *)anEntityDesc controller: (id)aController
{
ETLayoutItemGroup *itemGroup = [self itemGroupWithRepresentedObject: anEntityDesc];
ETTableLayout *layout = [ETTableLayout layoutWithObjectGraphContext: [self objectGraphContext]];
NSArray *headerNames = A(@"Name", @"Item Identifier", @"Derived",
@"Container", @"Multivalued", @"Ordered", @"Opposite", @"Type", @"Role");
[layout setDisplayedProperties: A(@"name", @"itemIdentifier", @"derived",
@"container", @"multivalued", @"ordered", @"opposite", @"type", @"role")];
// FIXME: Assertion at ETCollection+HOM.m:885
/*[[layout displayedProperties] zipWithCollection: headerNames andBlock:
^ void (NSString *property, NSString *headerName)
{
[layout setDisplayName: headerName forProperty: property];
}];
or
[[layout displayedProperties] enumerateObjectsUsingBlock:
^ void (id obj, NSUInteger i, BOOL stop*)
{
[layout setDisplayName: [headerNames objectAtIndex: i] forProperty: obj];
}*/
NSUInteger n = [[layout displayedProperties] count];
for (NSUInteger i = 0; i < n; i++)
{
[layout setDisplayName: [headerNames objectAtIndex: i]
forProperty: [[layout displayedProperties] objectAtIndex: i]];
}
ETController *controller = AUTORELEASE([[MBEntityViewController alloc]
initWithObjectGraphContext: [self objectGraphContext]]);
/* The controller templates are set up in -[MBEntityViewController init] */
[itemGroup setController: controller];
[itemGroup setAutoresizingMask: ETAutoresizingFlexibleWidth | ETAutoresizingFlexibleHeight];
[itemGroup setHeight: [self defaultEditorBodySize].height];
[itemGroup setWidth: 550];
[itemGroup setHasVerticalScroller: YES];
[itemGroup setSource: itemGroup];
[itemGroup setLayout: layout];
[itemGroup reload];
[aController setEntityViewItem: itemGroup];
return itemGroup;
}
- (NSSize) defaultBrowserSize
{
return NSMakeSize(600, 300);
}
- (ETLayoutItemGroup *) browserWithCollection: (id <ETCollection>)elements
{
NSParameterAssert(elements != nil);
ETLayoutItemGroup *browser = [self itemGroupWithRepresentedObject: elements];
[browser setSource: browser];
[browser setAutoresizingMask: ETAutoresizingFlexibleWidth | ETAutoresizingFlexibleHeight];
[browser setWidth: [self defaultBrowserSize].width]; // FIXME: Avoid negative size if -setSize: is not called
[browser setHeight: [self defaultBrowserSize].height - [self defaultIconAndLabelBarHeight]];
[browser setLayout: [self outlineLayoutForBrowser]];
[browser setHasVerticalScroller: YES];
[browser reload];
return browser;
}
- (ETLayoutItemGroup *) browserWithDescriptionCollection: (id <ETCollection>)descriptions
{
ETLayoutItemGroup *browser = [self browserWithCollection: descriptions];
ETLog(@"Description collection %@", [descriptions contentArray]);
return browser;
}
- (ETLayoutItemGroup *) browserBottomBarWithController: (MBRepositoryController *)aController
{
ETLayoutItem *popUpItem = [self popUpMenuWithItemTitles: A(@"Metamodel | List", @"Metamodel", @"Model", @"", @"List", @"Column")
representedObjects: nil
target: aController
action: @selector(changeRepositoryPresentation:)];
NSPopUpButton *popUp = (NSPopUpButton *)[popUpItem view];
// TODO: Support that in ETLayoutItemFactory
[popUp setPullsDown: YES];
[[popUp itemWithTitle: _(@"List")] setState: NSOnState];
[[popUp itemWithTitle: _(@"Column")] setState: NSOffState];
[popUpItem sizeToFit];
ETLayoutItem *saveButtonItem = [self buttonWithIconNamed: @"drive-harddisk"
target: aController
action: @selector(save:)];
ETLayoutItem *checkButtonItem = [self buttonWithIconNamed: @"system-restart"
target: aController
action: @selector(checkRepositoryValidity:)];
ETLayoutItem *searchFieldItem = [self searchFieldWithTarget: aController
action: @selector(searchRepository:)];
ETLayoutItemGroup *itemGroup = [self itemGroupWithItems:
A([self barElementFromItem: popUpItem withLabel: _(@"View")],
[self flexibleSpaceSeparator],
[self barElementFromItem: saveButtonItem withLabel: _(@"Save")],
[self barElementFromItem: checkButtonItem withLabel: _(@"Check")],
[self flexibleSpaceSeparator],
[self barElementFromItem: searchFieldItem withLabel: _(@"Filter")])];
[itemGroup setAutoresizingMask: ETAutoresizingFlexibleWidth];
[itemGroup setWidth: [self defaultBrowserSize].width];
[itemGroup setHeight: [self defaultIconAndLabelBarHeight]];
[itemGroup setLayout: [ETLineLayout layoutWithObjectGraphContext: [self objectGraphContext]]];
return itemGroup;
}
- (ETLayoutItemGroup *) repositoryViewWithRepository: (ETModelRepository *)aRepo
{
ETLayoutItemGroup *repositoryView = [self browserWithCollection: [aRepo metaRepository]];
ETController *controller = AUTORELEASE([[ETController alloc]
initWithObjectGraphContext: [self objectGraphContext]]);
[repositoryView setController: controller];
return repositoryView;
}
- (ETLayoutItemGroup *) browserWithRepository: (ETModelRepository *)aRepo
{
MBRepositoryController *controller = AUTORELEASE([[MBRepositoryController alloc]
initWithObjectGraphContext: [self objectGraphContext]]);
ETLayoutItemGroup *repositoryView = [self repositoryViewWithRepository: aRepo];
ETLayoutItemGroup *bottomBar = [self browserBottomBarWithController: controller];
ETLayoutItemGroup *browser = [self itemGroupWithFrame: ETMakeRect(NSZeroPoint, [self defaultBrowserSize])];
[controller setRepositoryViewItem: repositoryView];
[browser setController: controller];
[browser setRepresentedObject: aRepo]; /* For MBRepositoryController needs */
[browser setShouldMutateRepresentedObject: NO];
[browser setAutoresizingMask: ETAutoresizingFlexibleWidth | ETAutoresizingFlexibleHeight];
[browser setLayout: [ETColumnLayout layoutWithObjectGraphContext: [self objectGraphContext]]];
[browser addItems: A(bottomBar, repositoryView)];
ETLog(@"\n%@\n", [browser descriptionWithOptions: [NSMutableDictionary dictionaryWithObjectsAndKeys:
A(@"frame", @"autoresizingMask"), kETDescriptionOptionValuesForKeyPaths,
@"items", kETDescriptionOptionTraversalKey, nil]]);
return browser;
}
- (ETLayoutItemGroup *) checkReportWithWarnings: (NSArray *)warnings
{
ETLayoutItemGroup *itemGroup = [self itemGroupWithRepresentedObject: warnings];
[itemGroup setName: _(@"Repository Check Warnings")];
[itemGroup setSource: itemGroup];
[itemGroup setAutoresizingMask: ETAutoresizingFlexibleWidth | ETAutoresizingFlexibleHeight];
[itemGroup setSize: [self defaultBrowserSize]]; // FIXME: Avoid negative size if -setSize: is not called
[itemGroup setLayout: [ETTableLayout layoutWithObjectGraphContext: [self objectGraphContext]]];
return itemGroup;
}
@end