/* Based up Neutrino-GUI - Tuxbox-Project Copyright (C) 2001 by Steffen Hehn 'McClean Hintbox based up initial code by Copyright (C) 2003 Ralf Gandy 'thegoodguy' Copyright (C) 2004 Sven Traenkle 'zwen' Copyright (C) 2008-2009, 2011, 2013 Stefan Seyfried Implementation of CComponent Window class. Copyright (C) 2014-2016 Thilo Graf 'dbt' 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 "hintbox.h" #include /* x w y+-ccw_head----------------------------------------------+ |icon | caption | buttons |header (ccw_head) +-ccw_body----------------------------------------------+ |+-obj_content-----------------------------------------+| ||+-obj_hint 0----------------------------------------+||body (ccw_body) h||| obj_picon | obj_text ||| | ||+---------------------------------------------------+|| +-contents (obj_content) |+-----------------------------------------------------+| | +-------------------------------------------------------+ +-hint 0 (obj_hint) default added with new instance of CHintBox | | +-hint n optional added with addHintItem() */ using namespace std; CHintBox::CHintBox( const neutrino_locale_t Caption, const char * const Text, const int Width, const char * const Icon, const char * const Picon, const int& header_buttons, const int& text_mode, const int& indent): CComponentsWindow( 1, 1, width, HINTBOX_MIN_HEIGHT, Caption, string(Icon == NULL ? "" : Icon), NULL, CC_SHADOW_ON) { init(Text, Width, string(Picon == NULL ? "" : Picon), header_buttons, text_mode, indent); } CHintBox::CHintBox( const char * const Caption, const char * const Text, const int Width, const char * const Icon, const char * const Picon, const int& header_buttons, const int& text_mode, const int& indent):CComponentsWindow( 1, 1, width, HINTBOX_MIN_HEIGHT, Caption, string(Icon == NULL ? "" : Icon), NULL, CC_SHADOW_ON) { init(string(Text), Width, string(Picon == NULL ? "" : Picon), header_buttons, text_mode, indent); } CHintBox::CHintBox( const neutrino_locale_t Caption, const neutrino_locale_t Text, const int Width, const char * const Icon, const char * const Picon, const int& header_buttons, const int& text_mode, const int& indent):CComponentsWindow( 1, 1, width, HINTBOX_MIN_HEIGHT, Caption, string(Icon == NULL ? "" : Icon), NULL, CC_SHADOW_ON) { init(g_Locale->getText(Text), Width, string(Picon == NULL ? "" : Picon), header_buttons, text_mode, indent); } CHintBox::CHintBox( const char * const Caption, const neutrino_locale_t Text, const int Width, const char * const Icon, const char * const Picon, const int& header_buttons, const int& text_mode, const int& indent):CComponentsWindow( 1, 1, width, HINTBOX_MIN_HEIGHT, Caption, string(Icon == NULL ? "" : Icon), NULL, CC_SHADOW_ON) { init(g_Locale->getText(Text), Width, string(Picon == NULL ? "" : Picon), header_buttons, text_mode, indent); } void CHintBox::init(const std::string& Text, const int& Width, const std::string& Picon, const int& header_buttons, const int& text_mode, const int& indent) { timeout = HINTBOX_DEFAULT_TIMEOUT; w_indentation = indent; hb_font = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]; //set required window width and basic height width = getMaxWidth(Text, hb_font, Width); height = max(HINTBOX_MIN_HEIGHT, min(HINTBOX_MAX_HEIGHT, height)); ccw_buttons = header_buttons; //enable shadow shadow = true; //disable disable header if no title has been defined if (ccw_caption.empty()) showHeader(false); //disable footer for default showFooter(false); y_hint_obj = CC_CENTERED; //initialize timeout bar and its timer timeout_pb = NULL; timeout_pb_timer= NULL; if (!Text.empty()) addHintItem(Text, text_mode, Picon, COL_MENUCONTENT_TEXT, hb_font); } CHintBox::~CHintBox() { disableTimeOutBar(); } void CHintBox::enableTimeOutBar(bool enable) { if(!enable){ if(timeout_pb_timer){ delete timeout_pb_timer; timeout_pb_timer = NULL; } if(timeout_pb){ delete timeout_pb; timeout_pb = NULL; } return; } if(timeout_pb){ timeout_pb->paint0(); timeout_pb->setValues(timeout_pb->getValue()+1, 100*timeout); }else{ timeout_pb = new CProgressBar(); timeout_pb->setDimensionsAll(ccw_body->getRealXPos(), ccw_body->getRealYPos(), ccw_body->getWidth(), TIMEOUT_BAR_HEIGHT); timeout_pb->setValues(0, 100*timeout); if (!timeout_pb_timer) timeout_pb_timer = new CComponentsTimer(1, true); timeout_pb_timer->OnTimer.connect(sigc::mem_fun0(this, &CHintBox::showTimeOutBar)); timeout_pb_timer->startTimer(); } } int CHintBox::exec() { neutrino_msg_t msg; neutrino_msg_data_t data; int res = messages_return::none; uint64_t timeoutEnd = CRCInput::calcTimeoutEnd( timeout ); if (timeout > 0) enableTimeOutBar(); 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 ((msg == CRCInput::RC_up) || (msg == CRCInput::RC_down)) { if (msg == CRCInput::RC_up) this->scroll_up(); else this->scroll_down(); } else if (CNeutrinoApp::getInstance()->listModeKey(msg)){ // do nothing //TODO: if passed rc messages are ignored rc messaages: has no effect here too!! } 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; } } } disableTimeOutBar(); return res; } void CHintBox::addHintItem(const std::string& Text, const int& text_mode, const std::string& Picon, const fb_pixel_t& color_text, Font* font_text) { /* set required font and line height */ Font* item_font = !font_text ? hb_font : font_text; /* pre define required info height depends of lines and minimal needed height*/ int line_breaks = CTextBox::getLines(Text); int h_font = item_font->getHeight(); int h_lines = h_font * line_breaks; /* get required height depends of possible lines and max height */ h_hint_obj = min(HINTBOX_MAX_HEIGHT - (ccw_head ? ccw_head->getHeight() : 0), h_lines + 2*w_indentation); /* add scroll mode if needed */ int txt_mode = text_mode; if (h_lines > h_hint_obj){ txt_mode = text_mode | CTextBox::SCROLL; ccw_buttons = ccw_buttons | CComponentsHeader::CC_BTN_TOP | CComponentsHeader::CC_BTN_DOWN; } /* define y start position of infobox inside body */ if(!ccw_body->empty()){ ccw_body->front()->setYPos(w_indentation); y_hint_obj += ccw_body->back()->getYPos()+ ccw_body->back()->getHeight(); } /* calcoulation of maximal hintbox height include possible header*/ height = min(HINTBOX_MAX_HEIGHT, (ccw_head ? ccw_head->getHeight() : 0)+ h_hint_obj); height = max(height, HINTBOX_MIN_HEIGHT); /* get current maximal width and refresh window items TODO: required maximal width*/ width = getMaxWidth(Text, item_font, width); /* initialize infobox as container for text and possible picon*/ CComponentsInfoBox *info_box = new CComponentsInfoBox( 0, y_hint_obj, width, // FIXME: not critical here but ccw_body->getWidth() != width, this should be the same value! h_hint_obj, Text, txt_mode, item_font, ccw_body, CC_SHADOW_OFF, color_text); /* define picon and disable bg */ info_box->setPicture(Picon); info_box->doPaintBg(false); /* recalculate new hintbox height */ ReSize(); /* set hint box position general to center and refresh window */ setCenterPos(); Refresh(); } void CHintBox::setMsgText(const std::string& Text, const uint& hint_id, const int& mode, Font* font_text, const fb_pixel_t& color_text, const int& style) { uint id = hint_id; if (hint_id+1 > ccw_body->size()){ id = 0; dprintf(DEBUG_NORMAL, "[CHintBox] [%s - %d] mismatching hint_id [%u]...\n", __func__, __LINE__, id); } CComponentsInfoBox *obj_text = static_cast(ccw_body->getCCItem(id)); //set required font and line size Font* font = font_text == NULL ? g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO] : font_text; if (obj_text) obj_text->setText(Text, mode, font, color_text, style); } void CHintBox::ReSize() { int h = (ccw_head ? ccw_head->getHeight() : 0); for (size_t i= 0; i< ccw_body->size(); i++){ CComponentsItem *item = ccw_body->getCCItem(i); h += item->getHeight(); } height = min(HINTBOX_MAX_HEIGHT, max(HINTBOX_MIN_HEIGHT, max(height,h))); Refresh(); } void CHintBox::Scroll(bool down, const uint& hint_id) { uint id = hint_id; if (hint_id+1 > ccw_body->size()){ id = 0; dprintf(DEBUG_NORMAL, "[CHintBox] [%s - %d] mismatching hint_id [%u]...\n", __func__, __LINE__, id); } CComponentsInfoBox *obj_text = static_cast(ccw_body->getCCItem(id)); if (obj_text) { dprintf(DEBUG_DEBUG, "[CHintBox] [%s - %d] try to scroll %s hint_id [%u]...Text= %s\n", __func__, __LINE__, down ? "down" : "up", id, obj_text->getText().c_str()); CTextBox* textbox = obj_text->cctext->getCTextBoxObject(); if (textbox) { textbox->enableBackgroundPaint(true); if (down) textbox->scrollPageDown(1); else textbox->scrollPageUp(1); textbox->enableBackgroundPaint(false); } } } void CHintBox::scroll_up(const uint& hint_id) { Scroll(false, hint_id); } void CHintBox::scroll_down(const uint& hint_id) { Scroll(true, hint_id); } int CHintBox::getMaxWidth(const string& Text, Font *font, const int& minWidth) { return max(HINTBOX_MIN_WIDTH, max(minWidth+w_indentation, min(font->getRenderWidth(Text)+w_indentation, (int)frameBuffer->getScreenWidth()))); } int ShowHint(const char * const Caption, const char * const Text, const int Width, int timeout, const char * const Icon, const char * const Picon, const int& header_buttons) { int res = messages_return::none; CHintBox hintBox(Caption, Text, Width, Icon, Picon, header_buttons); hintBox.setTimeOut(timeout); hintBox.paint(); res = hintBox.exec(); hintBox.hide(); return res; } int ShowHint(const neutrino_locale_t Caption, const char * const Text, const int Width, int timeout, const char * const Icon, const char * const Picon, const int& header_buttons) { const char * caption = g_Locale->getText(Caption); return ShowHint(caption, Text, Width, timeout, Icon, Picon, header_buttons); } int ShowHint(const neutrino_locale_t Caption, const neutrino_locale_t Text, const int Width, int timeout, const char * const Icon, const char * const Picon, const int& header_buttons) { return ShowHint(Caption, g_Locale->getText(Text),Width,timeout,Icon, Picon, header_buttons); } int ShowHint(const char * const Caption, const neutrino_locale_t Text, const int Width, int timeout, const char * const Icon, const char * const Picon, const int& header_buttons) { return ShowHint(Caption, g_Locale->getText(Text),Width,timeout, Icon, Picon, header_buttons); } CHint::CHint(const char * const Text, bool show_background) : CHintBox("" , Text) { paint_bg = show_background; ccw_show_header = false; ccw_show_footer = false; } CHint::CHint(const neutrino_locale_t Text, bool show_background) : CHintBox("" , g_Locale->getText(Text)) { paint_bg = show_background; ccw_show_header = false; ccw_show_footer = false; } int ShowHintS(const char * const Text, int timeout, bool show_background) { int res = messages_return::none; CHint hint(Text, show_background); hint.setTimeOut(timeout); hint.paint(); res = hint.exec(); hint.hide(); return res; } int ShowHintS(const neutrino_locale_t Text, int timeout, bool show_background) { return ShowHintS(g_Locale->getText(Text), timeout, show_background); }