00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <cmath>
00024
00025
00026 #include <algorithm>
00027 using namespace std;
00028
00029
00030 #include <qapplication.h>
00031 #include <qpixmap.h>
00032 #include <qpainter.h>
00033 #include <qimage.h>
00034 #include <qcolor.h>
00035
00036
00037 #include "mythcontext.h"
00038 #include "mythdialogs.h"
00039 #include "osdlistbtntype.h"
00040
00041 #define LOC QString("OSDListTreeType: ")
00042 #define LOC_ERR QString("OSDListTreeType, Error: ")
00043
00044 OSDListTreeType::OSDListTreeType(
00045 const QString &name, const QRect &area,
00046 const QRect &levelsize, int levelspacing,
00047 float wmult, float hmult)
00048 : OSDType(name),
00049 treetop(NULL), currentpos(NULL),
00050 m_active(NULL), m_inactive(NULL),
00051 m_itemRegBeg(Qt::black), m_itemRegEnd(QColor(80,80,80)),
00052 m_itemSelBeg(QColor(82,202,56)), m_itemSelEnd(QColor(52,152,56)),
00053 m_itemRegAlpha(100), m_itemSelAlpha(255),
00054 m_spacing(0), m_margin(0),
00055 m_levelspacing(levelspacing),
00056 m_totalarea(area), m_levelsize(levelsize),
00057 m_unbiasedspacing(1.0f), m_unbiasedmargin(1.0f),
00058 m_unbiasedarea(0,0,0,0), m_unbiasedsize(0,0,0,0),
00059 m_wmult(wmult), m_hmult(hmult),
00060 m_depth(0), m_levelnum(-1),
00061 m_visible(true),
00062 m_arrowAccel(gContext->GetNumSetting("UseArrowAccels", 1))
00063 {
00064 m_wmult = (wmult == 0.0f) ? 1.0f : wmult;
00065 m_hmult = (hmult == 0.0f) ? 1.0f : hmult;
00066 m_unbiasedarea = unbias(area, wmult, hmult);
00067 m_unbiasedsize = unbias(levelsize, wmult, hmult);
00068 }
00069
00070 OSDListTreeType::~OSDListTreeType()
00071 {
00072 OSDListBtnList::iterator it = listLevels.begin();
00073 for (; it != listLevels.end(); ++it)
00074 delete *it;
00075 }
00076
00077 void OSDListTreeType::Reinit(float wmult, float hmult)
00078 {
00079 m_wmult = (wmult == 0.0f) ? 1.0f : wmult;
00080 m_hmult = (hmult == 0.0f) ? 1.0f : hmult;
00081 m_spacing = (uint) round(m_unbiasedspacing * wmult);
00082 m_margin = (uint) round(m_unbiasedmargin * wmult);
00083 m_totalarea = bias(m_unbiasedarea, wmult, hmult);
00084 m_levelsize = bias(m_unbiasedsize, wmult, hmult);
00085
00086 if (!treetop || m_levelnum < 0)
00087 return;
00088
00089
00090 vector<uint> list;
00091 for (uint i = 0; i <= (uint)m_levelnum; i++)
00092 list.push_back(listLevels[i]->GetItemCurrentPos());
00093
00094
00095 OSDListBtnList clone = listLevels;
00096 listLevels.clear();
00097 OSDListBtnList::iterator it = clone.begin();
00098 for (; it != clone.end(); ++it)
00099 delete *it;
00100
00101
00102 SetAsTree(treetop, &list);
00103 }
00104
00105 void OSDListTreeType::SetGroupCheckState(QString group, int newState)
00106 {
00107 OSDListBtnList::iterator it = listLevels.begin();
00108 for (; it != listLevels.end(); ++it)
00109 (*it)->SetGroupCheckState(group, newState);
00110 }
00111
00112 void OSDListTreeType::SetAsTree(OSDGenericTree *toplevel,
00113 vector<uint> *select_list)
00114 {
00115 if (treetop)
00116 {
00117 listLevels.clear();
00118 treetop = NULL;
00119 currentpos = NULL;
00120 m_depth = 0;
00121 m_levelnum = -1;
00122 }
00123
00124 m_depth = toplevel->calculateDepth(0) - 1;
00125 if (m_depth <= 0)
00126 {
00127 VERBOSE(VB_IMPORTANT, LOC_ERR + "SetAsTree: Need at least one level");
00128 return;
00129 }
00130
00131 currentpos = (OSDGenericTree*) toplevel->getChildAt(0);
00132 if (!currentpos)
00133 {
00134 VERBOSE(VB_IMPORTANT, LOC_ERR + "SetAsTree: Need top-level children");
00135 return;
00136 }
00137
00138
00139 for (uint i = 0; i < (uint)m_depth; i++)
00140 {
00141 QString levelname = QString("level%1").arg(i + 1);
00142 QRect curlevelarea = m_levelsize;
00143 curlevelarea.moveBy(m_totalarea.x(), m_totalarea.y());
00144 curlevelarea.moveBy((m_levelsize.width() + m_levelspacing) * i, 0);
00145
00146 OSDListBtnType *newlevel = new OSDListBtnType(
00147 levelname, curlevelarea, m_wmult, m_hmult, true);
00148
00149 newlevel->SetFontActive(m_active);
00150 newlevel->SetFontInactive(m_inactive);
00151 newlevel->SetItemRegColor(m_itemRegBeg, m_itemRegEnd, m_itemRegAlpha);
00152 newlevel->SetItemSelColor(m_itemSelBeg, m_itemSelEnd, m_itemSelAlpha);
00153 newlevel->SetSpacing(m_spacing);
00154 newlevel->SetMargin(m_margin);
00155
00156 listLevels.push_back(newlevel);
00157 }
00158
00159
00160 vector<uint> slist;
00161 slist.push_back(0);
00162 if (select_list)
00163 slist = *select_list;
00164
00165 currentpos = treetop = toplevel;
00166 for (m_levelnum = 0; m_levelnum < (int)slist.size(); m_levelnum++)
00167 {
00168 FillLevelFromTree(currentpos, m_levelnum);
00169 GetLevel(m_levelnum)->SetActive(true);
00170 GetLevel(m_levelnum)->SetVisible(true);
00171 if (slist[m_levelnum])
00172 GetLevel(m_levelnum)->SetItemCurrent(slist[m_levelnum]);
00173 EnterItem();
00174 }
00175 m_levelnum--;
00176 }
00177
00178 static bool has_action(QString action, const QStringList &actions)
00179 {
00180 QStringList::const_iterator it;
00181 for (it = actions.begin(); it != actions.end(); ++it)
00182 {
00183 if (action == *it)
00184 return true;
00185 }
00186 return false;
00187 }
00188
00189 bool OSDListTreeType::HandleKeypress(QKeyEvent *e)
00190 {
00191 QStringList actions;
00192 bool ok = gContext->GetMainWindow()->TranslateKeyPress(
00193 "TV Playback", e, actions);
00194
00195 if (!ok || ((uint)m_levelnum >= listLevels.size()))
00196 return false;
00197 else if (has_action("UP", actions))
00198 {
00199 GetLevel(m_levelnum)->MoveUp();
00200 EnterItem();
00201 }
00202 else if (has_action("DOWN", actions))
00203 {
00204 GetLevel(m_levelnum)->MoveDown();
00205 EnterItem();
00206 }
00207 else if (has_action("PAGEUP", actions))
00208 {
00209 GetLevel(m_levelnum)->MovePageUp();
00210 EnterItem();
00211 }
00212 else if (has_action("PAGEDOWN", actions))
00213 {
00214 GetLevel(m_levelnum)->MovePageDown();
00215 EnterItem();
00216 }
00217 else if (has_action("LEFT", actions) && (m_levelnum > 0))
00218 {
00219 GetLevel(m_levelnum)->Reset();
00220 GetLevel(m_levelnum)->SetVisible(false);
00221
00222 m_levelnum--;
00223 EnterItem();
00224 }
00225 else if ((has_action("LEFT", actions) && m_arrowAccel) ||
00226 has_action("ESCAPE", actions) ||
00227 has_action("CLEAROSD", actions) ||
00228 has_action("MENU", actions))
00229 {
00230 m_visible = false;
00231 }
00232 else if (has_action("RIGHT", actions) &&
00233 (m_levelnum + 1 < m_depth) &&
00234 (currentpos->childCount() > 0))
00235 {
00236 GetLevel(m_levelnum)->SetActive(false);
00237 m_levelnum++;
00238
00239 FillLevelFromTree(currentpos, m_levelnum);
00240 GetLevel(m_levelnum)->SetVisible(true);
00241 EnterItem();
00242 }
00243 else if ((has_action("RIGHT", actions) && m_arrowAccel) ||
00244 has_action("SELECT", actions))
00245 {
00246 SelectItem();
00247 }
00248 else
00249 {
00250 return false;
00251 }
00252
00253 return true;
00254 }
00255
00256 void OSDListTreeType::Draw(OSDSurface *surface, int fade, int maxfade,
00257 int xoff, int yoff)
00258 {
00259 OSDListBtnList::iterator it = listLevels.begin();
00260 for (; it != listLevels.end(); ++it)
00261 (*it)->Draw(surface, fade, maxfade, xoff, yoff);
00262 }
00263
00264 void OSDListTreeType::FillLevelFromTree(OSDGenericTree *item,
00265 uint level_num)
00266 {
00267 OSDListBtnType *list = GetLevel(level_num);
00268 if (!list)
00269 {
00270 VERBOSE(VB_IMPORTANT, LOC_ERR + "FillLevelFromTree() "
00271 "called with no list, ignoring.");
00272 return;
00273 }
00274 list->Reset();
00275
00276 QPtrList<GenericTree> *itemlist = item->getAllChildren();
00277 QPtrListIterator<GenericTree> it(*itemlist);
00278
00279 OSDGenericTree *child = (OSDGenericTree*) it.current();
00280 OSDListBtnTypeItem *newitem = NULL;
00281 for (;(child = (OSDGenericTree*) it.current()); ++it)
00282 {
00283 OSDTypeImage *im = child->getImage();
00284 QString label = child->getString();
00285 QString group = child->getGroup();
00286 bool canCheck = child->getCheckable() >= 0;
00287 bool hasCheck = child->getCheckable() == 1;
00288 bool hasChild = child->childCount() > 0;
00289
00290 newitem = new OSDListBtnTypeItem(list, label, im, canCheck, hasChild);
00291
00292 if (hasCheck)
00293 newitem->setChecked(OSDListBtnTypeItem::FullChecked);
00294 newitem->setGroup(group);
00295 newitem->setData(child);
00296
00297 child->setParentButton(newitem);
00298 }
00299 }
00300
00301 OSDListBtnType *OSDListTreeType::GetLevel(uint levelnum)
00302 {
00303 if (levelnum < listLevels.size())
00304 return listLevels[levelnum];
00305
00306 VERBOSE(VB_IMPORTANT, LOC_ERR + "GetLevel("<<levelnum<<") "
00307 "listLevels.size() is only "<<listLevels.size());
00308 return NULL;
00309 }
00310
00311 void OSDListTreeType::EnterItem(void)
00312 {
00313 if ((uint)m_levelnum >= listLevels.size())
00314 return;
00315
00316 listLevels[m_levelnum]->SetActive(true);
00317 OSDListBtnTypeItem *lbt = listLevels[m_levelnum]->GetItemCurrent();
00318 if (lbt)
00319 {
00320 currentpos = (OSDGenericTree*) (lbt->getData());
00321 emit itemEntered(this, currentpos);
00322 }
00323 }
00324
00325 void OSDListTreeType::SelectItem(void)
00326 {
00327 if (!currentpos)
00328 return;
00329
00330 SetGroupCheckState(currentpos->getGroup(), OSDListBtnTypeItem::NotChecked);
00331 currentpos->getParentButton()->setChecked(OSDListBtnTypeItem::FullChecked);
00332 emit itemSelected(this, currentpos);
00333 }
00334
00335 #undef LOC_ERR
00336 #undef LOC
00337
00339
00340 OSDListBtnType::OSDListBtnType(const QString &name, const QRect &area,
00341 float wmult, float hmult,
00342 bool showScrollArrows)
00343 : OSDType(name),
00344 m_order(0), m_rect(area),
00345 m_contentsRect(0,0,0,0), m_arrowsRect(0,0,0,0),
00346 m_wmult(wmult), m_hmult(hmult),
00347 m_itemHeight(0), m_itemSpacing(0),
00348 m_itemMargin(0), m_itemsVisible(0),
00349 m_active(false), m_showScrollArrows(showScrollArrows),
00350 m_showUpArrow(false), m_showDnArrow(false),
00351 m_initialized(false), m_clearing(false),
00352 m_visible(false),
00353 m_itemRegBeg(Qt::black), m_itemRegEnd(QColor(80,80,80)),
00354 m_itemSelBeg(QColor(82,202,56)), m_itemSelEnd(QColor(52,152,56)),
00355 m_itemRegAlpha(100), m_itemSelAlpha(255),
00356 m_fontActive(NULL), m_fontInactive(NULL),
00357 m_topIndx(0), m_selIndx(0),
00358 m_update(true)
00359 {
00360 }
00361
00362 OSDListBtnType::~OSDListBtnType()
00363 {
00364 Reset();
00365 }
00366
00367 void OSDListBtnType::SetGroupCheckState(QString group, int newState)
00368 {
00369 OSDListBtnItemList::iterator it;
00370 for (it = m_itemList.begin(); it != m_itemList.end(); ++it)
00371 if ((*it)->getGroup() == group)
00372 (*it)->setChecked((OSDListBtnTypeItem::CheckState) newState);
00373 }
00374
00375 void OSDListBtnType::Reset(void)
00376 {
00377 QMutexLocker lock(&m_update);
00378
00379 m_clearing = true;
00380 OSDListBtnItemList::iterator it;
00381 OSDListBtnItemList clone = m_itemList;
00382 m_itemList.clear();
00383 for (it = clone.begin(); it != clone.end(); ++it)
00384 delete (*it);
00385 m_clearing = false;
00386
00387 m_topIndx = 0;
00388 m_selIndx = 0;
00389 m_showUpArrow = false;
00390 m_showDnArrow = false;
00391 }
00392
00393 void OSDListBtnType::InsertItem(OSDListBtnTypeItem *item)
00394 {
00395 QMutexLocker lock(&m_update);
00396 m_itemList.push_back(item);
00397 m_showDnArrow = m_showScrollArrows && m_itemList.size() > m_itemsVisible;
00398 if (m_itemList.size() == 1)
00399 emit itemSelected(item);
00400 }
00401
00402 int find(const OSDListBtnItemList &list, const OSDListBtnTypeItem *item)
00403 {
00404 for (uint i = 0; i < list.size(); i++)
00405 if (list[i] == item)
00406 return i;
00407 return -1;
00408 }
00409
00410 void OSDListBtnType::RemoveItem(OSDListBtnTypeItem *item)
00411 {
00412 QMutexLocker lock(&m_update);
00413 if (m_clearing)
00414 return;
00415
00416 int i = find(m_itemList, item);
00417 if (i < 0)
00418 return;
00419
00420 m_itemList.erase(m_itemList.begin()+i);
00421
00422 m_showUpArrow = false;
00423 m_showDnArrow = m_itemList.size() > m_itemsVisible;
00424 m_selIndx = 0;
00425 m_topIndx = 0;
00426
00427 if (m_itemList.size())
00428 emit itemSelected(m_itemList[m_selIndx]);
00429 }
00430
00431 void OSDListBtnType::SetItemCurrent(const OSDListBtnTypeItem* item)
00432 {
00433 QMutexLocker lock(&m_update);
00434 int i = find(m_itemList, item);
00435 if (i >= 0)
00436 SetItemCurrent(i);
00437 }
00438
00439 void OSDListBtnType::SetItemCurrent(uint current)
00440 {
00441 QMutexLocker lock(&m_update);
00442 if (current >= m_itemList.size())
00443 return;
00444
00445 m_selIndx = current;
00446 m_topIndx = max(m_selIndx - (int)m_itemsVisible, 0);
00447 m_showUpArrow = m_topIndx;
00448 m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
00449 emit itemSelected(m_itemList[m_selIndx]);
00450 }
00451
00452 int OSDListBtnType::GetItemCurrentPos(void) const
00453 {
00454 QMutexLocker lock(&m_update);
00455 return (m_itemList.size()) ? m_selIndx : -1;
00456 }
00457
00458 OSDListBtnTypeItem* OSDListBtnType::GetItemCurrent(void)
00459 {
00460 QMutexLocker lock(&m_update);
00461 if (!m_itemList.size())
00462 return NULL;
00463 return m_itemList[m_selIndx];
00464 }
00465
00466 OSDListBtnTypeItem* OSDListBtnType::GetItemFirst(void)
00467 {
00468 QMutexLocker lock(&m_update);
00469 if (!m_itemList.size())
00470 return NULL;
00471 return m_itemList[0];
00472 }
00473
00474 OSDListBtnTypeItem* OSDListBtnType::GetItemNext(const OSDListBtnTypeItem *item)
00475 {
00476 QMutexLocker lock(&m_update);
00477 int i = find(m_itemList, item) + 1;
00478 if (i <= 0 || i >= (int)m_itemList.size())
00479 return NULL;
00480 return m_itemList[i];
00481 }
00482
00483 int OSDListBtnType::GetCount(void) const
00484 {
00485 QMutexLocker lock(&m_update);
00486 return m_itemList.size();
00487 }
00488
00489 OSDListBtnTypeItem* OSDListBtnType::GetItemAt(int pos)
00490 {
00491 QMutexLocker lock(&m_update);
00492 return m_itemList[pos];
00493 }
00494
00495 int OSDListBtnType::GetItemPos(const OSDListBtnTypeItem *item) const
00496 {
00497 QMutexLocker lock(&m_update);
00498 return find(m_itemList, item);
00499 }
00500
00501 void OSDListBtnType::MoveUp(void)
00502 {
00503 QMutexLocker lock(&m_update);
00504 if (!m_itemList.size())
00505 return;
00506
00507 if (--m_selIndx < 0)
00508 {
00509 m_selIndx = m_itemList.size() - 1;
00510 m_topIndx = (m_itemList.size() > m_itemsVisible) ?
00511 m_itemList.size() - m_itemsVisible : 0;
00512 }
00513
00514 m_topIndx = (m_selIndx < m_topIndx) ? m_selIndx : m_topIndx;
00515 m_showUpArrow = m_topIndx;
00516 m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
00517
00518 emit itemSelected(m_itemList[m_selIndx]);
00519 }
00520
00521 void OSDListBtnType::MoveDown(void)
00522 {
00523 QMutexLocker lock(&m_update);
00524 if (!m_itemList.size())
00525 return;
00526
00527 if (++m_selIndx >= (int)m_itemList.size())
00528 m_selIndx = m_topIndx = 0;
00529
00530 bool scroll_down = m_topIndx + (int)m_itemsVisible <= m_selIndx;
00531 m_topIndx = (scroll_down) ? m_topIndx + 1 : m_topIndx;
00532
00533 m_showUpArrow = m_topIndx;
00534 m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
00535
00536 emit itemSelected(m_itemList[m_selIndx]);
00537 }
00538
00539 void OSDListBtnType::MovePageUp(void)
00540 {
00541 QMutexLocker lock(&m_update);
00542 if (!m_itemList.size())
00543 return;
00544
00545 if (m_itemsVisible > m_itemList.size())
00546 return;
00547
00548 m_selIndx = m_topIndx = m_topIndx - m_itemsVisible;
00549
00550 if (m_selIndx < 0)
00551 {
00552 int top = (int)(m_itemsVisible *
00553 ceil((float)m_itemList.size()/(float)m_itemsVisible));
00554 m_selIndx = m_topIndx = top - m_itemsVisible;
00555 }
00556
00557 m_showUpArrow = m_topIndx;
00558 m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
00559
00560 emit itemSelected(m_itemList[m_selIndx]);
00561 }
00562
00563 void OSDListBtnType::MovePageDown(void)
00564 {
00565 QMutexLocker lock(&m_update);
00566 if (!m_itemList.size())
00567 return;
00568
00569 if (m_itemsVisible > m_itemList.size())
00570 return;
00571
00572 m_selIndx = m_topIndx+m_itemsVisible;
00573
00574 if (m_selIndx >= (int)m_itemList.size())
00575 m_selIndx = m_topIndx = 0;
00576
00577 bool scroll_down = m_topIndx + (int)m_itemsVisible <= m_selIndx;
00578 m_topIndx = (scroll_down) ? m_topIndx + m_itemsVisible : m_topIndx;
00579
00580 m_showUpArrow = m_topIndx;
00581 m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
00582
00583 emit itemSelected(m_itemList[m_selIndx]);
00584 }
00585
00586 void OSDListBtnType::Draw(OSDSurface *surface,
00587 int fade, int maxfade,
00588 int xoff, int yoff)
00589 {
00590 QMutexLocker lock(&m_update);
00591 if (!m_visible)
00592 return;
00593 if (!m_initialized)
00594 Init();
00595
00596 TTFFont *font = m_active ? m_fontActive : m_fontInactive;
00597
00598 int y = m_rect.y();
00599 for (uint i = m_topIndx; i < m_itemList.size(); i++)
00600 {
00601 if (!((y - m_rect.y()) <= (m_contentsRect.height() - m_itemHeight)))
00602 break;
00603 m_itemList[i]->paint(surface, font, fade, maxfade,
00604 m_rect.x() + xoff, y + yoff);
00605 y += m_itemHeight + m_itemSpacing;
00606 }
00607
00608 if (m_showScrollArrows)
00609 {
00610 if (m_showUpArrow)
00611 m_upArrowActPix.Draw(surface, fade, maxfade,
00612 m_rect.x() + m_arrowsRect.x() + xoff,
00613 m_rect.y() + m_arrowsRect.y() + yoff);
00614 else
00615 m_upArrowRegPix.Draw(surface, fade, maxfade,
00616 m_rect.x() + m_arrowsRect.x() + xoff,
00617 m_rect.y() + m_arrowsRect.y() + yoff);
00618 if (m_showDnArrow)
00619 m_dnArrowActPix.Draw(surface, fade, maxfade,
00620 m_rect.x() + m_arrowsRect.x() +
00621 m_upArrowRegPix.width() + m_itemMargin + xoff,
00622 m_rect.y() + m_arrowsRect.y() + yoff);
00623 else
00624 m_dnArrowRegPix.Draw(surface, fade, maxfade,
00625 m_rect.x() + m_arrowsRect.x() +
00626 m_upArrowRegPix.width() + m_itemMargin + xoff,
00627 m_rect.y() + m_arrowsRect.y() + yoff);
00628 }
00629 }
00630
00631 void OSDListBtnType::Init(void)
00632 {
00633 int sz1 = m_fontActive->Size() * 3 / 2;
00634 int sz2 = m_fontInactive->Size() * 3 / 2;
00635 m_itemHeight = max(sz1, sz2) + (int)(2 * m_itemMargin);
00636 m_itemHeight = m_itemHeight & ~0x1;
00637
00638 if (m_showScrollArrows)
00639 {
00640 LoadPixmap(m_upArrowRegPix, "uparrow-reg");
00641 LoadPixmap(m_upArrowActPix, "uparrow-sel");
00642 LoadPixmap(m_dnArrowRegPix, "dnarrow-reg");
00643 LoadPixmap(m_dnArrowActPix, "dnarrow-sel");
00644
00645 m_arrowsRect = QRect(0, m_rect.height() - m_upArrowActPix.height() - 1,
00646 m_rect.width(), m_upArrowActPix.height());
00647 }
00648 else
00649 m_arrowsRect = QRect(0, 0, 0, 0);
00650
00651 m_contentsRect = QRect(0, 0, m_rect.width(), m_rect.height() -
00652 m_arrowsRect.height() - 2 * m_itemMargin);
00653
00654 m_itemsVisible = 0;
00655 int y = 0;
00656 while (y <= m_contentsRect.height() - m_itemHeight)
00657 {
00658 y += m_itemHeight + m_itemSpacing;
00659 m_itemsVisible++;
00660 }
00661
00662 LoadPixmap(m_checkNonePix, "check-empty");
00663 LoadPixmap(m_checkHalfPix, "check-half");
00664 LoadPixmap(m_checkFullPix, "check-full");
00665 LoadPixmap(m_arrowPix, "arrow");
00666
00667 uint itemWidth = (m_rect.width() + 1) & (~1);
00668
00669 InitItem(m_itemRegPix, itemWidth, m_itemHeight,
00670 m_itemRegBeg, m_itemRegEnd, m_itemRegAlpha);
00671 InitItem(m_itemSelInactPix, itemWidth, m_itemHeight,
00672 m_itemSelBeg, m_itemSelEnd, m_itemRegAlpha);
00673 InitItem(m_itemSelActPix, itemWidth, m_itemHeight,
00674 m_itemSelBeg, m_itemSelEnd, 255);
00675
00676 m_showDnArrow = m_itemList.size() > m_itemsVisible && m_showScrollArrows;
00677 m_initialized = true;
00678 }
00679
00680 void OSDListBtnType::InitItem(
00681 OSDTypeImage &osdImg, uint width, uint height,
00682 QColor beg, QColor end, int alpha)
00683 {
00684 float rstep = ((float) (end.red() - beg.red())) / m_itemHeight;
00685 float gstep = ((float) (end.green() - beg.green())) / m_itemHeight;
00686 float bstep = ((float) (end.blue() - beg.blue())) / m_itemHeight;
00687
00688 unsigned char *data = new unsigned char[4 * width * height];
00689 uint32_t *ptr = (uint32_t*) data;
00690
00691 uint black = qRgba(0,0,0,alpha);
00692 for (uint x = 0; x < width; x++, ptr++)
00693 *ptr = black;
00694 for (uint y = 1; y < height - 1; y++)
00695 {
00696 int r = (int) (beg.red() + (y * rstep));
00697 int g = (int) (beg.green() + (y * gstep));
00698 int b = (int) (beg.blue() + (y * bstep));
00699 uint32_t color = qRgba(r,g,b,alpha);
00700 *ptr = black; ptr++;
00701 for (uint x = 1; x < width - 1; x++, ptr++)
00702 *ptr = color;
00703 *ptr = black; ptr++;
00704 }
00705 for (uint x = 0; x < width; x++, ptr++)
00706 *ptr = black;
00707
00708 {
00709 QImage img(data, width, height, 32, NULL, 65536 * 65536,
00710 QImage::LittleEndian);
00711 img.setAlphaBuffer(alpha<255);
00712 osdImg.Load(img);
00713 }
00714 delete[] data;
00715 }
00716
00717 void OSDListBtnType::LoadPixmap(OSDTypeImage& pix, const QString& fileName)
00718 {
00719 QString path = gContext->GetThemesParentDir() + "default/lb-";
00720 pix.Load(path + fileName + ".png", m_wmult, m_hmult);
00721 }
00722
00724 OSDListBtnTypeItem::OSDListBtnTypeItem(
00725 OSDListBtnType *lbtype, const QString &text,
00726 OSDTypeImage *pixmap, bool checkable,
00727 bool showArrow, CheckState state)
00728 : m_parent(lbtype), m_pixmap(pixmap),
00729 m_data(NULL), m_text(text),
00730 m_group(QString::null), m_state(state),
00731 m_showArrow(showArrow), m_checkable(checkable),
00732 m_checkRect(0,0,0,0), m_arrowRect(0,0,0,0),
00733 m_pixmapRect(0,0,0,0), m_textRect(0,0,0,0)
00734 {
00735 if (!m_parent->m_initialized)
00736 m_parent->Init();
00737
00738 OSDTypeImage &checkPix = m_parent->m_checkNonePix;
00739 OSDTypeImage &arrowPix = m_parent->m_arrowPix;
00740
00741 int margin = m_parent->m_itemMargin;
00742 int width = m_parent->m_rect.width();
00743 int height = m_parent->m_itemHeight;
00744 int cw = checkPix.ImageSize().width();
00745 int ch = checkPix.ImageSize().height();
00746 int aw = arrowPix.ImageSize().width();
00747 int ah = arrowPix.ImageSize().height();
00748 int pw = m_pixmap ? m_pixmap->ImageSize().width() : 0;
00749 int ph = m_pixmap ? m_pixmap->ImageSize().height() : 0;
00750
00751 if (m_checkable)
00752 m_checkRect = QRect(margin, (height - ch)/2, cw, ch);
00753
00754 if (m_showArrow)
00755 m_arrowRect = QRect(width - aw - margin, (height - ah)/2, aw, ah);
00756
00757 if (m_pixmap)
00758 {
00759 int tmp = (m_checkable) ? (2 * margin + m_checkRect.width()) : margin;
00760 m_pixmapRect = QRect(tmp, (height - ph)/2, pw, ph);
00761 }
00762
00763 int tx = margin, tw = width - (2 * margin);
00764 tx += (m_checkable) ? m_checkRect.width() + margin : 0;
00765 tx += (m_pixmap) ? m_pixmapRect.width() + margin : 0;
00766 tw -= (m_checkable) ? m_checkRect.width() + margin : 0;
00767 tw -= (m_showArrow) ? m_arrowRect.width() + margin : 0;
00768 tw -= (m_pixmap) ? m_pixmapRect.width() + margin : 0;
00769 m_textRect = QRect(tx, 0, tw, height);
00770
00771 m_parent->InsertItem(this);
00772 }
00773
00774 OSDListBtnTypeItem::~OSDListBtnTypeItem()
00775 {
00776 if (m_parent)
00777 m_parent->RemoveItem(this);
00778 }
00779
00780 void OSDListBtnTypeItem::paint(OSDSurface *surface, TTFFont *font,
00781 int fade, int maxfade, int x, int y)
00782 {
00783 if (this == m_parent->GetItemCurrent())
00784 {
00785 if (m_parent->m_active)
00786 m_parent->m_itemSelActPix.Draw(surface, fade, maxfade, x, y);
00787 else
00788 m_parent->m_itemSelInactPix.Draw(surface, fade, maxfade, x, y);
00789
00790 if (m_showArrow)
00791 {
00792 QRect ar(m_arrowRect);
00793 ar.moveBy(x, y);
00794 m_parent->m_arrowPix.Draw(surface, fade, maxfade, ar.x(), ar.y());
00795 }
00796 }
00797 else
00798 {
00799 if (m_parent->m_active)
00800 m_parent->m_itemRegPix.Draw(surface, fade, maxfade, x, y);
00801 else
00802 m_parent->m_itemRegPix.Draw(surface, fade, maxfade, x, y);
00803 }
00804
00805 if (m_checkable)
00806 {
00807 QRect cr(m_checkRect);
00808 cr.moveBy(x, y);
00809
00810 if (m_state == HalfChecked)
00811 m_parent->m_checkHalfPix.Draw(surface, fade, maxfade,
00812 cr.x(), cr.y());
00813 else if (m_state == FullChecked)
00814 m_parent->m_checkFullPix.Draw(surface, fade, maxfade,
00815 cr.x(), cr.y());
00816 else
00817 m_parent->m_checkNonePix.Draw(surface, fade, maxfade,
00818 cr.x(), cr.y());
00819 }
00820
00821 if (m_pixmap)
00822 {
00823 QRect pr(m_pixmapRect);
00824 pr.moveBy(x, y);
00825 m_pixmap->Draw(surface, fade, maxfade, pr.x(), pr.y());
00826 }
00827
00828 QRect tr(m_textRect);
00829 tr.moveBy(x, y);
00830 tr.moveBy(0, font->Size() / 4);
00831 font->DrawString(surface, tr.x(), tr.y(), m_text, tr.right(), tr.bottom());
00832 }