Fix FreeBSD build.
[haiku.git] / src / preferences / network / InterfaceListItem.cpp
blob02b62d304fd3ef49d21c6ebe88b7255633600e0c
1 /*
2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Alexander von Gluck IV, kallisti5@unixzen.com
7 * Philippe Houdoin
8 * Fredrik Modéen
9 * John Scipione, jscipione@gmail.com
13 #include "InterfaceListItem.h"
15 #include <algorithm>
17 #include <Application.h>
18 #include <Bitmap.h>
19 #include <Catalog.h>
20 #include <ControlLook.h>
21 #include <IconUtils.h>
22 #include <OutlineListView.h>
23 #include <Resources.h>
24 #include <String.h>
27 #define ICON_SIZE 32
30 #undef B_TRANSLATION_CONTEXT
31 #define B_TRANSLATION_CONTEXT "InterfaceListItem"
34 InterfaceListItem::InterfaceListItem(const char* name,
35 BNetworkInterfaceType type)
37 BListItem(0, false),
38 fType(type),
39 fIcon(NULL),
40 fFirstLineOffset(0),
41 fLineOffset(0),
42 fDisabled(false),
43 fHasLink(false),
44 fConnecting(false)
46 fInterface.SetTo(name);
47 _Init();
51 InterfaceListItem::~InterfaceListItem()
53 delete fIcon;
57 // #pragma mark - InterfaceListItem public methods
60 void
61 InterfaceListItem::DrawItem(BView* owner, BRect bounds, bool complete)
63 owner->PushState();
65 rgb_color lowColor = owner->LowColor();
67 if (IsSelected() || complete) {
68 if (IsSelected()) {
69 owner->SetHighColor(ui_color(B_LIST_SELECTED_BACKGROUND_COLOR));
70 owner->SetLowColor(owner->HighColor());
71 } else
72 owner->SetHighColor(lowColor);
74 owner->FillRect(bounds);
77 BBitmap* stateIcon = _StateIcon();
78 const char* stateText = _StateText();
80 // Set the initial bounds of item contents
81 BPoint iconPoint = bounds.LeftTop()
82 + BPoint(be_control_look->DefaultLabelSpacing(), 2);
83 BPoint statePoint = bounds.RightTop() + BPoint(0, fFirstLineOffset)
84 - BPoint(be_plain_font->StringWidth(stateText)
85 + be_control_look->DefaultLabelSpacing(), 0);
86 BPoint namePoint = bounds.LeftTop()
87 + BPoint(ICON_SIZE + (be_control_look->DefaultLabelSpacing() * 2),
88 fFirstLineOffset);
90 if (fDisabled) {
91 owner->SetDrawingMode(B_OP_ALPHA);
92 owner->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
93 owner->SetHighColor(0, 0, 0, 32);
94 } else
95 owner->SetDrawingMode(B_OP_OVER);
97 owner->DrawBitmapAsync(fIcon, iconPoint);
98 owner->DrawBitmapAsync(stateIcon, iconPoint);
100 if (fDisabled) {
101 rgb_color textColor;
102 if (IsSelected())
103 textColor = ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR);
104 else
105 textColor = ui_color(B_LIST_ITEM_TEXT_COLOR);
107 if (textColor.red + textColor.green + textColor.blue > 128 * 3)
108 owner->SetHighColor(tint_color(textColor, B_DARKEN_1_TINT));
109 else
110 owner->SetHighColor(tint_color(textColor, B_LIGHTEN_1_TINT));
111 } else {
112 if (IsSelected())
113 owner->SetHighColor(ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR));
114 else
115 owner->SetHighColor(ui_color(B_LIST_ITEM_TEXT_COLOR));
118 owner->SetFont(be_bold_font);
120 owner->DrawString(fDeviceName, namePoint);
121 owner->SetFont(be_plain_font);
122 owner->DrawString(stateText, statePoint);
124 BPoint linePoint = bounds.LeftTop()
125 + BPoint(ICON_SIZE + (be_control_look->DefaultLabelSpacing() * 2),
126 fFirstLineOffset + fLineOffset);
127 owner->DrawString(fSubtitle, linePoint);
129 owner->PopState();
133 void
134 InterfaceListItem::Update(BView* owner, const BFont* font)
136 BListItem::Update(owner, font);
137 font_height height;
138 font->GetHeight(&height);
140 float lineHeight = ceilf(height.ascent) + ceilf(height.descent)
141 + ceilf(height.leading);
143 fFirstLineOffset = 2 + ceilf(height.ascent + height.leading / 2);
144 fLineOffset = lineHeight;
146 _UpdateState();
148 SetWidth(fIcon->Bounds().Width() + 36
149 + be_control_look->DefaultLabelSpacing()
150 + be_bold_font->StringWidth(fDeviceName.String())
151 + owner->StringWidth(_StateText()));
152 SetHeight(std::max(2 * lineHeight + 4, fIcon->Bounds().Height() + 4));
153 // either to the text height or icon height, whichever is taller
157 void
158 InterfaceListItem::ConfigurationUpdated(const BMessage& message)
160 _UpdateState();
164 // #pragma mark - InterfaceListItem private methods
167 void
168 InterfaceListItem::_Init()
170 switch(fType) {
171 default:
172 case B_NETWORK_INTERFACE_TYPE_WIFI:
173 _PopulateBitmaps("wifi");
174 break;
175 case B_NETWORK_INTERFACE_TYPE_ETHERNET:
176 _PopulateBitmaps("ether");
177 break;
182 void
183 InterfaceListItem::_PopulateBitmaps(const char* mediaType)
185 const uint8* interfaceHVIF;
186 const uint8* offlineHVIF;
187 const uint8* pendingHVIF;
188 const uint8* onlineHVIF;
190 BBitmap* interfaceBitmap = NULL;
192 BResources* resources = BApplication::AppResources();
194 size_t iconSize;
196 // Try specific interface icon?
197 interfaceHVIF = (const uint8*)resources->LoadResource(
198 B_VECTOR_ICON_TYPE, Name(), &iconSize);
200 if (interfaceHVIF == NULL && mediaType != NULL)
201 // Not found, try interface media type?
202 interfaceHVIF = (const uint8*)resources->LoadResource(
203 B_VECTOR_ICON_TYPE, mediaType, &iconSize);
204 if (interfaceHVIF == NULL)
205 // Not found, try default interface icon?
206 interfaceHVIF = (const uint8*)resources->LoadResource(
207 B_VECTOR_ICON_TYPE, "ether", &iconSize);
209 if (interfaceHVIF) {
210 // Now build the bitmap
211 interfaceBitmap = new BBitmap(BRect(0, 0, ICON_SIZE, ICON_SIZE),
212 0, B_RGBA32);
213 if (BIconUtils::GetVectorIcon(interfaceHVIF,
214 iconSize, interfaceBitmap) == B_OK)
215 fIcon = interfaceBitmap;
216 else
217 delete interfaceBitmap;
220 // Load possible state icons
221 offlineHVIF = (const uint8*)resources->LoadResource(
222 B_VECTOR_ICON_TYPE, "offline", &iconSize);
224 if (offlineHVIF) {
225 fIconOffline = new BBitmap(BRect(0, 0, ICON_SIZE, ICON_SIZE),
226 0, B_RGBA32);
227 BIconUtils::GetVectorIcon(offlineHVIF, iconSize, fIconOffline);
230 pendingHVIF = (const uint8*)resources->LoadResource(
231 B_VECTOR_ICON_TYPE, "pending", &iconSize);
233 if (pendingHVIF) {
234 fIconPending = new BBitmap(BRect(0, 0, ICON_SIZE, ICON_SIZE),
235 0, B_RGBA32);
236 BIconUtils::GetVectorIcon(pendingHVIF, iconSize, fIconPending);
239 onlineHVIF = (const uint8*)resources->LoadResource(
240 B_VECTOR_ICON_TYPE, "online", &iconSize);
242 if (onlineHVIF) {
243 fIconOnline = new BBitmap(BRect(0, 0, ICON_SIZE, ICON_SIZE),
244 0, B_RGBA32);
245 BIconUtils::GetVectorIcon(onlineHVIF, iconSize, fIconOnline);
250 void
251 InterfaceListItem::_UpdateState()
253 fDeviceName = Name();
254 fDeviceName.RemoveFirst("/dev/net/");
256 fDisabled = (fInterface.Flags() & IFF_UP) == 0;
257 fHasLink = fInterface.HasLink();
258 fConnecting = (fInterface.Flags() & IFF_CONFIGURING) != 0;
260 switch (fType) {
261 case B_NETWORK_INTERFACE_TYPE_WIFI:
262 fSubtitle = B_TRANSLATE("Wireless device");
263 break;
264 case B_NETWORK_INTERFACE_TYPE_ETHERNET:
265 fSubtitle = B_TRANSLATE("Ethernet device");
266 break;
267 case B_NETWORK_INTERFACE_TYPE_DIAL_UP:
268 fSubtitle = B_TRANSLATE("Dial-up connection");
269 break;
270 case B_NETWORK_INTERFACE_TYPE_VPN:
271 fSubtitle = B_TRANSLATE("VPN connection");
272 break;
273 default:
274 fSubtitle = "";
279 BBitmap*
280 InterfaceListItem::_StateIcon() const
282 if (fDisabled)
283 return fIconOffline;
284 if (!fHasLink)
285 return fIconOffline;
286 // TODO!
287 // } else if ((fSettings->IPAddr(AF_INET).IsEmpty()
288 // && fSettings->IPAddr(AF_INET6).IsEmpty())
289 // && (fSettings->AutoConfigure(AF_INET)
290 // || fSettings->AutoConfigure(AF_INET6))) {
291 // interfaceState = "connecting" B_UTF8_ELLIPSIS;
292 // stateIcon = fIconPending;
294 return fIconOnline;
298 const char*
299 InterfaceListItem::_StateText() const
301 if (fDisabled)
302 return B_TRANSLATE("disabled");
303 if (!fInterface.HasLink())
304 return B_TRANSLATE("no link");
306 // TODO!
307 // } else if ((fSettings->IPAddr(AF_INET).IsEmpty()
308 // && fSettings->IPAddr(AF_INET6).IsEmpty())
309 // && (fSettings->AutoConfigure(AF_INET)
310 // || fSettings->AutoConfigure(AF_INET6))) {
311 // interfaceState = "connecting" B_UTF8_ELLIPSIS;
312 // stateIcon = fIconPending;
314 return B_TRANSLATE("connected");