diff --git a/Makefile b/Makefile index 19082f1..6c431c0 100644 --- a/Makefile +++ b/Makefile @@ -33,13 +33,15 @@ SRCS = \ src/AtomFeed.cpp, \ src/Config.cpp, \ src/Entry.cpp, \ + src/EntriesView.cpp, \ src/Feed.cpp, \ - src/FeedView.cpp, \ + src/FeedsView.cpp, \ src/Invocation.cpp \ src/MainWindow.cpp, \ src/Mimetypes.cpp, \ src/ProtocolListener.cpp, \ src/RssFeed.cpp, \ + src/UpdatesView.cpp, \ src/Util.cpp # Specify the resource definition files to use. Full or relative paths can be diff --git a/src/EntriesView.cpp b/src/EntriesView.cpp new file mode 100644 index 0000000..689f0df --- /dev/null +++ b/src/EntriesView.cpp @@ -0,0 +1,132 @@ +/* + * Copyright 2020, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "EntriesView.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +EntriesView::EntriesView(const char* name) + : + BGroupView(name, B_VERTICAL, B_USE_DEFAULT_SPACING) +{ + _InitInterface(); +} + + +void +EntriesView::AttachedToWindow() +{ + fEntryFolderText->SetTarget(this); + fEntryFolderBrowseButton->SetTarget(this); + fFileExtText->SetTarget(this); + + fOpenAsHtmlRadio->SetTarget(this); + fOpenAsUrlRadio->SetTarget(this); + fOpenWithSelectButton->SetTarget(this); +} + + +void +EntriesView::MessageReceived(BMessage* msg) +{ + switch (msg->what) + { + default: + { +// BWindow::MessageReceived(msg); + break; + } + } +} + + +void +EntriesView::_InitInterface() +{ + // Saving + fSavingBox = new BBox("saving"); + fSavingBox->SetLabel("Saving"); + + fEntryFolderLabel = new BStringView("entryFolderLabel", "Entry folder:"); + fEntryFolderText = new BTextControl("entryFolder", "", + "/boot/home/feeds/", new BMessage('ssss')); + fEntryFolderBrowseButton = new BButton("entryFolderBrowse", "Browse…", + new BMessage('mmmm')); + + fFileExtLabel = new BStringView("fileExtLabel", "File extension:"); + fFileExtText = new BTextControl("fileExt", "", "", new BMessage('ffff')); + + // Opening + fOpeningBox = new BBox("opening"); + fOpeningBox->SetLabel("Opening"); + + fOpenAsLabel = new BStringView("openAsLabel", "Open as:"); + fOpenAsHtmlRadio = new BRadioButton("asHtml", "HTML", new BMessage('ii')); + fOpenAsUrlRadio = new BRadioButton("asUrl", "URL", new BMessage('ii')); + + fOpenWithLabel = new BStringView("openWithLabel", "Open with:"); + fOpenWithMenu = new BPopUpMenu("openWith"); + fOpenWithMenuField = new BMenuField("openWithMenu", NULL, fOpenWithMenu); + fOpenWithMenu->AddItem(new BMenuItem("WebPositive", new BMessage('wwww'))); + fOpenWithSelectButton = new BButton("openWithSelect", "Select…", + new BMessage('mmmm')); + + + BLayoutBuilder::Group<>(fSavingBox, B_HORIZONTAL) + .SetInsets(B_USE_ITEM_INSETS) + .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) + .SetInsets(0, 20, B_USE_ITEM_INSETS, 0) + .Add(fEntryFolderLabel) + .Add(fFileExtLabel) + .End() + .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) + .SetInsets(0, 20, B_USE_ITEM_INSETS, 0) + .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) + .Add(fEntryFolderText) + .Add(fEntryFolderBrowseButton) + .End() + .Add(fFileExtText) + .End() + .End(); + + BLayoutBuilder::Group<>(fOpeningBox, B_HORIZONTAL, B_USE_HALF_ITEM_SPACING) + .SetInsets(B_USE_ITEM_INSETS) + .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) + .SetInsets(0, 20, B_USE_ITEM_INSETS, 0) + .Add(fOpenAsLabel) + .Add(fOpenWithLabel) + .End() + .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) + .SetInsets(0, 20, B_USE_ITEM_INSETS, 0) + .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) + .Add(fOpenAsHtmlRadio) + .Add(fOpenAsUrlRadio) + .AddGlue() + .End() + .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) + .Add(fOpenWithMenuField) + .Add(fOpenWithSelectButton) + .End() + .End() + .End(); + + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .SetInsets(B_USE_DEFAULT_SPACING) + .Add(fSavingBox) + .AddGlue() + .Add(fOpeningBox) + .AddGlue() + .End(); +} + + diff --git a/src/EntriesView.h b/src/EntriesView.h new file mode 100644 index 0000000..db4592f --- /dev/null +++ b/src/EntriesView.h @@ -0,0 +1,51 @@ +/* + * Copyright 2020, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef ENTRIESVIEW_H +#define ENTRIESVIEW_H + +#include +#include + +class BBox; +class BButton; +class BMenuField; +class BMessage; +class BPopUpMenu; +class BRadioButton; +class BStringView; +class BTextControl; + + +class EntriesView : public BGroupView { +public: + EntriesView(const char* name); + + void MessageReceived(BMessage* msg); + void AttachedToWindow(); + +private: + void _InitInterface(); + + + BBox* fSavingBox; + BStringView* fEntryFolderLabel; + BTextControl* fEntryFolderText; + BButton* fEntryFolderBrowseButton; + BStringView* fFileExtLabel; + BTextControl* fFileExtText; + + BBox* fOpeningBox; + BStringView* fOpenAsLabel; + BRadioButton* fOpenAsHtmlRadio; + BRadioButton* fOpenAsUrlRadio; + BStringView* fOpenWithLabel; + BPopUpMenu* fOpenWithMenu; + BMenuField* fOpenWithMenuField; + BButton* fOpenWithSelectButton; +}; + + +#endif // ENTRIESVIEW_H + diff --git a/src/FeedView.cpp b/src/FeedView.cpp deleted file mode 100644 index 56bf341..0000000 --- a/src/FeedView.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2020, Jaidyn Levesque - * All rights reserved. Distributed under the terms of the MIT license. - */ - -#include "FeedView.h" - -#include -#include -#include - - -FeedView::FeedView(const char* name) - : - BGroupView(name, B_VERTICAL, B_USE_DEFAULT_SPACING) -{ - _InitInterface(); -} - - -void -FeedView::MessageReceived(BMessage* msg) -{ -} - - -void -FeedView::_InitInterface() -{ - fTestButton = new BButton("stest", "Do Nothing!", - new BMessage('pppq')); - fTestButton->SetTarget(this); - fTestButton->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); - - BLayoutBuilder::Group<>(this, B_VERTICAL, 0) - .SetInsets(0, B_USE_DEFAULT_SPACING, 0, 0) - .Add(fTestButton) - .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING, B_USE_WINDOW_SPACING); -} - - diff --git a/src/FeedsView.cpp b/src/FeedsView.cpp new file mode 100644 index 0000000..4e7941b --- /dev/null +++ b/src/FeedsView.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2020, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "FeedsView.h" + +#include +#include +#include +#include +#include +#include + +#include + +FeedsView::FeedsView(const char* name) + : + BGroupView(name, B_VERTICAL, B_USE_DEFAULT_SPACING) +{ + _InitInterface(); +} + + +void +FeedsView::MessageReceived(BMessage* msg) +{ + switch (msg->what) + { + default: + { +// BWindow::MessageReceived(msg); + break; + } + } +} + + +void +FeedsView::_InitInterface() +{ + // Feeds list + fFeedsListView = new BListView("feedsList"); + fFeedsScrollView = new BScrollView("feedsScroll", fFeedsListView, + B_WILL_DRAW, false, true); + + font_height fontHeight; + GetFontHeight(&fontHeight); + int16 buttonHeight = int16(fontHeight.ascent + fontHeight.descent + 12); + BSize charButtonSize(buttonHeight, buttonHeight); + + // Add, Remove, Edit + fAddButton = new BButton("addFeed", "+", + new BMessage('fadd')); + fRemoveButton = new BButton("removeFeed", "-", + new BMessage('frem')); + + fAddButton->SetTarget(this); + fAddButton->SetExplicitSize(charButtonSize); + fRemoveButton->SetTarget(this); + fRemoveButton->SetExplicitSize(charButtonSize); + + + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .SetInsets(B_USE_DEFAULT_SPACING) + .Add(fFeedsScrollView) + + // Add, Remove, and Edit buttons + .AddGroup(B_HORIZONTAL, 0, 0.0) + .Add(new BSeparatorView(B_VERTICAL)) + .AddGroup(B_VERTICAL, 0, 0.0) + .AddGroup(B_HORIZONTAL, 1, 0.0) + .SetInsets(1) + .Add(fAddButton) + .Add(fRemoveButton) + .End() + .Add(new BSeparatorView(B_HORIZONTAL)) + .End() + .Add(new BSeparatorView(B_VERTICAL)) + .AddGlue() + .End(); +} + + diff --git a/src/FeedView.h b/src/FeedsView.h similarity index 53% rename from src/FeedView.h rename to src/FeedsView.h index 1c5848d..315f187 100644 --- a/src/FeedView.h +++ b/src/FeedsView.h @@ -2,28 +2,32 @@ * Copyright 2020, Jaidyn Levesque * All rights reserved. Distributed under the terms of the MIT license. */ -#ifndef FEEDVIEW_H -#define FEEDVIEW_H - +#ifndef FEEDSVIEW_H +#define FEEDSVIEW_H #include #include #include - class BMessage; +class BListView; +class BScrollView; -class FeedView : public BGroupView { +class FeedsView : public BGroupView { public: - FeedView(const char* name); + FeedsView(const char* name); void MessageReceived(BMessage* msg); + private: void _InitInterface(); - BButton* fTestButton; + BButton* fAddButton; + BButton* fRemoveButton; + BListView* fFeedsListView; + BScrollView* fFeedsScrollView; }; -#endif // FEEDVIEW_H +#endif // FEEDDVIEW_H diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index b242178..55abc40 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -12,7 +12,12 @@ #include #include +#include + #include "App.h" +#include "EntriesView.h" +#include "FeedsView.h" +#include "UpdatesView.h" enum { M_BUTTON_CLICKED = 'btcl' }; @@ -20,11 +25,10 @@ enum { M_BUTTON_CLICKED = 'btcl' }; MainWindow::MainWindow (void) : - BWindow(BRect(0,0,0,0), "Pogger", B_TITLED_WINDOW, B_NOT_RESIZABLE - | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS | B_QUIT_ON_WINDOW_CLOSE) + BWindow(BRect(BPoint(-1000.0, -1000.0), BSize(520, 380)), "Pogger", + B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE) { _InitInterface(); - MoveTo(BPoint(-1000.0,-1000.0)); MoveOnScreen(); } @@ -32,21 +36,14 @@ MainWindow::MainWindow (void) void MainWindow::MessageReceived(BMessage *msg) { - switch (msg->what) - { - case M_BUTTON_CLICKED: - { - BString labelString("Clicks: "); - labelString << "DAD"; - SetTitle(labelString.String()); - break; - } - default: - { - BWindow::MessageReceived(msg); - break; - } - } + switch (msg->what) + { + default: + { + BWindow::MessageReceived(msg); + break; + } + } } @@ -55,25 +52,32 @@ MainWindow::_InitInterface() { fBaseView = new BGroupView("baseView"); fTabView = new BTabView("tabView", B_WIDTH_FROM_WIDEST); - fFeedView = new FeedView("Feeds"); + fFeedsView = new FeedsView("Feeds"); + fEntriesView = new EntriesView("Entries"); + fUpdatesView = new UpdatesView("Updates"); - fTabView->AddTab(fFeedView); + fTabView->AddTab(fFeedsView); + fTabView->AddTab(fEntriesView); + fTabView->AddTab(fUpdatesView); fTabView->SetBorder(B_NO_BORDER); fBaseView->AddChild(fTabView); - fServiceToggleButton = new BButton("stoggle", "Start Service", - new BMessage('pppp')); -// fRevertButton->SetEnabled(false); - fServiceToggleButton->SetTarget(this); - fServiceToggleButton->SetExplicitAlignment( - BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); + fUpdateNowButton = new BButton("updateNow", "Update Now", + new BMessage('iiii')); + fUpdateNowButton->SetTarget(this); + fUpdateNowButton->SetExplicitAlignment( + BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE)); BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .SetInsets(0, B_USE_DEFAULT_SPACING, 0, 0) .Add(fBaseView) .Add(new BSeparatorView(B_HORIZONTAL)) .AddGroup(B_HORIZONTAL) - .Add(fServiceToggleButton) + .Add(fUpdateNowButton) .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING, B_USE_WINDOW_SPACING); + B_USE_DEFAULT_SPACING, B_USE_WINDOW_SPACING) + .End() + .End(); } + + diff --git a/src/MainWindow.h b/src/MainWindow.h index 8245040..131030d 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -1,14 +1,16 @@ -#ifndef PREFWINDOW_H -#define PREFWINDOW_H +#ifndef MAINWINDOW_H +#define MAINWINDOW_H #include -#include "FeedView.h" - class BButton; class BGroupView; class BTabView; +class EntriesView; +class FeedsView; +class UpdatesView; + class MainWindow : public BWindow { public: @@ -19,12 +21,15 @@ public: private: void _InitInterface(); - BGroupView* fBaseView; - BTabView* fTabView; - FeedView* fFeedView; + BGroupView* fBaseView; + BTabView* fTabView; + EntriesView* fEntriesView; + FeedsView* fFeedsView; + UpdatesView* fUpdatesView; - BButton* fServiceToggleButton; + BButton* fUpdateNowButton; }; -#endif +#endif // MAINWINDOW_H + diff --git a/src/UpdatesView.cpp b/src/UpdatesView.cpp new file mode 100644 index 0000000..b599e1a --- /dev/null +++ b/src/UpdatesView.cpp @@ -0,0 +1,125 @@ +/* + * Copyright 2020, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "UpdatesView.h" + +#include +#include +#include +#include +#include + +#include + + +UpdatesView::UpdatesView(const char* name) + : + BGroupView(name, B_VERTICAL, B_USE_DEFAULT_SPACING) +{ + _InitInterface(); +} + + +void +UpdatesView::AttachedToWindow() +{ + fNotifyNewCheck->SetTarget(this); + fNotifyErrorCheck->SetTarget(this); + fIntervalSlider->SetTarget(this); +} + + +void +UpdatesView::MessageReceived(BMessage* msg) +{ + switch (msg->what) + { + case 'iiii': + { + _UpdateIntervalLabel(); + break; + } + default: + { +// BWindow::MessageReceived(msg); + break; + } + } +} + + +void +UpdatesView::_InitInterface() +{ + fNotifyNewCheck = new BCheckBox("newNotify", "Notify about new entries", + new BMessage('nnnc')); + fNotifyErrorCheck = new BCheckBox("errorNotify", + "Notify about update failures", new BMessage('nnnc')); + + fNotificationsBox = new BBox("notifications"); + fNotificationsBox->SetLabel("Notifications"); + + fIntervalSlider = + new BSlider("interval", "Never automatically update", + new BMessage('iiii'), 0, 25, B_HORIZONTAL); + + fIntervalSlider->SetHashMarkCount(26); + fIntervalSlider->SetHashMarks(B_HASH_MARKS_BOTTOM); + fIntervalSlider->SetLimitLabels("Never", "24 hours"); + fIntervalSlider->SetModificationMessage(new BMessage('iiii')); + + fSchedulingBox = new BBox("scheduling"); + fSchedulingBox->SetLabel("Scheduling"); + + + BLayoutBuilder::Group<>(fNotificationsBox, B_VERTICAL, B_USE_HALF_ITEM_SPACING) + .SetInsets(B_USE_ITEM_INSETS) + .AddStrut(B_USE_ITEM_SPACING) + .Add(fNotifyNewCheck) + .Add(fNotifyErrorCheck) + .End(); + + BLayoutBuilder::Group<>(fSchedulingBox, B_VERTICAL, B_USE_HALF_ITEM_SPACING) + .SetInsets(B_USE_ITEM_INSETS) + .AddStrut(B_USE_ITEM_SPACING) + .Add(fIntervalSlider) + .End(); + + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .SetInsets(B_USE_DEFAULT_SPACING) + .Add(fNotificationsBox) + .AddGlue() + .Add(fSchedulingBox) + .AddGlue() + .End(); + + _UpdateIntervalLabel(); +} + + +void +UpdatesView::_UpdateIntervalLabel() +{ + int32 limit; + fIntervalSlider->GetLimits(NULL, &limit); + int index = fIntervalSlider->Position() / (1/(float)limit); + int hours = index - 1; + + BString newLabel; + BString strHour; + strHour << (int)hours; + + if (hours == -1 ) + newLabel = "Never automatically update"; + else if (hours == 0) + newLabel = "Update every 30 minutes"; + else + newLabel = "Update every %hour% hours"; + + newLabel.ReplaceAll("%hour%", strHour); + fIntervalSlider->SetLabel(newLabel.String()); +} + + diff --git a/src/UpdatesView.h b/src/UpdatesView.h new file mode 100644 index 0000000..4a2e6e9 --- /dev/null +++ b/src/UpdatesView.h @@ -0,0 +1,39 @@ +/* + * Copyright 2020, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef UPDATESVIEW_H +#define UPDATESVIEW_H + +#include +#include +#include + +class BBox; +class BCheckBox; +class BMessage; +class BSlider; + + +class UpdatesView : public BGroupView { +public: + UpdatesView(const char* name); + + void MessageReceived(BMessage* msg); + void AttachedToWindow(); + +private: + void _InitInterface(); + void _UpdateIntervalLabel(); + + BBox* fNotificationsBox; + BBox* fSchedulingBox; + + BCheckBox* fNotifyNewCheck; + BCheckBox* fNotifyErrorCheck; + BSlider* fIntervalSlider; +}; + + +#endif // UPDATESVIEW_H +