New notifications area at the top-right corner

This commit is contained in:
David Capello 2014-05-25 11:21:10 -03:00
parent d18b9a403b
commit 08fb98d40d
13 changed files with 197 additions and 17 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -77,6 +77,9 @@
<color id="timeline_padding" value="#7d929e" />
<color id="status_bar_text" value="#2e3234" />
<color id="status_bar_face" value="#7d929e" />
<color id="flag_normal" value="#d3cbbe" />
<color id="flag_active" value="#ff0000" />
<color id="flag_clicked" value="#7d929e" />
</colors>
<cursors>
@ -318,6 +321,8 @@
<part id="timeline_drop_layer_deco" x="252" y="127" w1="3" w2="1" w3="3" h1="2" h2="1" h3="2" />
<part id="timeline_drop_frame_deco" x="252" y="120" w1="2" w2="1" w3="2" h1="3" h2="1" h3="3" />
<part id="timeline_loop_range" x="240" y="132" w1="3" w2="6" w3="3" h1="3" h2="6" h3="3" />
<part id="flag_normal" x="0" y="240" w="16" h="10" />
<part id="flag_highlight" x="16" y="240" w="16" h="10" />
</parts>
<stylesheet>
@ -525,6 +530,17 @@
<background part="timeline_loop_range" />
</style>
<!-- flag -->
<style id="flag">
<background part="flag_normal" color="flag_normal" />
</style>
<style id="flag:active">
<background part="flag_highlight" color="flag_active" />
</style>
<style id="flag:clicked">
<background part="flag_highlight" color="flag_clicked" />
</style>
</stylesheet>
</skin>

View File

