hrev45907 adds 8 changesets to branch 'master' old head: 98a5231fe5497c526849f2d84b1a9bbcbdfd2dbc new head: 1b28bb090d027971096afce1c1edc69264d1f6b1 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=1b28bb0+%5E98a5231 ---------------------------------------------------------------------------- d951284: Haiku-Depot: Initial skeleton application 8608501: HaikuDepot: BGroupView for the controls defining list contents 7fa8316: HaikuDepot: PackagesListView BColumnListView derived class with code-duplication from DriveSetup that should be refactored eventually (BIconStringColumn and BColumn implementation to show it). Does nothing except create some columns. f344b1d: HaikuDepot: BGroupView holding buttons for package actions... ... that can be applied to the selected package(s). Does nothing except create the buttons and layout. ac7d911: HaikuDepot: Added new classes to build and main window. 713ce3b: HaikuDepot: BTabView with About, Rating & comments and Changelog Completely non-functional. Should be replaced by something visually more unified. The selected package's title and icon should be always visible above the three sections, and the sections should not be tabs but something more subtle. fade0fd: HaikuDepot: Added PackageInfoView, moved buttons to bottom 1b28bb0: HaikuDepot: Populate menu fields (non-functional) [ Stephan Aßmus <superstippi@xxxxxx> ] ---------------------------------------------------------------------------- 18 files changed, 1136 insertions(+) src/apps/Jamfile | 1 + src/apps/haiku-depot/App.cpp | 96 ++++++++++ src/apps/haiku-depot/App.h | 33 ++++ src/apps/haiku-depot/FilterView.cpp | 118 +++++++++++++ src/apps/haiku-depot/FilterView.h | 29 +++ src/apps/haiku-depot/HaikuDepot.rdef | 46 +++++ src/apps/haiku-depot/Jamfile | 28 +++ src/apps/haiku-depot/MainWindow.cpp | 96 ++++++++++ src/apps/haiku-depot/MainWindow.h | 28 +++ src/apps/haiku-depot/PackageActionsView.cpp | 81 +++++++++ src/apps/haiku-depot/PackageActionsView.h | 29 +++ src/apps/haiku-depot/PackageInfoView.cpp | 61 +++++++ src/apps/haiku-depot/PackageInfoView.h | 25 +++ src/apps/haiku-depot/PackageListView.cpp | 223 ++++++++++++++++++++++++ src/apps/haiku-depot/PackageListView.h | 67 +++++++ src/apps/haiku-depot/main.cpp | 17 ++ src/apps/haiku-depot/support.cpp | 132 ++++++++++++++ src/apps/haiku-depot/support.h | 26 +++ ############################################################################ Commit: d9512848e468e26dcb67d87a66ecd677fd66844b URL: http://cgit.haiku-os.org/haiku/commit/?id=d951284 Author: Stephan Aßmus <superstippi@xxxxxx> Date: Sat Jul 27 07:34:14 2013 UTC Haiku-Depot: Initial skeleton application ---------------------------------------------------------------------------- diff --git a/src/apps/Jamfile b/src/apps/Jamfile index 6c3a8fc..4cc22a1 100644 --- a/src/apps/Jamfile +++ b/src/apps/Jamfile @@ -25,6 +25,7 @@ HaikuSubInclude fontdemo ; HaikuSubInclude glteapot ; HaikuSubInclude gradients ; HaikuSubInclude haiku3d ; +HaikuSubInclude haiku-depot ; HaikuSubInclude icon-o-matic ; HaikuSubInclude installedpackages ; HaikuSubInclude installer ; diff --git a/src/apps/haiku-depot/App.cpp b/src/apps/haiku-depot/App.cpp new file mode 100644 index 0000000..fae6481 --- /dev/null +++ b/src/apps/haiku-depot/App.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "App.h" + +#include <stdio.h> + +#include <Catalog.h> +#include <Entry.h> +#include <Message.h> +#include <String.h> + +#include "support.h" + +#include "MainWindow.h" + + +#undef B_TRANSLATION_CONTEXT +#define B_TRANSLATION_CONTEXT "App" + + +App::App() + : + BApplication("application/x-vnd.Haiku-HaikuDepot") +{ +} + + +App::~App() +{ +} + + +bool +App::QuitRequested() +{ + if (fMainWindow->LockLooperWithTimeout(1500000) == B_OK) { + BRect windowFrame = fMainWindow->Frame(); + fMainWindow->UnlockLooper(); + + _StoreSettings(windowFrame); + } + + return true; +} + + +void +App::ReadyToRun() +{ + BRect frame(50.0, 50.0, 749.0, 549.0); + + BMessage settings; + status_t status = load_settings(&settings, "main_settings", "HaikuDepot"); + if (status == B_OK) { + settings.FindRect("window frame", &frame); + } + + make_sure_frame_is_on_screen(frame); + + fMainWindow = new MainWindow(frame); + fMainWindow->Show(); +} + + +void +App::MessageReceived(BMessage* message) +{ + switch (message->what) { + case MSG_MAIN_WINDOW_CLOSED: + { + BRect windowFrame; + if (message->FindRect("window frame", &windowFrame) == B_OK) + _StoreSettings(windowFrame); + + Quit(); + break; + } + + default: + BApplication::MessageReceived(message); + break; + } +} + + +void +App::_StoreSettings(const BRect& windowFrame) +{ + BMessage settings; + settings.AddRect("window frame", windowFrame); + save_settings(&settings, "main_settings", "HaikuDepot"); +} + diff --git a/src/apps/haiku-depot/App.h b/src/apps/haiku-depot/App.h new file mode 100644 index 0000000..e48e61c --- /dev/null +++ b/src/apps/haiku-depot/App.h @@ -0,0 +1,33 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef APP_H +#define APP_H + + +#include <Application.h> +#include <List.h> +#include <Size.h> + + +class MainWindow; + + +class App : public BApplication { +public: + App(); + virtual ~App(); + + virtual bool QuitRequested(); + virtual void ReadyToRun(); + virtual void MessageReceived(BMessage* message); + +private: + void _StoreSettings(const BRect& windowFrame); + + MainWindow* fMainWindow; +}; + + +#endif // APP_H diff --git a/src/apps/haiku-depot/HaikuDepot.rdef b/src/apps/haiku-depot/HaikuDepot.rdef new file mode 100644 index 0000000..c91dc91 --- /dev/null +++ b/src/apps/haiku-depot/HaikuDepot.rdef @@ -0,0 +1,46 @@ + +resource app_signature "application/x-vnd.Haiku-HaikuDepot"; + +resource app_name_catalog_entry "x-vnd.Haiku-HaikuDepot:System name:HaikuDepot"; + +resource app_flags B_SINGLE_LAUNCH; + +resource app_version { + major = 0, + middle = 0, + minor = 1, + + variety = B_APPV_ALPHA, + internal = 1, + + short_info = "HaikuDepot", + long_info = "HaikuDepot ©2013 Haiku" +}; + +resource vector_icon { + $"6E6369660D0500020112023DEB47BD4D713B47993BE4594843FB4BC62F000032" + $"FF005A03FF990003FFE40003FDFF7502000602000000B6FA0BB6FA0B00000046" + $"86C94A0BE800FF0000FFFF6666020006023727A3AEA7053080AD38FA08496B7B" + $"4AC41300F70606FF9804040200060234A005341E7FB7602E3817404893414A70" + $"1400FF6666FFC200000200060239496E39C491BC42BD3BF1B749D83049AAFF00" + $"B20404FF8B03030200160236FA0B36FA0B36FA0BB6FA0B48D2FD4A56710096FF" + $"580200060338EC7E3992F0BA0B4939582E4ABDF947F9C300FF000066FF0000FF" + $"610202020006033C13B4BC6C533F097A3E9A69478C893F11A700FFACACA7FFF1" + $"F1FFB4B4B4020112033B000000000000000039000046C0004BB00000FF1FA7FF" + $"0BFFFF000C060A8ABF0ABC08CAA134603C40584C554C55595260455F485E4444" + $"4A4F42444A3C50334EBA4BC7E5060DE6FF8802364E5C405240464046C0FBC13D" + $"C4F9BEC1C2C2C005CAD6BB675C205C235920BF27B8EFC280B311BDE2BB25363C" + $"BCDDBD1A363C2A20462E2C4834500A0425442C44353E2B3E0A032F44353E2C44" + $"0A043E513E47385038570A03384D38503E470207BFD6B95343B760BDA6BD2633" + $"43BB79BFE1334339493949BE05C26DC494BE11C0C1C041C688BCF456315435C8" + $"67B8DCC70EB6DBC7F5B7C3C624B5F34B26C50BB57F47280A063343B89FC30BB8" + $"A1C30DBADBC546BADDC54739490A042E4F3A4339422D4E0604BF4233C44DB5A0" + $"BEEFBCB13840BD95BE8FBDC5BEBD4334BF3ABCFDC4F0B64359220605EE023A4B" + $"3852384E3857BEC15F43524357434E414B0A042054206034603454100A010100" + $"000A0C010B000A000101000A00010A123ECDF73EDA22BEDA223ECDF7494B02C5" + $"A04A01178400040A02010A023ECDF73EDA22BEDA223ECDF7494B02C5A04A0A03" + $"010A023E292D3E320CBE328D3E28AE48F3C2447A6A0A04010A023CACE53CB6B4" + $"BCB8813CAB20486D1B48A8BB0A050102000A080103000A060104000A08010500" + $"0A0A0106000A090107000A0001081001178400040A070108000A0B010900" +}; + diff --git a/src/apps/haiku-depot/Jamfile b/src/apps/haiku-depot/Jamfile new file mode 100644 index 0000000..f788c3e --- /dev/null +++ b/src/apps/haiku-depot/Jamfile @@ -0,0 +1,19 @@ +SubDir HAIKU_TOP src apps haiku-depot ; + +UsePrivateHeaders shared ; + +Application HaikuDepot : + App.cpp + main.cpp + MainWindow.cpp + support.cpp + : be translation libshared.a $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS) + : HaikuDepot.rdef +; + +DoCatalogs HaikuDepot : + x-vnd.Haiku-HaikuDepot + : + App.cpp + MainWindow.cpp +; diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp new file mode 100644 index 0000000..73f106c --- /dev/null +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -0,0 +1,60 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "MainWindow.h" + +#include <stdio.h> + +#include <Alert.h> +#include <Application.h> +#include <Button.h> +#include <Catalog.h> +#include <LayoutBuilder.h> +#include <Menu.h> +#include <MenuItem.h> +#include <Messenger.h> +#include <ScrollView.h> +#include <TabView.h> + +#undef B_TRANSLATION_CONTEXT +#define B_TRANSLATION_CONTEXT "MainWindow" + +MainWindow::MainWindow(BRect frame) + : + BWindow(frame, B_TRANSLATE_SYSTEM_NAME("HaikuDepot"), + B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, + B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS) +{ +} + + +MainWindow::~MainWindow() +{ +} + + +bool +MainWindow::QuitRequested() +{ + BMessage message(MSG_MAIN_WINDOW_CLOSED); + message.AddRect("window frame", Frame()); + be_app->PostMessage(&message); + + return true; +} + + +void +MainWindow::MessageReceived(BMessage* message) +{ + switch (message->what) { + case B_SIMPLE_DATA: + case B_REFS_RECEIVED: + break; + default: + BWindow::MessageReceived(message); + break; + } +} diff --git a/src/apps/haiku-depot/MainWindow.h b/src/apps/haiku-depot/MainWindow.h new file mode 100644 index 0000000..7f3476c --- /dev/null +++ b/src/apps/haiku-depot/MainWindow.h @@ -0,0 +1,28 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef MAIN_WINDOW_H +#define MAIN_WINDOW_H + +#include <Window.h> + + +enum { + MSG_MAIN_WINDOW_CLOSED = 'mwcl', +}; + + +class MainWindow : public BWindow { +public: + MainWindow(BRect frame); + virtual ~MainWindow(); + + // BWindow interface + virtual bool QuitRequested(); + virtual void MessageReceived(BMessage* message); + +private: +}; + +#endif // MAIN_WINDOW_H diff --git a/src/apps/haiku-depot/main.cpp b/src/apps/haiku-depot/main.cpp new file mode 100644 index 0000000..f01d915 --- /dev/null +++ b/src/apps/haiku-depot/main.cpp @@ -0,0 +1,17 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx> + * All rights reserved. Distributed under the terms of the MIT License. + */ + + +#include <stdio.h> + +#include "App.h" + + +int +main(int argc, char* argv[]) +{ + App().Run(); + return 0; +} diff --git a/src/apps/haiku-depot/support.cpp b/src/apps/haiku-depot/support.cpp new file mode 100644 index 0000000..022040d --- /dev/null +++ b/src/apps/haiku-depot/support.cpp @@ -0,0 +1,132 @@ +/* + * Copyright 2006, 2011, 2013 Stephan Aßmus <superstippi@xxxxxx> + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "support.h" + +#include <algorithm> +#include <stdio.h> +#include <string.h> + +#include <Directory.h> +#include <File.h> +#include <FindDirectory.h> +#include <Path.h> +#include <Screen.h> + + +status_t +load_settings(BMessage* message, const char* fileName, const char* folder) +{ + if (message == NULL || fileName == NULL || fileName[0] == '\0') + return B_BAD_VALUE; + + BPath path; + status_t ret = find_directory(B_USER_SETTINGS_DIRECTORY, &path); + if (ret != B_OK) + return ret; + + // passing folder is optional + if (folder != NULL) + ret = path.Append(folder); + + if (ret == B_OK && (ret = path.Append(fileName)) == B_OK ) { + BFile file(path.Path(), B_READ_ONLY); + ret = file.InitCheck(); + if (ret == B_OK) + ret = message->Unflatten(&file); + } + + return ret; +} + + +status_t +save_settings(BMessage* message, const char* fileName, const char* folder) +{ + if (message == NULL || fileName == NULL || fileName[0] == '\0') + return B_BAD_VALUE; + + BPath path; + status_t ret = find_directory(B_USER_SETTINGS_DIRECTORY, &path); + if (ret != B_OK) + return ret; + + // passing folder is optional + if (folder != NULL) + ret = path.Append(folder); + + if (ret == B_OK) + ret = create_directory(path.Path(), 0777); + + if (ret == B_OK) + ret = path.Append(fileName); + + if (ret == B_OK) { + BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); + ret = file.InitCheck(); + if (ret == B_OK) + ret = message->Flatten(&file); + } + + return ret; +} + + +bool +make_sure_frame_is_on_screen(BRect& frame, float borderWidth, + float tabHeight, BWindow* window) +{ + if (!frame.IsValid()) + return false; + + BScreen* screen = window != NULL ? new BScreen(window) + : new BScreen(B_MAIN_SCREEN_ID); + + if (!screen->IsValid()) { + delete screen; + return false; + } + + BRect screenFrame = screen->Frame(); + + // Validate borderWidth and tabHeight + if (borderWidth < 0.0f) + borderWidth = 0.0f; + else + borderWidth = std::min(borderWidth, floorf(screenFrame.Width() / 4.0f)); + + if (tabHeight < 0.0f) + tabHeight = 0.0f; + else + tabHeight = std::min(tabHeight, floorf(screenFrame.Height() / 4.0f)); + + // Account for window border and tab. It doesn't matter much if the + // decorator frame is wider, just as long as the user can grab a + // border to move the window + screenFrame.InsetBy(borderWidth, borderWidth); + screenFrame.top += tabHeight; + + if (!screenFrame.Contains(frame)) { + // make sure frame fits in the screen + if (frame.Width() > screenFrame.Width()) + frame.right -= frame.Width() - screenFrame.Width(); + if (frame.Height() > screenFrame.Height()) + frame.bottom -= frame.Height() - screenFrame.Height(); + + // frame is now at the most the size of the screen + if (frame.right > screenFrame.right) + frame.OffsetBy(-(frame.right - screenFrame.right), 0.0); + if (frame.bottom > screenFrame.bottom) + frame.OffsetBy(0.0, -(frame.bottom - screenFrame.bottom)); + if (frame.left < screenFrame.left) + frame.OffsetBy((screenFrame.left - frame.left), 0.0); + if (frame.top < screenFrame.top) + frame.OffsetBy(0.0, (screenFrame.top - frame.top)); + } + + delete screen; + return true; +} + diff --git a/src/apps/haiku-depot/support.h b/src/apps/haiku-depot/support.h new file mode 100644 index 0000000..a23b3ac --- /dev/null +++ b/src/apps/haiku-depot/support.h @@ -0,0 +1,26 @@ +/* + * Copyright 2006, 2013 Stephan Aßmus <superstippi@xxxxxx> + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#ifndef SUPPORT_H +#define SUPPORT_H + +#include <Rect.h> + + +class BMessage; +class BWindow; + + +status_t load_settings(BMessage* message, const char* fileName, + const char* folder = NULL); + +status_t save_settings(BMessage* message, const char* fileName, + const char* folder = NULL); + +bool make_sure_frame_is_on_screen(BRect& frame, float borderWidth = 5.0f, + float tabHeight = 20.0f, BWindow* window = NULL); + + +#endif // SUPPORT_H ############################################################################ Commit: 8608501abb80f5a1490b10b8c5044e0e4a996e1e URL: http://cgit.haiku-os.org/haiku/commit/?id=8608501 Author: Stephan Aßmus <superstippi@xxxxxx> Date: Sat Jul 27 20:21:58 2013 UTC HaikuDepot: BGroupView for the controls defining list contents ---------------------------------------------------------------------------- diff --git a/src/apps/haiku-depot/FilterView.cpp b/src/apps/haiku-depot/FilterView.cpp new file mode 100644 index 0000000..50c12a3 --- /dev/null +++ b/src/apps/haiku-depot/FilterView.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "FilterView.h" + +#include <algorithm> +#include <stdio.h> + +#include <Catalog.h> +#include <LayoutBuilder.h> +#include <MenuField.h> +#include <MenuItem.h> +#include <Messenger.h> +#include <PopUpMenu.h> +#include <TextControl.h> + + +#undef B_TRANSLATION_CONTEXT +#define B_TRANSLATION_CONTEXT "FilterView" + + +enum { + MSG_CATEGORY_SELECTED = 'ctsl', + MSG_REPOSITORY_SELECTED = 'rpsl', + MSG_SEARCH_TERMS_MODIFIED = 'stmd', +}; + + +FilterView::FilterView() + : + BGroupView("filter view") +{ + // Contruct category popup + BPopUpMenu* categoryMenu = new BPopUpMenu(B_TRANSLATE("Category")); + fCategoryField = new BMenuField("category", B_TRANSLATE("Category:"), + categoryMenu); + + // Construct repository popup + BPopUpMenu* repositoryMenu = new BPopUpMenu(B_TRANSLATE("Depot")); + fRepositoryField = new BMenuField("repository", B_TRANSLATE("Depot:"), + repositoryMenu); + + // Construct search terms field + fSearchTermsText = new BTextControl("search terms", + B_TRANSLATE("Search terms:"), "", NULL); + fSearchTermsText->SetModificationMessage( + new BMessage(MSG_SEARCH_TERMS_MODIFIED)); + + BSize minSearchSize = fSearchTermsText->MinSize(); + float minSearchWidth + = be_plain_font->StringWidth(fSearchTermsText->Label()) + + be_plain_font->StringWidth("XXX") * 6; + minSearchWidth = std::max(minSearchSize.width, minSearchWidth); + minSearchSize.width = minSearchWidth; + fSearchTermsText->SetExplicitMinSize(minSearchSize); + float maxSearchWidth = minSearchWidth * 2; + fSearchTermsText->SetExplicitMaxSize(BSize(maxSearchWidth, B_SIZE_UNSET)); + + // Build layout + BLayoutBuilder::Group<>(this) + .Add(fCategoryField, 0.0f) + .Add(fRepositoryField, 0.0f) + .AddGlue(0.5f) + .Add(fSearchTermsText, 1.0f) + + .SetInsets(B_USE_DEFAULT_SPACING) + ; +} + + +FilterView::~FilterView() +{ +} + + +void +FilterView::AttachedToWindow() +{ + fCategoryField->Menu()->SetTargetForItems(this); + fRepositoryField->Menu()->SetTargetForItems(this); + fSearchTermsText->SetTarget(this); +} + + +void +FilterView::MessageReceived(BMessage* message) +{ + switch (message->what) { + default: + BGroupView::MessageReceived(message); + break; + } +} diff --git a/src/apps/haiku-depot/FilterView.h b/src/apps/haiku-depot/FilterView.h new file mode 100644 index 0000000..d52adcf --- /dev/null +++ b/src/apps/haiku-depot/FilterView.h @@ -0,0 +1,29 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef FILTER_VIEW_H +#define FILTER_VIEW_H + +#include <GroupView.h> + + +class BMenuField; +class BTextControl; + + +class FilterView : public BGroupView { +public: + FilterView(); + virtual ~FilterView(); + + virtual void AttachedToWindow(); + virtual void MessageReceived(BMessage* message); + +private: + BMenuField* fCategoryField; + BMenuField* fRepositoryField; + BTextControl* fSearchTermsText; +}; + +#endif // FILTER_VIEW_H ############################################################################ Commit: 7fa83160f89bc5b4c988ba45b07991f8c71e7111 URL: http://cgit.haiku-os.org/haiku/commit/?id=7fa8316 Author: Stephan Aßmus <superstippi@xxxxxx> Date: Sat Jul 27 20:23:25 2013 UTC HaikuDepot: PackagesListView BColumnListView derived class with code-duplication from DriveSetup that should be refactored eventually (BIconStringColumn and BColumn implementation to show it). Does nothing except create some columns. ---------------------------------------------------------------------------- diff --git a/src/apps/haiku-depot/PackageListView.cpp b/src/apps/haiku-depot/PackageListView.cpp new file mode 100644 index 0000000..2877d6f --- /dev/null +++ b/src/apps/haiku-depot/PackageListView.cpp @@ -0,0 +1,223 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "PackageListView.h" + +#include <algorithm> +#include <stdio.h> + +#include <Catalog.h> + + +#undef B_TRANSLATION_CONTEXT +#define B_TRANSLATION_CONTEXT "PackageListView" + + +// #pragma mark - BBitmapStringField + + +// TODO: Code-duplication with DriveSetup PartitionList.cpp +BBitmapStringField::BBitmapStringField(BBitmap* bitmap, const char* string) + : + Inherited(string), + fBitmap(bitmap) +{ +} + + +BBitmapStringField::~BBitmapStringField() +{ + delete fBitmap; +} + + +void +BBitmapStringField::SetBitmap(BBitmap* bitmap) +{ + delete fBitmap; + fBitmap = bitmap; + // TODO: cause a redraw? +} + + +// #pragma mark - PackageColumn + + +// TODO: Code-duplication with DriveSetup PartitionList.cpp + + +float PackageColumn::sTextMargin = 0.0; + + +PackageColumn::PackageColumn(const char* title, float width, float minWidth, + float maxWidth, uint32 truncateMode, alignment align) + : + Inherited(title, width, minWidth, maxWidth, align), + fTruncateMode(truncateMode) +{ + SetWantsEvents(true); +} + + +void +PackageColumn::DrawField(BField* field, BRect rect, BView* parent) +{ + BBitmapStringField* bitmapField + = dynamic_cast<BBitmapStringField*>(field); + BStringField* stringField = dynamic_cast<BStringField*>(field); + + if (bitmapField) { + const BBitmap* bitmap = bitmapField->Bitmap(); + + // figure out the placement + float x = 0.0; + BRect r = bitmap ? bitmap->Bounds() : BRect(0, 0, 15, 15); + float y = rect.top + ((rect.Height() - r.Height()) / 2); + float width = 0.0; + + switch (Alignment()) { + default: + case B_ALIGN_LEFT: + case B_ALIGN_CENTER: + x = rect.left + sTextMargin; + width = rect.right - (x + r.Width()) - (2 * sTextMargin); + r.Set(x + r.Width(), rect.top, rect.right - width, rect.bottom); + break; + + case B_ALIGN_RIGHT: + x = rect.right - sTextMargin - r.Width(); + width = (x - rect.left - (2 * sTextMargin)); + r.Set(rect.left, rect.top, rect.left + width, rect.bottom); + break; + } + + if (width != bitmapField->Width()) { + BString truncatedString(bitmapField->String()); + parent->TruncateString(&truncatedString, fTruncateMode, width + 2); + bitmapField->SetClippedString(truncatedString.String()); + bitmapField->SetWidth(width); + } + + // draw the bitmap + if (bitmap) { + parent->SetDrawingMode(B_OP_ALPHA); + parent->DrawBitmap(bitmap, BPoint(x, y)); + parent->SetDrawingMode(B_OP_OVER); + } + + // draw the string + DrawString(bitmapField->ClippedString(), parent, r); + + } else if (stringField) { + + float width = rect.Width() - (2 * sTextMargin); + + if (width != stringField->Width()) { + BString truncatedString(stringField->String()); + + parent->TruncateString(&truncatedString, fTruncateMode, width + 2); + stringField->SetClippedString(truncatedString.String()); + stringField->SetWidth(width); + } + + DrawString(stringField->ClippedString(), parent, rect); + } +} + + +float +PackageColumn::GetPreferredWidth(BField *_field, BView* parent) const +{ + BBitmapStringField* bitmapField + = dynamic_cast<BBitmapStringField*>(_field); + BStringField* stringField = dynamic_cast<BStringField*>(_field); + + float parentWidth = Inherited::GetPreferredWidth(_field, parent); + float width = 0.0; + + if (bitmapField) { + const BBitmap* bitmap = bitmapField->Bitmap(); + BFont font; + parent->GetFont(&font); + width = font.StringWidth(bitmapField->String()) + 3 * sTextMargin; + if (bitmap) + width += bitmap->Bounds().Width(); + else + width += 16; + } else if (stringField) { + BFont font; + parent->GetFont(&font); + width = font.StringWidth(stringField->String()) + 2 * sTextMargin; + } + return max_c(width, parentWidth); +} + + +bool +PackageColumn::AcceptsField(const BField* field) const +{ + return dynamic_cast<const BStringField*>(field) != NULL; +} + + +void +PackageColumn::InitTextMargin(BView* parent) +{ + BFont font; + parent->GetFont(&font); + sTextMargin = ceilf(font.Size() * 0.8); +} + + +// #pragma mark - PackageListView + + +enum { + kNameColumn, + kRatingColumn, + kDescriptionColumn, + kSizeColumn, + kStatusColumn, +}; + + +PackageListView::PackageListView() + : + BColumnListView("package list view", 0, B_FANCY_BORDER, true) +{ + AddColumn(new PackageColumn(B_TRANSLATE("Name"), 150, 50, 500, + B_TRUNCATE_MIDDLE), kNameColumn); + AddColumn(new PackageColumn(B_TRANSLATE("Rating"), 100, 50, 500, + B_TRUNCATE_MIDDLE), kRatingColumn); + AddColumn(new PackageColumn(B_TRANSLATE("Description"), 130, 50, 500, + B_TRUNCATE_MIDDLE), kDescriptionColumn); + AddColumn(new PackageColumn(B_TRANSLATE("Size"), 100, 50, 500, + B_TRUNCATE_END), kSizeColumn); + AddColumn(new PackageColumn(B_TRANSLATE("Status"), 100, 50, 500, + B_TRUNCATE_END), kStatusColumn); +} + + +PackageListView::~PackageListView() +{ +} + + +void +PackageListView::AttachedToWindow() +{ + PackageColumn::InitTextMargin(ScrollView()); +} + + +void +PackageListView::MessageReceived(BMessage* message) +{ + switch (message->what) { + default: + BColumnListView::MessageReceived(message); + break; + } +} diff --git a/src/apps/haiku-depot/PackageListView.h b/src/apps/haiku-depot/PackageListView.h new file mode 100644 index 0000000..ac23889 --- /dev/null +++ b/src/apps/haiku-depot/PackageListView.h @@ -0,0 +1,67 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef PACKAGE_LIST_VIEW_H +#define PACKAGE_LIST_VIEW_H + + +#include <ColumnListView.h> +#include <ColumnTypes.h> + + +// A field type displaying both a bitmap and a string so that the +// tree display looks nicer (both text and bitmap are indented) +// TODO: Code-duplication with DriveSetup PartitionList.h +class BBitmapStringField : public BStringField { + typedef BStringField Inherited; +public: + BBitmapStringField(BBitmap* bitmap, + const char* string); + virtual ~BBitmapStringField(); + + void SetBitmap(BBitmap* bitmap); + const BBitmap* Bitmap() const + { return fBitmap; } + +private: + BBitmap* fBitmap; +}; + + +// BColumn for PackageListView which knows how to render +// a BBitmapStringField +// TODO: Code-duplication with DriveSetup PartitionList.h +class PackageColumn : public BTitledColumn { + typedef BTitledColumn Inherited; +public: + PackageColumn(const char* title, + float width, float minWidth, + float maxWidth, uint32 truncateMode, + alignment align = B_ALIGN_LEFT); + + virtual void DrawField(BField* field, BRect rect, + BView* parent); + virtual float GetPreferredWidth(BField* field, + BView* parent) const; + + virtual bool AcceptsField(const BField* field) const; + + static void InitTextMargin(BView* parent); + +private: + uint32 fTruncateMode; + static float sTextMargin; +}; + + +class PackageListView : public BColumnListView { +public: + PackageListView(); + virtual ~PackageListView(); + + virtual void AttachedToWindow(); + virtual void MessageReceived(BMessage* message); +}; + +#endif // PACKAGE_LIST_VIEW_H ############################################################################ Commit: f344b1dca68ddc2e9688bf9c6f966ca74c7f9def URL: http://cgit.haiku-os.org/haiku/commit/?id=f344b1d Author: Stephan Aßmus <superstippi@xxxxxx> Date: Sat Jul 27 20:25:08 2013 UTC HaikuDepot: BGroupView holding buttons for package actions... ... that can be applied to the selected package(s). Does nothing except create the buttons and layout. ---------------------------------------------------------------------------- diff --git a/src/apps/haiku-depot/PackageActionsView.cpp b/src/apps/haiku-depot/PackageActionsView.cpp new file mode 100644 index 0000000..8d18043 --- /dev/null +++ b/src/apps/haiku-depot/PackageActionsView.cpp @@ -0,0 +1,81 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "PackageActionsView.h" + +#include <algorithm> +#include <stdio.h> + +#include <Button.h> +#include <Catalog.h> +#include <LayoutBuilder.h> +#include <Message.h> + + +#undef B_TRANSLATION_CONTEXT +#define B_TRANSLATION_CONTEXT "PackageActionsView" + + +enum { + MSG_INSTALL = 'inst', + MSG_TOGGLE_ACTIVE = 'tgac', + MSG_UPDATE = 'stmd', + MSG_UNINSTALL = 'dein', +}; + + +PackageActionsView::PackageActionsView() + : + BGroupView("package actions view") +{ + // Contruct action buttons + fInstallButton = new BButton("install", B_TRANSLATE("Install"), + new BMessage(MSG_INSTALL)); + + fToggleActiveButton = new BButton("toggle active", + B_TRANSLATE("Deactivate"), new BMessage(MSG_TOGGLE_ACTIVE)); + + fUpdateButton = new BButton("update", + B_TRANSLATE("Update"), new BMessage(MSG_UPDATE)); + + fUninstallButton = new BButton("uninstall", B_TRANSLATE("Uninstall"), + new BMessage(MSG_UNINSTALL)); + + // Build layout + BLayoutBuilder::Group<>(this) + .AddGlue(1.0f) + .Add(fUninstallButton) + .AddGlue(0.1f) + .Add(fUpdateButton) + .Add(fToggleActiveButton) + .Add(fInstallButton) + ; +} + + +PackageActionsView::~PackageActionsView() +{ +} + + +void +PackageActionsView::AttachedToWindow() +{ + fInstallButton->SetTarget(this); + fToggleActiveButton->SetTarget(this); + fUpdateButton->SetTarget(this); + fUninstallButton->SetTarget(this); +} + + +void +PackageActionsView::MessageReceived(BMessage* message) +{ + switch (message->what) { + default: + BGroupView::MessageReceived(message); + break; + } +} diff --git a/src/apps/haiku-depot/PackageActionsView.h b/src/apps/haiku-depot/PackageActionsView.h new file mode 100644 index 0000000..02ef03c --- /dev/null +++ b/src/apps/haiku-depot/PackageActionsView.h @@ -0,0 +1,29 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef PACKAGE_ACTIONS_VIEW_H +#define PACKAGE_ACTIONS_VIEW_H + +#include <GroupView.h> + + +class BButton; + + +class PackageActionsView : public BGroupView { +public: + PackageActionsView(); + virtual ~PackageActionsView(); + + virtual void AttachedToWindow(); + virtual void MessageReceived(BMessage* message); + +private: + BButton* fInstallButton; + BButton* fToggleActiveButton; + BButton* fUpdateButton; + BButton* fUninstallButton; +}; + +#endif // PACKAGE_ACTIONS_VIEW_H ############################################################################ Commit: ac7d911bae29ef07fc8f0c55f4f88376ea9aee19 URL: http://cgit.haiku-os.org/haiku/commit/?id=ac7d911 Author: Stephan Aßmus <superstippi@xxxxxx> Date: Sat Jul 27 20:27:02 2013 UTC HaikuDepot: Added new classes to build and main window. ---------------------------------------------------------------------------- diff --git a/src/apps/haiku-depot/Jamfile b/src/apps/haiku-depot/Jamfile index f788c3e..3b8e2d0 100644 --- a/src/apps/haiku-depot/Jamfile +++ b/src/apps/haiku-depot/Jamfile @@ -1,13 +1,17 @@ SubDir HAIKU_TOP src apps haiku-depot ; -UsePrivateHeaders shared ; +UsePrivateHeaders interface shared ; Application HaikuDepot : App.cpp + FilterView.cpp main.cpp MainWindow.cpp + PackageActionsView.cpp + PackageListView.cpp support.cpp - : be translation libshared.a $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS) + : be translation libcolumnlistview.a libshared.a $(TARGET_LIBSUPC++) + $(HAIKU_LOCALE_LIBS) : HaikuDepot.rdef ; @@ -15,5 +19,8 @@ DoCatalogs HaikuDepot : x-vnd.Haiku-HaikuDepot : App.cpp + FilterView.cpp MainWindow.cpp + PackageActionsView.cpp + PackageListView.cpp ; diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp index 73f106c..e25bbc7 100644 --- a/src/apps/haiku-depot/MainWindow.cpp +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -12,21 +12,56 @@ #include <Button.h> #include <Catalog.h> #include <LayoutBuilder.h> -#include <Menu.h> +#include <MenuBar.h> #include <MenuItem.h> #include <Messenger.h> #include <ScrollView.h> #include <TabView.h> +#include "FilterView.h" +#include "PackageActionsView.h" +#include "PackageListView.h" + + #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "MainWindow" + MainWindow::MainWindow(BRect frame) : BWindow(frame, B_TRANSLATE_SYSTEM_NAME("HaikuDepot"), B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS) { + BMenuBar* mainMenu = new BMenuBar(B_TRANSLATE("Main Menu")); + BMenu* menu = new BMenu(B_TRANSLATE("Package")); + mainMenu->AddItem(menu); + + FilterView* filterView = new FilterView(); + + PackageListView* packageListView = new PackageListView(); + + PackageActionsView* packageActionsView = new PackageActionsView(); + + BSplitView* splitView = new BSplitView(B_VERTICAL, B_USE_SMALL_SPACING); + + BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) + .Add(mainMenu) + .Add(filterView) + .AddGroup(B_VERTICAL) + .AddSplit(splitView) + .AddGroup(B_VERTICAL) + .Add(packageListView) + .Add(packageActionsView) + .End() + .Add(new BGroupView) + .End() + .SetInsets(B_USE_DEFAULT_SPACING, 0.0f, B_USE_DEFAULT_SPACING, + B_USE_DEFAULT_SPACING) + .End() + ; + + splitView->SetCollapsible(0, false); } ############################################################################ Commit: 713ce3be95f86c487245ef502557a70423be16b4 URL: http://cgit.haiku-os.org/haiku/commit/?id=713ce3b Author: Stephan Aßmus <superstippi@xxxxxx> Date: Sat Jul 27 20:54:18 2013 UTC HaikuDepot: BTabView with About, Rating & comments and Changelog Completely non-functional. Should be replaced by something visually more unified. The selected package's title and icon should be always visible above the three sections, and the sections should not be tabs but something more subtle. ---------------------------------------------------------------------------- diff --git a/src/apps/haiku-depot/PackageInfoView.cpp b/src/apps/haiku-depot/PackageInfoView.cpp new file mode 100644 index 0000000..662f1ab --- /dev/null +++ b/src/apps/haiku-depot/PackageInfoView.cpp @@ -0,0 +1,61 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "PackageInfoView.h" + +#include <algorithm> +#include <stdio.h> + +#include <Button.h> +#include <Catalog.h> +#include <LayoutBuilder.h> +#include <Message.h> + + +#undef B_TRANSLATION_CONTEXT +#define B_TRANSLATION_CONTEXT "PackageInfoView" + + +PackageInfoView::PackageInfoView() + : + BTabView("package info view", B_WIDTH_FROM_WIDEST) +{ + fDescriptionView = new BView("about", 0); + AddTab(fDescriptionView); + + fRatingAndCommentsView = new BView("rating and comments", 0); + AddTab(fRatingAndCommentsView); + + fChangeLogView = new BView("changelog", 0); + AddTab(fChangeLogView); + + TabAt(0)->SetLabel(B_TRANSLATE("About")); + TabAt(1)->SetLabel(B_TRANSLATE("Rating & comments")); + TabAt(2)->SetLabel(B_TRANSLATE("Changelog")); + + Select(0); +} + + +PackageInfoView::~PackageInfoView() +{ +} + + +void +PackageInfoView::AttachedToWindow() +{ +} + + +void +PackageInfoView::MessageReceived(BMessage* message) +{ + switch (message->what) { + default: + BTabView::MessageReceived(message); + break; + } +} diff --git a/src/apps/haiku-depot/PackageInfoView.h b/src/apps/haiku-depot/PackageInfoView.h new file mode 100644 index 0000000..d174988 --- /dev/null +++ b/src/apps/haiku-depot/PackageInfoView.h @@ -0,0 +1,25 @@ +/* + * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef PACKAGE_INFO_VIEW_H +#define PACKAGE_INFO_VIEW_H + +#include <TabView.h> + + +class PackageInfoView : public BTabView { +public: + PackageInfoView(); + virtual ~PackageInfoView(); + + virtual void AttachedToWindow(); + virtual void MessageReceived(BMessage* message); + +private: + BView* fDescriptionView; + BView* fRatingAndCommentsView; + BView* fChangeLogView; +}; + +#endif // PACKAGE_INFO_VIEW_H ############################################################################ Commit: fade0fd59d36e04676ac28c48474627c3551a0c2 URL: http://cgit.haiku-os.org/haiku/commit/?id=fade0fd Author: Stephan Aßmus <superstippi@xxxxxx> Date: Sat Jul 27 20:56:20 2013 UTC HaikuDepot: Added PackageInfoView, moved buttons to bottom ---------------------------------------------------------------------------- diff --git a/src/apps/haiku-depot/Jamfile b/src/apps/haiku-depot/Jamfile index 3b8e2d0..cb532f3 100644 --- a/src/apps/haiku-depot/Jamfile +++ b/src/apps/haiku-depot/Jamfile @@ -8,6 +8,7 @@ Application HaikuDepot : main.cpp MainWindow.cpp PackageActionsView.cpp + PackageInfoView.cpp PackageListView.cpp support.cpp : be translation libcolumnlistview.a libshared.a $(TARGET_LIBSUPC++) @@ -22,5 +23,6 @@ DoCatalogs HaikuDepot : FilterView.cpp MainWindow.cpp PackageActionsView.cpp + PackageInfoView.cpp PackageListView.cpp ; diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp index e25bbc7..6008c49 100644 --- a/src/apps/haiku-depot/MainWindow.cpp +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -20,6 +20,7 @@ #include "FilterView.h" #include "PackageActionsView.h" +#include "PackageInfoView.h" #include "PackageListView.h" @@ -42,6 +43,8 @@ MainWindow::MainWindow(BRect frame) PackageListView* packageListView = new PackageListView(); PackageActionsView* packageActionsView = new PackageActionsView(); + + PackageInfoView* packageInfoView = new PackageInfoView(); BSplitView* splitView = new BSplitView(B_VERTICAL, B_USE_SMALL_SPACING); @@ -50,12 +53,10 @@ MainWindow::MainWindow(BRect frame) .Add(filterView) .AddGroup(B_VERTICAL) .AddSplit(splitView) - .AddGroup(B_VERTICAL) - .Add(packageListView) - .Add(packageActionsView) - .End() - .Add(new BGroupView) + .Add(packageListView) + .Add(packageInfoView) .End() + .Add(packageActionsView) .SetInsets(B_USE_DEFAULT_SPACING, 0.0f, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) .End() ############################################################################ Revision: hrev45907 Commit: 1b28bb090d027971096afce1c1edc69264d1f6b1 URL: http://cgit.haiku-os.org/haiku/commit/?id=1b28bb0 Author: Stephan Aßmus <superstippi@xxxxxx> Date: Sat Jul 27 21:14:43 2013 UTC HaikuDepot: Populate menu fields (non-functional) ---------------------------------------------------------------------------- diff --git a/src/apps/haiku-depot/FilterView.cpp b/src/apps/haiku-depot/FilterView.cpp index 50c12a3..e630553 100644 --- a/src/apps/haiku-depot/FilterView.cpp +++ b/src/apps/haiku-depot/FilterView.cpp @@ -34,11 +34,34 @@ FilterView::FilterView() { // Contruct category popup BPopUpMenu* categoryMenu = new BPopUpMenu(B_TRANSLATE("Category")); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All packages"), NULL)); + categoryMenu->AddItem(new BSeparatorItem()); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Audio"), NULL)); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Games"), NULL)); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Graphics"), NULL)); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Development"), NULL)); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Miscellaneous"), NULL)); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Shell"), NULL)); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Video"), NULL)); + categoryMenu->AddItem(new BSeparatorItem()); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Installed packages"), + NULL)); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Uninstalled packages"), + NULL)); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("User selected packages"), + NULL)); + categoryMenu->AddItem(new BSeparatorItem()); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Downloading"), NULL)); + categoryMenu->AddItem(new BMenuItem(B_TRANSLATE("Update available"), NULL)); + categoryMenu->ItemAt(0)->SetMarked(true); + fCategoryField = new BMenuField("category", B_TRANSLATE("Category:"), categoryMenu); // Construct repository popup BPopUpMenu* repositoryMenu = new BPopUpMenu(B_TRANSLATE("Depot")); + repositoryMenu->AddItem(new BMenuItem(B_TRANSLATE("All depots"), NULL)); + repositoryMenu->ItemAt(0)->SetMarked(true); fRepositoryField = new BMenuField("repository", B_TRANSLATE("Depot:"), repositoryMenu);