From d9512848e468e26dcb67d87a66ecd677fd66844b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sat, 27 Jul 2013 09:34:14 +0200 Subject: [PATCH] Haiku-Depot: Initial skeleton application --- src/apps/Jamfile | 1 + src/apps/haiku-depot/App.cpp | 96 +++++++++++++++++++ src/apps/haiku-depot/App.h | 33 +++++++ src/apps/haiku-depot/HaikuDepot.rdef | 46 ++++++++++ src/apps/haiku-depot/Jamfile | 19 ++++ src/apps/haiku-depot/MainWindow.cpp | 60 ++++++++++++ src/apps/haiku-depot/MainWindow.h | 28 ++++++ src/apps/haiku-depot/main.cpp | 17 ++++ src/apps/haiku-depot/support.cpp | 132 +++++++++++++++++++++++++++ src/apps/haiku-depot/support.h | 26 ++++++ 10 files changed, 458 insertions(+) create mode 100644 src/apps/haiku-depot/App.cpp create mode 100644 src/apps/haiku-depot/App.h create mode 100644 src/apps/haiku-depot/HaikuDepot.rdef create mode 100644 src/apps/haiku-depot/Jamfile create mode 100644 src/apps/haiku-depot/MainWindow.cpp create mode 100644 src/apps/haiku-depot/MainWindow.h create mode 100644 src/apps/haiku-depot/main.cpp create mode 100644 src/apps/haiku-depot/support.cpp create mode 100644 src/apps/haiku-depot/support.h diff --git a/src/apps/Jamfile b/src/apps/Jamfile index 6c3a8fc0ea..4cc22a1bd2 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 0000000000..fae6481046 --- /dev/null +++ b/src/apps/haiku-depot/App.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2013, Stephan Aßmus . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "App.h" + +#include + +#include +#include +#include +#include + +#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 0000000000..e48e61c291 --- /dev/null +++ b/src/apps/haiku-depot/App.h @@ -0,0 +1,33 @@ +/* + * Copyright 2013, Stephan Aßmus . + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef APP_H +#define APP_H + + +#include +#include +#include + + +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 0000000000..c91dc910ca --- /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 0000000000..f788c3eb86 --- /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 0000000000..73f106c14e --- /dev/null +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -0,0 +1,60 @@ +/* + * Copyright 2013, Stephan Aßmus . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "MainWindow.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 0000000000..7f3476cfee --- /dev/null +++ b/src/apps/haiku-depot/MainWindow.h @@ -0,0 +1,28 @@ +/* + * Copyright 2013, Stephan Aßmus . + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef MAIN_WINDOW_H +#define MAIN_WINDOW_H + +#include + + +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 0000000000..f01d9159d6 --- /dev/null +++ b/src/apps/haiku-depot/main.cpp @@ -0,0 +1,17 @@ +/* + * Copyright 2013, Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT License. + */ + + +#include + +#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 0000000000..022040db5d --- /dev/null +++ b/src/apps/haiku-depot/support.cpp @@ -0,0 +1,132 @@ +/* + * Copyright 2006, 2011, 2013 Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "support.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + + +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 0000000000..a23b3ac5ef --- /dev/null +++ b/src/apps/haiku-depot/support.h @@ -0,0 +1,26 @@ +/* + * Copyright 2006, 2013 Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#ifndef SUPPORT_H +#define SUPPORT_H + +#include + + +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