@ -183,6 +183,7 @@ add_library(app-lib
ui/main_menu_bar.cpp
ui/main_window.cpp
ui/mini_editor.cpp
ui/notifications.cpp
ui/palette_listbox.cpp
ui/palette_popup.cpp
ui/palette_view.cpp

View File

@ -331,6 +331,11 @@ RecentFiles* App::getRecentFiles() const
return &m_modules->m_recent_files;
}
void App::showNotification(const char* text, const char* url)
{
m_mainWindow->showNotification(text, url);
}
// Updates palette and redraw the screen.
void app_refresh_screen()
{

View File

@ -71,6 +71,8 @@ namespace app {
RecentFiles* getRecentFiles() const;
MainWindow* getMainWindow() const { return m_mainWindow; }
void showNotification(const char* text, const char* url);
// App Signals
Signal0<void> Exit;
Signal0<void> PaletteChange;

View File

@ -24,8 +24,8 @@
#include "app/check_update.h"
#include "app/app.h"
#include "app/ini_file.h"
#include "app/ui/status_bar.h"
#include "base/bind.h"
#include <ctime>
@ -169,7 +169,7 @@ void CheckUpdateThreadLauncher::onMonitoringTick()
case updater::CheckUpdateResponse::Critical:
case updater::CheckUpdateResponse::Major:
StatusBar::instance()->showNotification("New Version!", m_response.getUrl().c_str());
App::instance()->showNotification("New Version Available!", m_response.getUrl().c_str());
break;
}

View File

@ -36,6 +36,9 @@
#include "app/ui/editor/editor_view.h"
#include "app/ui/main_menu_bar.h"
#include "app/ui/mini_editor.h"
#include "app/ui/notifications.h"
#include "app/ui/skin/skin_property.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/start_view.h"
#include "app/ui/status_bar.h"
#include "app/ui/tabs.h"
@ -77,6 +80,7 @@ MainWindow::MainWindow()
Widget* box_timeline = findChild("timeline");
m_menuBar = new MainMenuBar();
m_notifications = new Notifications();
m_contextBar = new ContextBar();
m_statusBar = new StatusBar();
m_colorBar = new ColorBar(box_colorbar->getAlign());
@ -99,12 +103,16 @@ MainWindow::MainWindow()
m_tabsBar->setExpansive(true);
m_timeline->setExpansive(true);
m_workspace->setExpansive(true);
m_notifications->setVisible(false);
// Setup the menus
m_menuBar->setMenu(AppMenus::instance()->getRootMenu());
// Add the widgets in the boxes
if (box_menubar) box_menubar->addChild(m_menuBar);
if (box_menubar) {
box_menubar->addChild(m_menuBar);
box_menubar->addChild(m_notifications);
}
if (box_contextbar) box_contextbar->addChild(m_contextBar);
if (box_colorbar) box_colorbar->addChild(m_colorBar);
if (box_toolbar) box_toolbar->addChild(m_toolBar);
@ -149,6 +157,13 @@ void MainWindow::reloadMenus()
invalidate();
}
void MainWindow::showNotification(const char* text, const char* url)
{
m_notifications->addLink(text, url);
m_notifications->setVisible(true);
m_notifications->getParent()->layout();
}
void MainWindow::setMode(Mode mode)
{
// Check if we already are in the given mode.

View File

@ -33,6 +33,7 @@ namespace app {
class ContextBar;
class MainMenuBar;
class MiniEditorWindow;
class Notifications;
class StartView;
class StatusBar;
class Tabs;
@ -60,6 +61,7 @@ namespace app {
void start();
void reloadMenus();
void showNotification(const char* text, const char* url);
Mode getMode() const { return m_mode; }
void setMode(Mode mode);
@ -93,6 +95,7 @@ namespace app {
Workspace* m_workspace;
MiniEditorWindow* m_miniEditor;
StartView* m_startView;
Notifications* m_notifications;
};
}

View File

@ -0,0 +1,97 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/ui/notifications.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/skin/style.h"
#include "base/launcher.h"
#include "ui/menu.h"
#include "ui/paint_event.h"
#include "ui/preferred_size_event.h"
namespace app {
using namespace ui;
static const char* kFlag = "flag";
class NotificationItem : public MenuItem {
public:
NotificationItem(const char* text, const char* url)
: MenuItem(text),
m_url(url) {
}
protected:
void onClick() OVERRIDE {
MenuItem::onClick();
if (!m_url.empty())
base::launcher::open_url(m_url);
}
private:
std::string m_url;
};
Notifications::Notifications()
: Button("")
, m_flagStyle(skin::get_style(kFlag))
, m_withNotifications(false)
{
}
void Notifications::addLink(const char* text, const char* url)
{
m_popup.addChild(new NotificationItem(text, url));
m_withNotifications = true;
}
void Notifications::onPreferredSize(PreferredSizeEvent& ev)
{
ev.setPreferredSize(gfx::Size(16, 10)*jguiscale()); // TODO hard-coded flag size
}
void Notifications::onPaint(PaintEvent& ev)
{
Graphics* g = ev.getGraphics();
skin::Style::State state;
if (hasMouseOver()) state += skin::Style::hover();
if (m_withNotifications) state += skin::Style::active();
if (isSelected()) state += skin::Style::clicked();
m_flagStyle->paint(g, getClientBounds(), NULL, state);
}
void Notifications::onClick(ui::Event& ev)
{
m_withNotifications = false;
invalidate();
gfx::Rect bounds = getBounds();
m_popup.showPopup(
bounds.x - m_popup.getPreferredSize().w,
bounds.y + bounds.h);
}
} // namespace app

View File

@ -0,0 +1,50 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_UI_NOTIFICATIONS_H_INCLUDED
#define APP_UI_NOTIFICATIONS_H_INCLUDED
#pragma once
#include "ui/button.h"
#include "ui/menu.h"
namespace app {
namespace skin {
class Style;
}
class Notifications : public ui::Button {
public:
Notifications();
void addLink(const char* text, const char* url);
protected:
void onPreferredSize(ui::PreferredSizeEvent& ev) OVERRIDE;
void onPaint(ui::PaintEvent& ev) OVERRIDE;
void onClick(ui::Event& ev) OVERRIDE;
private:
skin::Style* m_flagStyle;
bool m_withNotifications;
ui::Menu m_popup;
};
} // namespace app
#endif

View File

@ -371,14 +371,6 @@ void StatusBar::showTool(int msecs, tools::Tool* tool)
}
}
void StatusBar::showNotification(const char* text, const char* link)
{
m_linkLabel->setText(text);
m_linkLabel->setUrl(link);
layout();
invalidate();
}
//////////////////////////////////////////////////////////////////////
// Progress bars stuff

View File

@ -80,9 +80,6 @@ namespace app {
Progress* addProgress();
void removeProgress(Progress* progress);
// Method to show notifications (each notification can contain a link).
void showNotification(const char* text, const char* link);
protected:
bool onProcessMessage(ui::Message* msg) OVERRIDE;
void onResize(ui::ResizeEvent& ev) OVERRIDE;

View File

@ -346,7 +346,7 @@ void Menu::onPreferredSize(PreferredSizeEvent& ev)
UI_FOREACH_WIDGET_WITH_END(getChildren(), it, end) {
reqSize = (*it)->getPreferredSize();
if (this->getParent()->type == kMenuBarWidget) {
if (getParent() && getParent()->type == kMenuBarWidget) {
size.w += reqSize.w + ((it+1 != end) ? this->child_spacing: 0);
size.h = MAX(size.h, reqSize.h);
}
@ -872,13 +872,15 @@ void MenuItem::onClick()
void MenuItem::onPreferredSize(PreferredSizeEvent& ev)
{
Size size(0, 0);
int bar = (this->getParent()->getParent()->type == kMenuBarWidget);
bool bar = (getParent() &&
getParent()->getParent() &&
getParent()->getParent()->type == kMenuBarWidget);
if (hasText()) {
size.w =
+ this->border_width.l
+ getTextWidth()
+ ((bar) ? this->child_spacing/4: this->child_spacing)
+ (bar ? this->child_spacing/4: this->child_spacing)
+ this->border_width.r;
size.h =