/************************************************************************* * sbControl.cpp - items on screen * * author: Konstantin Maslyuk "Kalemas" mailto:kalemas@mail.ru * * 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 version 2. * * 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. ************************************************************************/ #include "sbCore.h" #include "sbControl.h" #pragma warning(disable : 4018) sbRect layout (int scheme, int num, int start, int end = 0) { const int themeSize = Theme->size; sbRect rect; if (scheme == 1) // bottom bar { if (end > 0) { rect.left = Core->getRect().right*start/num; rect.top = Core->getRect().bottom-Theme->PanelSize; rect.right = Core->getRect().right*end/num; rect.bottom = Core->getRect().bottom; } else { rect.left = Core->getRect().right*(start-1)/num; rect.top = Core->getRect().bottom-Theme->PanelSize; rect.right = Core->getRect().right*start/num; rect.bottom = Core->getRect().bottom; } } else if (scheme == 2) // can switch { rect.left = Core->getRect().right*(start-1)/num; rect.top = Core->getRect().bottom-(themeSize*40/100); rect.right = Core->getRect().right*start/num; rect.bottom = Core->getRect().bottom-(themeSize*20/100); } else if (scheme == 0) // screen matrix { int rows, columns, pv, ph, sep=themeSize/((num+2)*4), indent=max(themeSize*8/100,sep*4/3); columns = (int)sqrt((float)num+2); rows = (int)ceil(num/(float)columns); pv = start%columns == 0 ? columns : start%columns; ph = ((start-pv)/columns)+1; rect.left = indent+((Core->getRect().right-(indent*2)+sep)*(pv-1)/columns); rect.top = (themeSize*10/100)+indent+((Core->getRect().bottom-(themeSize*30/100)-(indent*2)+sep)*(ph-1)/rows); rect.right = indent+((Core->getRect().right-(indent*2)+sep)*pv/columns)-sep; rect.bottom = (themeSize*10/100)+indent+((Core->getRect().bottom-(themeSize*30/100)-(indent*2)+sep)*ph/rows)-sep; int w = rect.width(); int h = rect.height(); if ( h > w ) { rect.top = rect.top + ((h-w)/2); rect.bottom = rect.top + w; } } else sbAssert ( true ); return rect; } sbControl::sbControl ( TYPE _type_ ) : type ( _type_ ) , text ( L"" ) { const int themeSize = Theme->size; //const sbRect * screenRect = & Core->getSurface( sbCore::SURFACE::TYPE_WHOLE )->rect; switch (type) { // navigation case TYPE_OPEN_BOOK_SELECTION: rect = layout(1,16,0,6); setText(L"Book"); break; case TYPE_OPEN_SEARCH: rect = layout(1,16,6,11); setText(L"Search"); break; case TYPE_CLOSE: rect = layout(1,16,11,16); setText(L"Back"); break; case TYPE_OPEN_SEARCH_2: rect = layout(1,16,0,6); setText(L"Search"); break; case TYPE_OPEN_MODULE_SELECTION: rect = layout(1,16,6,11); setText(L"Module"); break; // list case TYPE_OPEN_NAVIGATION_LIST: rect = layout(1,16,0,5); setText(L"Goto"); break; case TYPE_OPEN_OPTIONS: rect = layout(1,16,5,11); setText(L"Options"); break; case TYPE_OPEN_HOME: rect = layout(1,16,11,16); setText(L"Home"); break; // home case TYPE_OPEN_NAVIGATION: rect = layout(1,16,0,6); setText(L"Goto"); break; case TYPE_OPEN_HISTORY: rect = layout(1,16,6,11); setText(L"History"); break; case TYPE_EXIT: rect = layout(1,16,11,16); setText(L"Exit"); break; // module installer disclaimer case TYPE_INSTALLER_DISCLAIMER_ACCEPT : rect = layout(1,2,0,1); setText(L"Accept"); break; case TYPE_INSTALLER_DISCLAIMER_DECLINE : rect = layout(1,2,1,2); setText(L"Decline"); break; // other case TYPE_WIDE_MODULES: rect = layout(1,1,1); setText(L"Close"); break; case TYPE_WIDE_CLOSE: rect = layout(1,1,1); setText(L"Close"); break; case TYPE_MODE_ADD_STAR: rect = layout(1,4,2); setText(L"*"); break; case TYPE_OPEN_TEXT: rect = layout(1,4,2); setText(L"H"); break; case TYPE_CAN_SWITCH_LEFT: rect = layout(2,12,1); setText(L"<"); break; case TYPE_CAN_SWITCH_RIGHT: rect = layout(2,12,12); setText(L">"); break; case TYPE_BUTTON_OPEN_FILE: rect = layout(1,4,1); setText(L""); break; case TYPE_OPEN_BOOKMARKS: rect = layout(1,4,2); setText(L"B"); break; case TYPE_OPEN_READINGS: rect = layout(1,4,3); setText(L"R"); break; case TYPE_MENU_EXIT: { rect = Core->getRect(); childrens.push_back(new sbControl (sbControl::TYPE_MENU_EXIT_YES, layout(0,2,1), L"Yes")); childrens.push_back(new sbControl (sbControl::TYPE_MENU_EXIT_NO, layout(0,2,2), L"No")); setText(L"Exit?"); } break; case TYPE_MENU_VERSE: { rect = Core->getRect(); // get verse state childrens.push_back(new sbControl (sbControl::TYPE_MENU_VERSE_ADD_DYNAMIC_BOOKMARK, layout(0,4,1), L"DB")); childrens.push_back(new sbControl (sbControl::TYPE_MENU_VERSE_ADD_STATIC_BOOKMARK, layout(0,4,2), L"SB")); childrens.push_back(new sbControl (sbControl::TYPE_MENU_VERSE_REMOVE_BOOKMARK, layout(0,4,3), L"-B")); childrens.push_back(new sbControl (sbControl::TYPE_MENU_VERSE_START_EDITING, layout(0,4,4), L"Edit")); childrens.push_back(new sbControl (sbControl::TYPE_MENU_CANCEL, layout(1,1,1), L"Cancel")); setText(L"Verse"); } break; default: if (type >= TYPE_MENU_SET_VERSE && type < TYPE_MENU_SET_VERSE_MAX) { int count = type - TYPE_MENU_SET_VERSE; static int max = 0; if ( max == 0 ) max = atoi((*Core->getOptions())["Ui"].getWithDefault( "MaxVerses" , "50" )); int step = count / max + 1; count = count / step; rect = Core->getRect(); for ( int i = 1; i <= count; i++ ) { TCHAR* text = new TCHAR [5]; text = _itot ( i*step , text , 10 ); childrens.push_back( new sbControl ((TYPE)(TYPE_SET_VERSE+(i*step)), layout(0,count+1,i), text)); } childrens.push_back( new sbControl (sbControl::TYPE_MENU_CANCEL, layout(1,1,1), L"Cancel")); setText ( L"Select Verse:" ); } else sbAssert(true); break; } } sbControl::sbControl ( TYPE _type_ , const sbRect _rect_ , const TCHAR* _text_ ) : type ( _type_ ) , rect ( _rect_ ) { setText ( _text_ ); } sbControl::~sbControl() { // some menus own children text if (type >= TYPE_MENU_SET_VERSE && type < TYPE_MENU_SET_VERSE_MAX) { for (int i=0; i < childrens.size(); i++) if (childrens[i]->type != TYPE_MENU_CANCEL) delete [] childrens[i]->text; } for (int i = 0; i < childrens.size(); i++) delete childrens[i]; } void sbControl::onPaint ( sbSurface hdc ) const { sbFont font = sbSelectFont(hdc, Theme->styles[style].font); switch (type) { case TYPE_OPEN_BOOK_SELECTION: case TYPE_OPEN_MODULE_SELECTION: case TYPE_CLOSE: case TYPE_OPEN_NAVIGATION_LIST: case TYPE_OPEN_OPTIONS: case TYPE_OPEN_HOME: case TYPE_OPEN_NAVIGATION: case TYPE_OPEN_HISTORY: case TYPE_EXIT: case TYPE_WIDE_CLOSE: case TYPE_WIDE_MODULES: case TYPE_MENU_CANCEL: case TYPE_INSTALLER_DISCLAIMER_ACCEPT: case TYPE_INSTALLER_DISCLAIMER_DECLINE: case TYPE_OPEN_SEARCH: case TYPE_OPEN_SEARCH_2: { Theme->drawElement(hdc, &rect, sbTheme::ELEMENT::PANEL); sbSelectColor(hdc, Theme->fadeColor(Theme->elements[sbTheme::ELEMENT::PANEL].textColor,textPos.x,textPos.y)); sbDrawText(hdc, textPos.x, textPos.y, text, _tcslen(text)); } break; case TYPE_CAN_SWITCH_LEFT: case TYPE_CAN_SWITCH_RIGHT: { sbSelectColor ( hdc, Theme->fadeColor(Theme->ItemSubTextColor,textPos.x,textPos.y)); sbDrawText ( hdc, textPos.x, textPos.y, text, _tcslen(text)); } break; default: if (isMenu()) { sbAssert(Theme->fadeSurface != true); Theme->fadeSurface = false; for (int i=0; i < childrens.size(); i++) childrens[i]->onPaint( hdc ); sbSelectColor(hdc, Theme->ItemMenuTextColor); sbDrawText(hdc, textPos.x, textPos.y, text, _tcslen(text)); Theme->fadeSurface = true; } else { Theme->drawElement(hdc, &rect, sbTheme::ELEMENT::MENU); sbSelectColor(hdc, Theme->fadeColor(Theme->elements[sbTheme::ELEMENT::MENU].textColor,textPos.x,textPos.y)); sbDrawText(hdc, textPos.x, textPos.y, text, _tcslen(text)); } } sbSelectFont(hdc, font); } void sbControl::onPressed() { switch (type) { case TYPE_OPEN_HOME: Core->switchList(sbList::TYPE_HOME); break; case TYPE_OPEN_TEXT: Core->switchList(sbList::TYPE_MODULE_VIEW); break; case TYPE_OPEN_NAVIGATION: case TYPE_OPEN_NAVIGATION_LIST: case TYPE_OPEN_BOOK_SELECTION: Core->switchList(sbList::TYPE_SELECT_BOOK); break; case TYPE_OPEN_MODULE_SELECTION: Core->switchList(sbList::TYPE_SELECT_MODULE); break; case TYPE_OPEN_HISTORY: Core->switchList(sbList::TYPE_HISTORY); break; case TYPE_OPEN_BOOKMARKS: Core->switchList(sbList::TYPE_BOOKMARKS); break; case TYPE_OPEN_READINGS: Core->switchList(sbList::TYPE_READINGS); break; case TYPE_MENU_EXIT_YES: sbExit(1); break; case TYPE_WIDE_MODULES: Core->switchList(sbList::TYPE_MODULE_VIEW); break; case TYPE_WIDE_CLOSE: Core->switchList(sbList::TYPE_HOME); break; case TYPE_CLOSE: Core->switchList(sbList::TYPE_MODULE_VIEW); break; case TYPE_OPEN_OPTIONS: Core->switchList(sbList::TYPE_MENU_OPTIONS); break; case TYPE_OPEN_SEARCH_2: case TYPE_OPEN_SEARCH: Core->switchList(sbList::TYPE_SEARCH); break; case TYPE_CAN_SWITCH_LEFT: case TYPE_CAN_SWITCH_RIGHT: break; case TYPE_INSTALLER_DISCLAIMER_ACCEPT: Core->getInstallMgr()->setUserDisclaimerConfirmed(true); Core->switchList(sbList::TYPE_MODULE_INSTALLER); break; case TYPE_INSTALLER_DISCLAIMER_DECLINE: Core->switchList(sbList::TYPE_SELECT_MODULE); break; //case TYPE_EXIT: // if (sbQueryBox(L"Do you want exit?")) sbExit(1); // break; default: { if (isMenu()) { for (int i=0; i < childrens.size(); i++) { if (childrens[i]->hit(Core->getInput()->last.x, Core->getInput()->last.y)) { childrens[i]->onPressed(); break; } if (i == childrens.size()-1) Core->controlPressed(type); } } else { Core->controlPressed(type); } } } } void sbControl::setText ( const TCHAR * _text_ ) { sbPoint sz; text = (TCHAR*)_text_; if ( text[0] == 0 ) return; const int h = (rect.height())/2; if (h < Theme->styles[sbTheme::STYLE::BUTTON_SMALL].size) style = sbTheme::STYLE::BUTTON_SMALL; //else if (h < Theme->styles[sbTheme::STYLE::TEXT].size) // style = sbTheme::STYLE::TEXT; else if (h < Theme->styles[sbTheme::STYLE::BUTTON].size) style = sbTheme::STYLE::BUTTON; else style = sbTheme::STYLE::CAPTION; //SelectObject ( hdc, Theme->styles[style].font ); sz = sbGetTextExtent ( Theme->styles[style].font, text, _tcslen(text) ); textPos.x = (rect.width() - sz.x) / 2 + rect.left; textPos.y = (rect.height() - sz.y) / 2 + rect.top; if ( isMenu() ) { int bottom = rect.bottom; for (int i=0; irect.top,bottom); textPos.y = rect.top+((bottom-rect.top-sz.y)/2); } }