1//CLVListItem source file
2
3
4//******************************************************************************************************
5//**** PROJECT HEADER FILES
6//******************************************************************************************************
7#define CLVListItem_CPP
8#include <stdio.h>
9#include "CLVListItem.h"
10#include "ColumnListView.h"
11#include "CLVColumn.h"
12#include "PrefilledBitmap.h"
13
14#include "InterfaceKit.h"
15
16//******************************************************************************************************
17//**** CLVItem CLASS DEFINITION
18//******************************************************************************************************
19CLVListItem::CLVListItem(uint32 level, bool superitem, bool expanded, float minheight)
20: BListItem(level, expanded),
21fExpanderButtonRect(-1.0,-1.0,-1.0,-1.0),
22fExpanderColumnRect(-1.0,-1.0,-1.0,-1.0),
23_selectedColumn(-1)
24{
25	fSuperItem = superitem;
26	fOutlineLevel = level;
27	fMinHeight = minheight;
28}
29
30
31CLVListItem::~CLVListItem()
32{ }
33
34
35bool CLVListItem::IsSuperItem() const
36{
37	return fSuperItem;
38}
39
40
41void CLVListItem::SetSuperItem(bool superitem)
42{
43	fSuperItem = superitem;
44}
45
46
47uint32 CLVListItem::OutlineLevel() const
48{
49	return fOutlineLevel;
50}
51
52void CLVListItem::SetOutlineLevel(uint32 level)
53{
54	fOutlineLevel = level;
55}
56
57void CLVListItem::Pulse(BView * owner)
58{
59    // empty
60}
61
62void CLVListItem::DrawItem(BView* owner, BRect itemRect, bool complete)
63{
64	BList* DisplayList = &((ColumnListView*)owner)->fColumnDisplayList;
65	int32 NumberOfColumns = DisplayList->CountItems();
66	float PushMax = itemRect.right;
67	CLVColumn* ThisColumn;
68	BRect ThisColumnRect = itemRect;
69	float ExpanderDelta = OutlineLevel() * 20.0;
70	//Figure out what the limit is for expanders pushing other columns
71	for(int32 Counter = 0; Counter < NumberOfColumns; Counter++)
72	{
73		ThisColumn = (CLVColumn*)DisplayList->ItemAt(Counter);
74		if((ThisColumn->fFlags & CLV_EXPANDER) || ThisColumn->fPushedByExpander)
75			PushMax = ThisColumn->fColumnEnd;
76	}
77	BRegion ClippingRegion;
78	if(!complete)
79		owner->GetClippingRegion(&ClippingRegion);
80	else
81		ClippingRegion.Set(itemRect);
82	float LastColumnEnd = -1.0;
83
84	//Draw the columns
85	for(int32 Counter = 0; Counter < NumberOfColumns; Counter++)
86	{
87		ThisColumn = (CLVColumn*)DisplayList->ItemAt(Counter);
88		if(!ThisColumn->IsShown())
89			continue;
90		ThisColumnRect.left = ThisColumn->fColumnBegin;
91		ThisColumnRect.right = LastColumnEnd = ThisColumn->fColumnEnd;
92		float Shift = 0.0;
93		if((ThisColumn->fFlags & CLV_EXPANDER) || ThisColumn->fPushedByExpander)
94			Shift = ExpanderDelta;
95		if(ThisColumn->fFlags & CLV_EXPANDER)
96		{
97			ThisColumnRect.right += Shift;
98			if(ThisColumnRect.right > PushMax)
99				ThisColumnRect.right = PushMax;
100			fExpanderColumnRect = ThisColumnRect;
101			if(ClippingRegion.Intersects(ThisColumnRect))
102			{
103				//Give the programmer a chance to do his kind of highlighting if the item is selected
104				int32 actualIndex = ((ColumnListView*)owner)->fColumnList.IndexOf(ThisColumn);
105				DrawItemColumn(owner, ThisColumnRect, actualIndex, (_selectedColumn == actualIndex), complete);
106				if(fSuperItem)
107				{
108					//Draw the expander, clip manually
109					float TopOffset = ceil((ThisColumnRect.bottom-ThisColumnRect.top-10.0)/2.0);
110					float LeftOffset = ThisColumn->fColumnEnd + Shift - 3.0 - 10.0;
111					float RightClip = LeftOffset + 10.0 - ThisColumnRect.right;
112					if(RightClip < 0.0)
113						RightClip = 0.0;
114					BBitmap* Arrow;
115					if(IsExpanded())
116						Arrow = &((ColumnListView*)owner)->fDownArrow;
117					else
118						Arrow = &((ColumnListView*)owner)->fRightArrow;
119					if(LeftOffset <= ThisColumnRect.right)
120					{
121						fExpanderButtonRect.Set(LeftOffset,ThisColumnRect.top+TopOffset,
122							LeftOffset+10.0-RightClip,ThisColumnRect.top+TopOffset+10.0);
123						owner->SetDrawingMode(B_OP_OVER);
124						owner->DrawBitmap(Arrow, BRect(0.0,0.0,10.0-RightClip,10.0),fExpanderButtonRect);
125						owner->SetDrawingMode(B_OP_COPY);
126					}
127					else
128						fExpanderButtonRect.Set(-1.0,-1.0,-1.0,-1.0);
129				}
130			}
131		}
132		else
133		{
134			ThisColumnRect.left += Shift;
135			ThisColumnRect.right += Shift;
136			if(Shift > 0.0 && ThisColumnRect.right > PushMax)
137				ThisColumnRect.right = PushMax;
138			if(ThisColumnRect.right >= ThisColumnRect.left && ClippingRegion.Intersects(ThisColumnRect))
139			{
140			    int32 actualIndex = ((ColumnListView*)owner)->fColumnList.IndexOf(ThisColumn);
141				DrawItemColumn(owner, ThisColumnRect, actualIndex, (_selectedColumn == actualIndex), complete);
142	        }
143		}
144	}
145	//Fill the area after all the columns (so the select highlight goes all the way across)
146	ThisColumnRect.left = LastColumnEnd + 1.0;
147	ThisColumnRect.right = owner->Bounds().right;
148	if(ThisColumnRect.left <= ThisColumnRect.right && ClippingRegion.Intersects(ThisColumnRect))
149    {
150		DrawItemColumn(owner, ThisColumnRect,-1, false, complete);
151	}
152}
153
154
155float CLVListItem::ExpanderShift(int32 column_index, BView* owner)
156{
157	BList* DisplayList = &((ColumnListView*)owner)->fColumnDisplayList;
158	CLVColumn* ThisColumn = (CLVColumn*)DisplayList->ItemAt(column_index);
159	float ExpanderDelta = OutlineLevel() * 20.0;
160	if(!ThisColumn->fPushedByExpander)
161		ExpanderDelta = 0.0;
162	return ExpanderDelta;
163}
164
165
166void CLVListItem::Update(BView* owner, const BFont* font)
167{
168	BListItem::Update(owner,font);
169	float ItemHeight = Height();
170	if(ItemHeight < fMinHeight)
171		ItemHeight = fMinHeight;
172	SetWidth(((ColumnListView*)owner)->fPageWidth);
173	SetHeight(ItemHeight);
174}
175