2 * Copyright 2011, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
7 #include "GroupListView.h"
14 class RendererLayoutItem
: public BAbstractLayout
{
16 RendererLayoutItem(BView
* owner
, int32 index
, void* item
,
17 ListItemRenderer
*& renderer
)
26 ListItemRenderer
* Renderer() const
28 fRenderer
->SetTo(fOwner
, fItem
);
42 virtual BSize
BaseMinSize()
44 fRenderer
->SetTo(fOwner
, fItem
);
45 return fRenderer
->MinSize();
48 virtual BSize
BasePreferredSize()
50 fRenderer
->SetTo(fOwner
, fItem
);
51 return fRenderer
->PreferredSize();
55 virtual void DoLayout()
57 // shouldn't ever be called?
64 ListItemRenderer
*& fRenderer
;
68 GroupListView::GroupListView(const char* name
, GroupListModel
* model
,
69 enum orientation orientation
, float spacing
)
71 BView(NULL
, B_WILL_DRAW
, new BGroupLayout(orientation
, spacing
)),
75 fSelectionMessage(NULL
)
77 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
82 GroupListView::~GroupListView()
86 delete fGroupRenderer
;
87 delete fSelectionMessage
;
92 GroupListView::SetModel(GroupListModel
* model
)
94 // TODO: remove all previous
95 // TODO: add change mechanism
96 // TODO: use a "virtual" BGroupLayout (ie. one that create its layout items
100 std::map
<addr_t
, BGroupLayout
*> groupMap
;
102 int32 groupCount
= model
->CountGroups();
103 for (int groupIndex
= 0; groupIndex
< groupCount
; groupIndex
++) {
104 BGroupLayout
* groupItem
= new BGroupLayout(B_VERTICAL
, 0);
105 groupItem
->SetVisible(false);
108 void* group
= model
->GroupAt(groupIndex
);
109 groupMap
[(addr_t
)group
] = groupItem
;
110 groupItem
->AddItem(new RendererLayoutItem(this, groupIndex
, group
,
114 int32 itemCount
= model
->CountItems();
115 for (int itemIndex
= 0; itemIndex
< itemCount
; itemIndex
++) {
116 void* group
= model
->GroupForItemAt(itemIndex
);
120 BGroupLayout
* groupItem
= groupMap
[(addr_t
)group
];
121 if (groupItem
== NULL
)
124 groupItem
->SetVisible(true);
126 RendererLayoutItem
* rendererItem
= new RendererLayoutItem(this,
127 itemIndex
, model
->ItemAt(itemIndex
), fItemRenderer
);
128 groupItem
->AddItem(rendererItem
);
134 GroupListView::SetItemRenderer(ListItemRenderer
* renderer
)
136 fItemRenderer
= renderer
;
142 GroupListView::SetGroupRenderer(ListItemRenderer
* renderer
)
144 fGroupRenderer
= renderer
;
150 GroupListView::SetSelectionMessage(BMessage
* message
, BMessenger target
)
152 fSelectionMessage
= message
;
153 fSelectionTarget
= target
;
158 GroupListView::AttachedToWindow()
164 GroupListView::MessageReceived(BMessage
* message
)
166 switch (message
->what
) {
168 BView::MessageReceived(message
);
175 GroupListView::MouseDown(BPoint point
)
177 if (fSelectionMessage
== NULL
)
180 BLayoutItem
* item
= _ItemAt(GetLayout(), point
);
182 if (RendererLayoutItem
* rendererItem
183 = dynamic_cast<RendererLayoutItem
*>(item
)) {
184 BMessage
message(*fSelectionMessage
);
187 if (Window()->CurrentMessage() != NULL
)
188 buttons
= Window()->CurrentMessage()->FindInt32("buttons");
190 message
.AddInt32("buttons", buttons
);
191 message
.AddInt32("index", rendererItem
->Index());
192 message
.AddPointer(rendererItem
->Renderer() == fGroupRenderer
193 ? "group" : "item", rendererItem
->Item());
195 fSelectionTarget
.SendMessage(&message
);
201 GroupListView::Draw(BRect updateRect
)
203 _Draw(GetLayout(), updateRect
);
208 GroupListView::_Draw(BLayoutItem
* item
, BRect updateRect
)
210 if (RendererLayoutItem
* rendererItem
211 = dynamic_cast<RendererLayoutItem
*>(item
)) {
212 ListItemRenderer
* renderer
= rendererItem
->Renderer();
213 renderer
->Draw(this, rendererItem
->Frame(), rendererItem
->Index(),
215 } else if (BLayout
* layout
= dynamic_cast<BLayout
*>(item
)) {
216 for (int i
= 0; i
< layout
->CountItems(); i
++) {
217 item
= layout
->ItemAt(i
);
218 if (!item
->IsVisible() || !item
->Frame().Intersects(updateRect
))
221 _Draw(item
, updateRect
);
228 GroupListView::_ItemAt(BLayoutItem
* item
, BPoint point
)
230 if (RendererLayoutItem
* rendererItem
231 = dynamic_cast<RendererLayoutItem
*>(item
))
234 if (BLayout
* layout
= dynamic_cast<BLayout
*>(item
)) {
235 for (int i
= 0; i
< layout
->CountItems(); i
++) {
236 item
= layout
->ItemAt(i
);
237 if (!item
->IsVisible() || !item
->Frame().Contains(point
))
240 return _ItemAt(item
, point
);