Network: added interface list item.

* Added BNetworkInterfaceListItem that can be used by interface protocol
  add-ons to represent their functionality in the list view.
* It will automatically update itself on changes, and will show the
  specified label, and address, if any, as well as indicate whether or
  not the family has been disabled (which doesn't work perfectly yet,
  as IFF_AUTO_CONFIGURED is on the interface level).
* Therefore, the interface list item will no longer show the address,
  but the type of the device instead.
* Introduced the BNetworkConfigurationListener interface that is used
  to broadcast network updates to.
This commit is contained in:
Axel Dörfler 2015-03-05 12:56:16 +00:00
parent b00dcbcad2
commit 5274e9b004
8 changed files with 232 additions and 65 deletions

View File

@ -10,9 +10,13 @@
#include <image.h>
#include <ListItem.h>
#include <Resources.h>
#include <String.h>
#include <View.h>
class BNetworkAddress;
namespace BNetworkKit {
@ -31,7 +35,14 @@ class BNetworkProfile;
class BNetworkSettings;
class BNetworkSettingsItem {
class BNetworkConfigurationListener {
public:
virtual void ConfigurationUpdated(
const BMessage& message) = 0;
};
class BNetworkSettingsItem : public BNetworkConfigurationListener {
public:
BNetworkSettingsItem();
virtual ~BNetworkSettingsItem();
@ -73,6 +84,36 @@ private:
};
class BNetworkInterfaceListItem : public BListItem,
public BNetworkConfigurationListener {
public:
BNetworkInterfaceListItem(int family,
const char* interface, const char* label,
BNetworkSettings& settings);
~BNetworkInterfaceListItem();
virtual void DrawItem(BView* owner,
BRect bounds, bool complete);
virtual void Update(BView* owner, const BFont* font);
virtual void ConfigurationUpdated(const BMessage& message);
private:
BFont _AddressFont();
void _UpdateState();
private:
BNetworkSettings& fSettings;
int fFamily;
const char* fInterface;
const char* fLabel;
BString fAddress;
bool fDisabled;
float fLineOffset;
float fSpacing;
};
class BNetworkSettingsAddOn {
public:
BNetworkSettingsAddOn(image_id image,

View File

@ -49,7 +49,8 @@ public:
private:
BNetworkSettings& fSettings;
BStringItem* fItem;
BNetworkInterfaceListItem*
fItem;
InterfaceAddressView*
fView;
};
@ -63,7 +64,8 @@ IPv4InterfaceItem::IPv4InterfaceItem(const char* interface,
:
BNetworkSettingsInterfaceItem(interface),
fSettings(settings),
fItem(new BStringItem(B_TRANSLATE("IPv4"))),
fItem(new BNetworkInterfaceListItem(AF_INET, Interface(),
B_TRANSLATE("IPv4"), settings)),
fView(NULL)
{
}

View File

@ -49,7 +49,8 @@ public:
private:
BNetworkSettings& fSettings;
BStringItem* fItem;
BNetworkInterfaceListItem*
fItem;
InterfaceAddressView*
fView;
};
@ -63,7 +64,8 @@ IPv6InterfaceItem::IPv6InterfaceItem(const char* interface,
:
BNetworkSettingsInterfaceItem(interface),
fSettings(settings),
fItem(new BStringItem(B_TRANSLATE("IPv6"))),
fItem(new BNetworkInterfaceListItem(AF_INET6, Interface(),
B_TRANSLATE("IPv6"), settings)),
fView(NULL)
{
}

View File

@ -24,7 +24,7 @@
#include <String.h>
#define ICON_SIZE 37
#define ICON_SIZE 32
#undef B_TRANSLATION_CONTEXT
@ -53,43 +53,39 @@ InterfaceListItem::~InterfaceListItem()
void
InterfaceListItem::DrawItem(BView* owner, BRect bounds, bool complete)
{
BOutlineListView* list = dynamic_cast<BOutlineListView*>(owner);
if (list == NULL)
return;
owner->PushState();
rgb_color lowColor = list->LowColor();
rgb_color lowColor = owner->LowColor();
if (IsSelected() || complete) {
if (IsSelected()) {
list->SetHighColor(ui_color(B_LIST_SELECTED_BACKGROUND_COLOR));
list->SetLowColor(list->HighColor());
owner->SetHighColor(ui_color(B_LIST_SELECTED_BACKGROUND_COLOR));
owner->SetLowColor(owner->HighColor());
} else
list->SetHighColor(lowColor);
owner->SetHighColor(lowColor);
list->FillRect(bounds);
owner->FillRect(bounds);
}
BBitmap* stateIcon = _StateIcon();
const char* stateText = _StateText();
// Set the initial bounds of item contents
BPoint iconPoint = bounds.LeftTop() + BPoint(4, 4);
BPoint iconPoint = bounds.LeftTop() + BPoint(4, 2);
BPoint statePoint = bounds.RightTop() + BPoint(0, fFirstLineOffset)
- BPoint(be_plain_font->StringWidth(stateText) + 4.0f, 0);
BPoint namePoint = bounds.LeftTop()
+ BPoint(ICON_SIZE + 12, fFirstLineOffset);
if (fDisabled) {
list->SetDrawingMode(B_OP_ALPHA);
list->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
list->SetHighColor(0, 0, 0, 32);
owner->SetDrawingMode(B_OP_ALPHA);
owner->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
owner->SetHighColor(0, 0, 0, 32);
} else
list->SetDrawingMode(B_OP_OVER);
owner->SetDrawingMode(B_OP_OVER);
list->DrawBitmapAsync(fIcon, iconPoint);
list->DrawBitmapAsync(stateIcon, iconPoint);
owner->DrawBitmapAsync(fIcon, iconPoint);
owner->DrawBitmapAsync(stateIcon, iconPoint);
if (fDisabled) {
rgb_color textColor;
@ -99,30 +95,25 @@ InterfaceListItem::DrawItem(BView* owner, BRect bounds, bool complete)
textColor = ui_color(B_LIST_ITEM_TEXT_COLOR);
if (textColor.red + textColor.green + textColor.blue > 128 * 3)
list->SetHighColor(tint_color(textColor, B_DARKEN_1_TINT));
owner->SetHighColor(tint_color(textColor, B_DARKEN_1_TINT));
else
list->SetHighColor(tint_color(textColor, B_LIGHTEN_1_TINT));
owner->SetHighColor(tint_color(textColor, B_LIGHTEN_1_TINT));
} else {
if (IsSelected())
list->SetHighColor(ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR));
owner->SetHighColor(ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR));
else
list->SetHighColor(ui_color(B_LIST_ITEM_TEXT_COLOR));
owner->SetHighColor(ui_color(B_LIST_ITEM_TEXT_COLOR));
}
list->SetFont(be_bold_font);
owner->SetFont(be_bold_font);
list->DrawString(fDeviceName, namePoint);
list->SetFont(be_plain_font);
list->DrawString(stateText, statePoint);
owner->DrawString(fDeviceName, namePoint);
owner->SetFont(be_plain_font);
owner->DrawString(stateText, statePoint);
BPoint linePoint = bounds.LeftTop() + BPoint(ICON_SIZE + 12,
fFirstLineOffset + fLineOffset);
for (size_t line = 0; line < sizeof(fAddress) / sizeof(fAddress[0]);
line++) {
list->DrawString(fAddress[line], linePoint);
linePoint.y += fLineOffset;
}
owner->DrawString(fSubtitle, linePoint);
owner->PopState();
}
@ -146,7 +137,7 @@ InterfaceListItem::Update(BView* owner, const BFont* font)
SetWidth(fIcon->Bounds().Width() + 44
+ be_bold_font->StringWidth(fDeviceName.String())
+ owner->StringWidth(_StateText()));
SetHeight(std::max(3 * lineHeight + 4, fIcon->Bounds().Height() + 8));
SetHeight(std::max(2 * lineHeight + 4, fIcon->Bounds().Height() + 4));
// either to the text height or icon height, whichever is taller
}
@ -255,23 +246,13 @@ InterfaceListItem::_UpdateState()
fHasLink = fInterface.HasLink();
fConnecting = (fInterface.Flags() & IFF_CONFIGURING) != 0;
int32 count = fInterface.CountAddresses();
int lastFamily = -1;
size_t addressIndex = 0;
for (int32 index = 0; index < count; index++) {
if (addressIndex >= sizeof(fAddress) / sizeof(fAddress[0]))
break;
BNetworkInterfaceAddress address;
if (fInterface.GetAddressAt(index, address) == B_OK) {
if (address.Address().IsEmpty()
|| lastFamily == address.Address().Family())
continue;
fAddress[addressIndex++] = address.Address().ToString();
lastFamily = address.Address().Family();
}
}
BNetworkDevice device(Name());
if (device.IsWireless())
fSubtitle = B_TRANSLATE("Wireless device");
else if (device.IsEthernet())
fSubtitle = B_TRANSLATE("Ethernet device");
else
fSubtitle = "";
}

