hrev47248 adds 2 changesets to branch 'master' old head: b6c34f4c44851acfa4f671933f304adab82bedbb new head: 5710ad967d7ba37ced59b5c80f0dde001e5417cd overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=5710ad9+%5Eb6c34f4 ---------------------------------------------------------------------------- 6f79af3: Web+: move BookmarbKar to own file. It's a bit long for an inline class, and I'm going to add more stuff to it. 5710ad9: Move overflowing items from bookmark bar to a menu. Since the bookmark bar can now be resized smaller than the space needed for the items, move items that don't fit in it to a menu, which is always the last item in the BMenuBar. [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 5 files changed, 296 insertions(+), 136 deletions(-) src/apps/webpositive/BookmarkBar.cpp | 218 +++++++++++++++++++++++++ src/apps/webpositive/BookmarkBar.h | 47 ++++++ src/apps/webpositive/BrowserWindow.cpp | 137 +--------------- src/apps/webpositive/Jamfile | 1 + src/system/libroot/posix/string/strdup.cpp | 29 ++++ ############################################################################ Commit: 6f79af3c556146444b5c759f9483220db1223393 URL: http://cgit.haiku-os.org/haiku/commit/?id=6f79af3 Author: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> Date: Fri May 23 13:38:10 2014 UTC Web+: move BookmarbKar to own file. It's a bit long for an inline class, and I'm going to add more stuff to it. ---------------------------------------------------------------------------- diff --git a/src/apps/webpositive/BookmarkBar.cpp b/src/apps/webpositive/BookmarkBar.cpp new file mode 100644 index 0000000..4501e75 --- /dev/null +++ b/src/apps/webpositive/BookmarkBar.cpp @@ -0,0 +1,154 @@ +/* + * Copyright 2014, Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>. + * Distributed under the terms of the MIT License. + */ + + +#include "BookmarkBar.h" + +#include <Directory.h> +#include <Entry.h> +#include <IconMenuItem.h> +#include <Messenger.h> +#include <Window.h> + +#include "NavMenu.h" + + +BookmarkBar::BookmarkBar(const char* title, BHandler* target, + const entry_ref* navDir) + : BMenuBar(title) +{ + BEntry(navDir).GetNodeRef(&fNodeRef); +} + + +BookmarkBar::~BookmarkBar() +{ + stop_watching(BMessenger(this)); +} + + +void +BookmarkBar::AttachedToWindow() +{ + BMenuBar::AttachedToWindow(); + watch_node(&fNodeRef, B_WATCH_DIRECTORY, BMessenger(this)); + + // Enumerate initial directory content + BDirectory dir(&fNodeRef); + BEntry bookmark; + while(dir.GetNextEntry(&bookmark) == B_OK) { + node_ref ref; + bookmark.GetNodeRef(&ref); + _AddItem(ref.node, &bookmark); + } +} + + +void +BookmarkBar::MessageReceived(BMessage* message) +{ + switch(message->what) { + case B_NODE_MONITOR: + { + int32 opcode = message->FindInt32("opcode"); + ino_t inode = message->FindInt64("node"); + switch(opcode) { + case B_ENTRY_CREATED: + { + entry_ref ref; + const char *name; + + message->FindInt32("device", &ref.device); + message->FindInt64("directory", &ref.directory); + message->FindString("name", &name); + ref.set_name(name); + + BEntry entry(&ref); + _AddItem(inode, &entry); + break; + } + case B_ENTRY_MOVED: + { + if (fItemsMap[inode] == NULL) + { + entry_ref ref; + const char *name; + + message->FindInt32("device", &ref.device); + message->FindInt64("to directory", &ref.directory); + message->FindString("name", &name); + ref.set_name(name); + + BEntry entry(&ref); + _AddItem(inode, &entry); + break; + } else { + // Existing item. Check if it's a rename or a move + // to some other folder. + ino_t from, to; + message->FindInt64("to directory", &to); + message->FindInt64("from directory", &from); + if (from == to) + { + const char *name; + message->FindString("name", &name); + fItemsMap[inode]->SetLabel(name); + break; + } + } + + // fall through: the item was moved from here to + // elsewhere, remove it from the bar. + } + case B_ENTRY_REMOVED: + { + IconMenuItem* item = fItemsMap[inode]; + RemoveItem(item); + fItemsMap.erase(inode); + delete item; + } + } + return; + } + } + + BMenuBar::MessageReceived(message); +} + + +void +BookmarkBar::_AddItem(ino_t inode, BEntry* entry) +{ + char name[B_FILE_NAME_LENGTH]; + entry->GetName(name); + + // make sure the item doesn't already exists + if (fItemsMap[inode] != NULL) + return; + + entry_ref ref; + entry->GetRef(&ref); + + IconMenuItem* item = NULL; + + if(entry->IsDirectory()) { + BNavMenu* menu = new BNavMenu(name, B_REFS_RECEIVED, Window()); + menu->SetNavDir(&ref); + item = new IconMenuItem(menu, NULL, + "application/x-vnd.Be-directory", B_MINI_ICON); + + } else { + BNode node(entry); + BNodeInfo info(&node); + + BMessage* message = new BMessage(B_REFS_RECEIVED); + message->AddRef("refs", &ref); + item = new IconMenuItem(name, message, &info, + B_MINI_ICON); + } + + BMenuBar::AddItem(item); + fItemsMap[inode] = item; +} diff --git a/src/apps/webpositive/BookmarkBar.h b/src/apps/webpositive/BookmarkBar.h new file mode 100644 index 0000000..af0e8bd --- /dev/null +++ b/src/apps/webpositive/BookmarkBar.h @@ -0,0 +1,42 @@ +/* + * Copyright 2014, Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>. + * Distributed under the terms of the MIT License. + */ +#ifndef BOOKMARK_BAR_H +#define BOOKMARK_BAR_H + + +#include <map> + +#include <MenuBar.h> +#include <Node.h> +#include <NodeMonitor.h> + + +class BEntry; + +namespace BPrivate { + class IconMenuItem; +} + + +class BookmarkBar: public BMenuBar { +public: + BookmarkBar(const char* title, + BHandler* target, + const entry_ref* navDir); + ~BookmarkBar(); + + void AttachedToWindow(); + void MessageReceived(BMessage* message); + +private: + void _AddItem(ino_t inode, BEntry* entry); + +private: + node_ref fNodeRef; + std::map<ino_t, BPrivate::IconMenuItem*> fItemsMap; +}; + + +#endif // BOOKMARK_BAR_H diff --git a/src/apps/webpositive/BrowserWindow.cpp b/src/apps/webpositive/BrowserWindow.cpp index bbb2a91..b25e180 100644 --- a/src/apps/webpositive/BrowserWindow.cpp +++ b/src/apps/webpositive/BrowserWindow.cpp @@ -74,6 +74,7 @@ #include "AuthenticationPanel.h" #include "BaseURL.h" #include "BitmapButton.h" +#include "BookmarkBar.h" #include "BrowserApp.h" #include "BrowsingHistory.h" #include "CredentialsStorage.h" @@ -176,142 +177,6 @@ private: }; -class BookmarkBar: public BMenuBar { -public: - BookmarkBar(const char* title, BHandler* target, const entry_ref* navDir) - : BMenuBar(title) - { - BEntry(navDir).GetNodeRef(&fNodeRef); - } - - ~BookmarkBar() - { - stop_watching(BMessenger(this)); - } - - void AttachedToWindow() - { - BMenuBar::AttachedToWindow(); - watch_node(&fNodeRef, B_WATCH_DIRECTORY, BMessenger(this)); - - // Enumerate initial directory content - BDirectory dir(&fNodeRef); - BEntry bookmark; - while(dir.GetNextEntry(&bookmark) == B_OK) { - node_ref ref; - bookmark.GetNodeRef(&ref); - AddItem(ref.node, &bookmark); - } - } - - void MessageReceived(BMessage* message) - { - switch(message->what) { - case B_NODE_MONITOR: - int32 opcode = message->FindInt32("opcode"); - ino_t inode = message->FindInt64("node"); - switch(opcode) { - case B_ENTRY_CREATED: - { - entry_ref ref; - const char *name; - - message->FindInt32("device", &ref.device); - message->FindInt64("directory", &ref.directory); - message->FindString("name", &name); - ref.set_name(name); - - BEntry entry(&ref); - AddItem(inode, &entry); - break; - } - case B_ENTRY_MOVED: - { - if (fItemsMap[inode] == NULL) - { - entry_ref ref; - const char *name; - - message->FindInt32("device", &ref.device); - message->FindInt64("to directory", &ref.directory); - message->FindString("name", &name); - ref.set_name(name); - - BEntry entry(&ref); - AddItem(inode, &entry); - break; - } else { - // Existing item. Check if it's a rename or a move - // to some other folder. - ino_t from, to; - message->FindInt64("to directory", &to); - message->FindInt64("from directory", &from); - if (from == to) - { - const char *name; - message->FindString("name", &name); - fItemsMap[inode]->SetLabel(name); - break; - } - } - - // fall through: the item was moved from here to - // elsewhere, remove it from the bar. - } - case B_ENTRY_REMOVED: - { - IconMenuItem* item = fItemsMap[inode]; - RemoveItem(item); - fItemsMap.erase(inode); - delete item; - } - } - return; - } - - BMenuBar::MessageReceived(message); - } - -private: - void AddItem(ino_t inode, BEntry* entry) - { - char name[B_FILE_NAME_LENGTH]; - entry->GetName(name); - - // make sure the item doesn't already exists - if (fItemsMap[inode] != NULL) - return; - - entry_ref ref; - entry->GetRef(&ref); - - IconMenuItem* item = NULL; - - if(entry->IsDirectory()) { - BNavMenu* menu = new BNavMenu(name, B_REFS_RECEIVED, Window()); - menu->SetNavDir(&ref); - item = new IconMenuItem(menu, NULL, - "application/x-vnd.Be-directory", B_MINI_ICON); - - } else { - BNode node(entry); - BNodeInfo info(&node); - - BMessage* message = new BMessage(B_REFS_RECEIVED); - message->AddRef("refs", &ref); - item = new IconMenuItem(name, message, &info, - B_MINI_ICON); - } - - BMenuBar::AddItem(item); - fItemsMap[inode] = item; - } - - node_ref fNodeRef; - std::map<ino_t, IconMenuItem*> fItemsMap; -}; - - class PageUserData : public BWebView::UserData { public: PageUserData(BView* focusedView) diff --git a/src/apps/webpositive/Jamfile b/src/apps/webpositive/Jamfile index df84daa..65fa471 100644 --- a/src/apps/webpositive/Jamfile +++ b/src/apps/webpositive/Jamfile @@ -19,6 +19,7 @@ local sources = # support BaseURL.cpp BitmapButton.cpp + BookmarkBar.cpp FontSelectionView.cpp SettingsMessage.cpp diff --git a/src/system/libroot/posix/string/strdup.cpp b/src/system/libroot/posix/string/strdup.cpp new file mode 100644 index 0000000..a4306f0 --- /dev/null +++ b/src/system/libroot/posix/string/strdup.cpp @@ -0,0 +1,29 @@ +/* + * Copyright 2003-2007, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include <string.h> +#include <stdlib.h> + + +char* +strdup(const char *string) +{ + char* copied; + size_t length; + + // unlike the standard strdup() function, the BeOS implementation + // handles NULL strings gracefully + if (string == NULL) + return NULL; + + length = strlen(string) + 1; + + if ((copied = (char *)malloc(length)) == NULL) + return NULL; + + memcpy(copied, string, length); + return copied; +} ############################################################################ Revision: hrev47248 Commit: 5710ad967d7ba37ced59b5c80f0dde001e5417cd URL: http://cgit.haiku-os.org/haiku/commit/?id=5710ad9 Author: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> Date: Fri May 23 15:54:30 2014 UTC Move overflowing items from bookmark bar to a menu. Since the bookmark bar can now be resized smaller than the space needed for the items, move items that don't fit in it to a menu, which is always the last item in the BMenuBar. ---------------------------------------------------------------------------- diff --git a/src/apps/webpositive/BookmarkBar.cpp b/src/apps/webpositive/BookmarkBar.cpp index 4501e75..3cd1772 100644 --- a/src/apps/webpositive/BookmarkBar.cpp +++ b/src/apps/webpositive/BookmarkBar.cpp @@ -14,12 +14,19 @@ #include "NavMenu.h" +#include <stdio.h> + BookmarkBar::BookmarkBar(const char* title, BHandler* target, const entry_ref* navDir) : BMenuBar(title) { + SetFlags(Flags() | B_FRAME_EVENTS); BEntry(navDir).GetNodeRef(&fNodeRef); + + fOverflowMenu = new BMenu(B_UTF8_ELLIPSIS); + + AddItem(fOverflowMenu); } @@ -119,6 +126,59 @@ BookmarkBar::MessageReceived(BMessage* message) void +BookmarkBar::FrameResized(float width, float height) +{ + int32 count = CountItems() - 1; + // We don't touch the "more" menu + int32 i = 0; + float rightmost = 0.f; + while (i < count) { + BMenuItem* item = ItemAt(i); + BRect frame = item->Frame(); + if (frame.right > width - 32) + break; + rightmost = frame.right; + i++; + } + + if (i == count) { + // See if we can move some items from the "more" menu in the remaining + // space. + BMenuItem* extraItem = fOverflowMenu->ItemAt(0); + while (extraItem) { + BRect frame = extraItem->Frame(); + if (frame.Width() + rightmost > width - 32) + break; + + AddItem(fOverflowMenu->RemoveItem((int32)0), i); + i++; + + extraItem = fOverflowMenu->ItemAt(0); + } + } else { + // Remove any overflowing item and move them to the "more" menu. + for (int j = i; j < count; j++) + fOverflowMenu->AddItem(RemoveItem(j), 0); + } +} + + +BSize +BookmarkBar::MinSize() +{ + BSize size = BMenuBar::MinSize(); + + // We only need space to show the "more" button. + size.width = 32; + + return size; +} + + +//#pragma mark - private methods + + +void BookmarkBar::_AddItem(ino_t inode, BEntry* entry) { char name[B_FILE_NAME_LENGTH]; @@ -149,6 +209,10 @@ BookmarkBar::_AddItem(ino_t inode, BEntry* entry) B_MINI_ICON); } - BMenuBar::AddItem(item); + BMenuBar::AddItem(item, CountItems() - 1); fItemsMap[inode] = item; + + // Move the item to the "more" menu if it overflows. + BRect r = Bounds(); + FrameResized(r.width(), r.height()); } diff --git a/src/apps/webpositive/BookmarkBar.h b/src/apps/webpositive/BookmarkBar.h index af0e8bd..651e3ab 100644 --- a/src/apps/webpositive/BookmarkBar.h +++ b/src/apps/webpositive/BookmarkBar.h @@ -11,6 +11,7 @@ #include <MenuBar.h> #include <Node.h> #include <NodeMonitor.h> +#include <Size.h> class BEntry; @@ -30,12 +31,16 @@ public: void AttachedToWindow(); void MessageReceived(BMessage* message); + void FrameResized(float width, float height); + BSize MinSize(); + private: void _AddItem(ino_t inode, BEntry* entry); private: node_ref fNodeRef; std::map<ino_t, BPrivate::IconMenuItem*> fItemsMap; + BMenu* fOverflowMenu; };