/*
Neutrino-GUI - DBoxII-Project
Copyright (C) 2001 Steffen Hehn 'McClean'
Homepage: http://dbox.cyberphoria.org/
Copyright (C) 2008-2009, 2011, 2013 Stefan Seyfried
License: GPL
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, see .
*/
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#define borderwidth 4
#define HINTBOX_MAX_HEIGHT 420
CHintBox::CHintBox(const neutrino_locale_t Caption, const char * const Text, const int Width, const char * const Icon)
{
const char * caption_tmp = g_Locale->getText(Caption);
init(caption_tmp, Text, Width, Icon);
}
CHintBox::CHintBox(const char * const Caption, const char * const Text, const int Width, const char * const Icon)
{
init(Caption, Text, Width, Icon);
}
void CHintBox::init(const char * const Caption, const char * const Text, const int Width, const char * const Icon)
{
char * begin;
char * pos;
int nw;
int scrollWidth = 0;
int maxLineWidth = 0;
message = strdup(Text);
width = Width;
theight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight();
fheight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight();
height = theight + fheight;
textStartX = 0;
caption = Caption;
begin = message;
while (true)
{
height += fheight;
if (height > HINTBOX_MAX_HEIGHT)
height -= fheight;
line.push_back(begin);
pos = strchr(begin, '\n');
if (pos != NULL)
{
*pos = 0;
begin = pos + 1;
}
else
break;
}
if (fheight != 0)
entries_per_page = ((height - theight) / fheight) - 1;
else /* avoid division by zero */
entries_per_page = 1;
current_page = 0;
unsigned int additional_width;
if (entries_per_page < line.size())
scrollWidth = 15;
else
scrollWidth = 0;
additional_width = 20 + scrollWidth;
if (Icon != NULL)
{
iconfile = Icon;
additional_width += 30;
}
else
iconfile = "";
nw = additional_width + g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getRenderWidth(caption);
if (nw > width)
width = nw;
for (std::vector::const_iterator it = line.begin(); it != line.end(); ++it)
{
int w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(*it);
maxLineWidth = std::max(maxLineWidth, w);
nw = additional_width + w;
if (nw > width)
width = nw;
}
/* make sure we don't overflow the usable area */
if (nw > (int)CFrameBuffer::getInstance()->getScreenWidth())
width = CFrameBuffer::getInstance()->getScreenWidth();
textStartX = (width - scrollWidth - maxLineWidth) / 2;
window = NULL;
}
CHintBox::~CHintBox(void)
{
if (window != NULL)
{
delete window;
window = NULL;
}
free(message);
}
void CHintBox::paint(void)
{
if (window != NULL)
{
/*
* do not paint stuff twice:
* => thread safety needed by movieplayer.cpp:
* one thread calls our paint method, the other one our hide method
* => no memory leaks
*/
return;
}
CFrameBuffer* frameBuffer = CFrameBuffer::getInstance();
window = new CFBWindow(frameBuffer->getScreenX() + ((frameBuffer->getScreenWidth() - width ) >> 1),
frameBuffer->getScreenY() + ((frameBuffer->getScreenHeight() - height) >> 2),
width + borderwidth,
height + borderwidth);
refresh();
}
void CHintBox::refresh(void)
{
if (window == NULL)
{
return;
}
//window->paintBoxRel(borderwidth, height, width, borderwidth, COL_INFOBAR_SHADOW_PLUS_0);
//window->paintBoxRel(width, borderwidth, borderwidth, height - borderwidth, COL_INFOBAR_SHADOW_PLUS_0);
window->paintBoxRel(width - 20, borderwidth, borderwidth + 20, height - borderwidth - 20, COL_INFOBAR_SHADOW_PLUS_0, RADIUS_LARGE, CORNER_TOP); // right
window->paintBoxRel(borderwidth, height-20, width, borderwidth+20, COL_INFOBAR_SHADOW_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); // bottom
//window->paintBoxRel(0, 0, width, theight, (CFBWindow::color_t)COL_MENUHEAD_PLUS_0);
window->paintBoxRel(0, 0, width, theight, (CFBWindow::color_t)COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP);//round
if (!iconfile.empty())
{
int iw, ih;
CFrameBuffer::getInstance()->getIconSize(iconfile.c_str(), &iw, &ih);
//window->paintIcon(iconfile.c_str(), 8, 5);
window->paintIcon(iconfile.c_str(), 10, 0, theight);
//window->RenderString(g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE], iw+20, theight, width - 20-iw, g_Locale->getText(caption), COL_MENUHEAD_TEXT, 0, true); // UTF-8
window->RenderString(g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE], iw+20, theight, width - 20-iw, caption, COL_MENUHEAD_TEXT, 0, true); // UTF-8
}
else
window->RenderString(g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE], 10, theight, width - 10, caption, COL_MENUHEAD_TEXT, 0, true); // UTF-8
//window->paintBoxRel(0, theight, width, (entries_per_page + 1) * fheight, (CFBWindow::color_t)COL_MENUCONTENT_PLUS_0);
window->paintBoxRel(0, theight, width, (entries_per_page + 1) * fheight, (CFBWindow::color_t)COL_MENUCONTENT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM);//round
int count = entries_per_page;
int ypos = theight + (fheight >> 1);
for (std::vector::const_iterator it = line.begin() + (entries_per_page * current_page); ((it != line.end()) && (count > 0)); ++it, count--)
window->RenderString(g_Font[SNeutrinoSettings::FONT_TYPE_MENU], textStartX, (ypos += fheight), width, *it, COL_MENUCONTENT_TEXT, 0, true); // UTF-8
if (entries_per_page < line.size())
{
ypos = theight + (fheight >> 1);
window->paintBoxRel(width - 15, ypos , 15, entries_per_page * fheight, COL_MENUCONTENT_PLUS_1);
unsigned int marker_size = (entries_per_page * fheight) / ((line.size() + entries_per_page - 1) / entries_per_page);
window->paintBoxRel(width - 13, ypos + current_page * marker_size, 11, marker_size , COL_MENUCONTENT_PLUS_3);
}
}
bool CHintBox::has_scrollbar(void)
{
return (entries_per_page < line.size());
}
void CHintBox::scroll_up(void)
{
if (current_page > 0)
{
current_page--;
refresh();
}
}
void CHintBox::scroll_down(void)
{
if ((entries_per_page * (current_page + 1)) <= line.size())
{
current_page++;
refresh();
}
}
void CHintBox::hide(void)
{
if (window != NULL)
{
delete window;
window = NULL;
}
}
int ShowHint(const neutrino_locale_t Caption, const char * const Text, const int Width, int timeout, const char * const Icon)
{
const char * caption = g_Locale->getText(Caption);
return ShowHint(caption, Text, Width, timeout, Icon);
}
int ShowHint(const char * const Caption, const char * const Text, const int Width, int timeout, const char * const Icon)
{
neutrino_msg_t msg;
neutrino_msg_data_t data;
CHintBox * hintBox = new CHintBox(Caption, Text, Width, Icon);
hintBox->paint();
if ( timeout == -1 )
timeout = 5; /// default timeout 5 sec
//timeout = g_settings.timing[SNeutrinoSettings::TIMING_INFOBAR];
uint64_t timeoutEnd = CRCInput::calcTimeoutEnd( timeout );
int res = messages_return::none;
while ( ! ( res & ( messages_return::cancel_info | messages_return::cancel_all ) ) )
{
g_RCInput->getMsgAbsoluteTimeout( &msg, &data, &timeoutEnd );
if ((msg == CRCInput::RC_timeout) || (msg == CRCInput::RC_ok))
{
res = messages_return::cancel_info;
}
else if(msg == CRCInput::RC_home)
{
res = messages_return::cancel_all;
}
else if ((hintBox->has_scrollbar()) && ((msg == CRCInput::RC_up) || (msg == CRCInput::RC_down)))
{
if (msg == CRCInput::RC_up)
hintBox->scroll_up();
else
hintBox->scroll_down();
}
else if((msg == CRCInput::RC_sat) || (msg == CRCInput::RC_favorites)) {
}
else if(msg == CRCInput::RC_mode) {
res = messages_return::handled;
break;
}
else if((msg == CRCInput::RC_next) || (msg == CRCInput::RC_prev)) {
res = messages_return::cancel_all;
g_RCInput->postMsg(msg, data);
}
else
{
res = CNeutrinoApp::getInstance()->handleMsg(msg, data);
if (res & messages_return::unhandled)
{
// leave here and handle above...
g_RCInput->postMsg(msg, data);
res = messages_return::cancel_all;
}
}
}
hintBox->hide();
delete hintBox;
return res;
}
int ShowHint(const neutrino_locale_t Caption, const neutrino_locale_t Text, const int Width, int timeout, const char * const Icon)
{
return ShowHint(Caption, g_Locale->getText(Text),Width,timeout,Icon);
}
int ShowHint(const char * const Caption, const neutrino_locale_t Text, const int Width, int timeout, const char * const Icon)
{
return ShowHint(Caption, g_Locale->getText(Text),Width,timeout,Icon);
}