View File

@ -14,12 +14,14 @@
#include <ListItem.h>
#include <NetworkInterface.h>
#include <NetworkSettingsAddOn.h>
class BBitmap;
class InterfaceListItem : public BListItem {
class InterfaceListItem : public BListItem,
public BNetworkKit::BNetworkConfigurationListener {
public:
InterfaceListItem(const char* name);
~InterfaceListItem();
@ -30,7 +32,7 @@ public:
inline const char* Name() { return fInterface.Name(); }
void ConfigurationUpdated(const BMessage& message);
virtual void ConfigurationUpdated(const BMessage& message);
private:
void _Init();
@ -55,7 +57,7 @@ private:
bool fDisabled;
bool fHasLink;
bool fConnecting;
BString fAddress[2];
BString fSubtitle;
};

View File

@ -9,6 +9,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <ControlLook.h>
#include <NetworkAddress.h>
#include <NetworkInterface.h>
#include <NetworkSettings.h>
using namespace BNetworkKit;
@ -85,6 +90,137 @@ BNetworkSettingsInterfaceItem::Interface() const
// #pragma mark -
BNetworkInterfaceListItem::BNetworkInterfaceListItem(int family,
const char* interface, const char* label, BNetworkSettings& settings)
:
fSettings(settings),
fFamily(family),
fInterface(interface),
fLabel(label)
{
}
BNetworkInterfaceListItem::~BNetworkInterfaceListItem()
{
}
void
BNetworkInterfaceListItem::DrawItem(BView* owner, BRect bounds, bool complete)
{
owner->PushState();
if (IsSelected() || complete) {
if (IsSelected()) {
owner->SetHighColor(ui_color(B_LIST_SELECTED_BACKGROUND_COLOR));
owner->SetLowColor(owner->HighColor());
} else
owner->SetHighColor(owner->LowColor());
owner->FillRect(bounds);
}
// Set the initial bounds of item contents
BPoint labelLocation = bounds.LeftTop() + BPoint(fSpacing, fLineOffset);
if (fDisabled) {
rgb_color textColor;
if (IsSelected())
textColor = ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR);
else
textColor = ui_color(B_LIST_ITEM_TEXT_COLOR);
if (textColor.red + textColor.green + textColor.blue > 128 * 3)
owner->SetHighColor(tint_color(textColor, B_DARKEN_1_TINT));
else
owner->SetHighColor(tint_color(textColor, B_LIGHTEN_1_TINT));
} else {
if (IsSelected())
owner->SetHighColor(ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR));
else
owner->SetHighColor(ui_color(B_LIST_ITEM_TEXT_COLOR));
}
owner->SetFont(be_plain_font);
owner->DrawString(fLabel, labelLocation);
if (!fAddress.IsEmpty()) {
BFont font = _AddressFont();
owner->MovePenBy(fSpacing, 0);
owner->SetFont(&font);
owner->DrawString(fAddress);
}
owner->PopState();
}
void
BNetworkInterfaceListItem::Update(BView* owner, const BFont* font)
{
_UpdateState();
fSpacing = be_control_look->DefaultLabelSpacing();
BListItem::Update(owner, font);
font_height height;
font->GetHeight(&height);
float lineHeight = ceilf(height.ascent) + ceilf(height.descent)
+ ceilf(height.leading);
fLineOffset = 2 + ceilf(height.ascent + height.leading / 2);
SetWidth(owner->StringWidth(fLabel) + 2 * fSpacing
+ _AddressFont().StringWidth(fAddress.String()));
SetHeight(lineHeight + 4);
}
void
BNetworkInterfaceListItem::ConfigurationUpdated(const BMessage& message)
{
_UpdateState();
}
BFont
BNetworkInterfaceListItem::_AddressFont()
{
BFont font;
font.SetFace(B_ITALIC_FACE);
font.SetSize(font.Size() * 0.9f);
return font;
}
void
BNetworkInterfaceListItem::_UpdateState()
{
BNetworkInterfaceAddress address;
BNetworkInterface interface(fInterface);
bool autoConfigure = fSettings.Interface(fInterface).IsAutoConfigure(
fFamily);
fAddress = "";
fDisabled = !autoConfigure;
int32 index = interface.FindFirstAddress(fFamily);
if (index < 0)
return;
interface.GetAddressAt(index, address);
fDisabled = address.Address().IsEmpty() && !autoConfigure;
if (!address.Address().IsEmpty())
fAddress << "(" << address.Address().ToString() << ")";
}
// #pragma mark -
BNetworkSettingsAddOn::BNetworkSettingsAddOn(image_id image,
BNetworkSettings& settings)
:

View File

@ -349,11 +349,10 @@ NetworkWindow::_ScanAddOns()
fAddOns.AddItem(addOn);
// Per interface items
InterfaceItemMap::const_iterator iterator
= fInterfaceItemMap.begin();
ItemMap::const_iterator iterator = fInterfaceItemMap.begin();
for (; iterator != fInterfaceItemMap.end(); iterator++) {
const BString& interface = iterator->first;
InterfaceListItem* interfaceItem = iterator->second;
BListItem* interfaceItem = iterator->second;
uint32 cookie = 0;
while (true) {
@ -463,9 +462,13 @@ NetworkWindow::_BroadcastSettingsUpdate(uint32 type)
void
NetworkWindow::_BroadcastConfigurationUpdate(const BMessage& message)
{
InterfaceItemMap::const_iterator itemIterator = fInterfaceItemMap.begin();
for (; itemIterator != fInterfaceItemMap.end(); itemIterator++)
itemIterator->second->ConfigurationUpdated(message);
for (int32 index = 0; index < fListView->FullListCountItems(); index++) {
BNetworkConfigurationListener* listener
= dynamic_cast<BNetworkConfigurationListener*>(
fListView->FullListItemAt(index));
if (listener != NULL)
listener->ConfigurationUpdated(message);
}
SettingsMap::const_iterator iterator = fSettingsMap.begin();
for (; iterator != fSettingsMap.end(); iterator++)

View File

@ -55,14 +55,14 @@ private:
private:
typedef BObjectList<BNetworkSettingsAddOn> AddOnList;
typedef BObjectList<BNetworkSettingsItem> ItemList;
typedef std::map<BString, InterfaceListItem*> InterfaceItemMap;
typedef std::map<BString, BListItem*> ItemMap;
typedef std::map<BListItem*, BNetworkSettingsItem*> SettingsMap;
BNetworkSettings fSettings;
AddOnList fAddOns;
BOutlineListView* fListView;
InterfaceItemMap fInterfaceItemMap;
ItemMap fInterfaceItemMap;
BListItem* fServicesItem;
BListItem* fDialUpItem;
BListItem* fOtherItem;