25 #define YUILogComponent "mga-ncurses"
26 #include <yui/YUILog.h>
27 #include <yui/mga/YMGAMenuBar.h>
29 #include <yui/YTypes.h>
30 #include <yui/YShortcut.h>
31 #include <yui/ncurses/NCurses.h>
32 #include "YMGANCMenuBar.h"
33 #include "NCMGAPopupMenu.h"
34 #include <yui/ncurses/YNCursesUI.h>
35 #include <yui/mga/YMGAMenuItem.h>
36 #include <yui/ncurses/NCLabel.h>
48 std::vector<struct __MBItem*> items;
50 unsigned nextSerialNo;
59 YMGAMenuItem * mi =
dynamic_cast<YMGAMenuItem *
>(i->item);
61 if (mi->enabled() && !mi->hidden())
68 for (uint i=0; i < items.size(); i++)
70 if (items[i]->item == selected->item)
76 if (i+1 < items.size())
78 YMGAMenuItem * mi =
dynamic_cast<YMGAMenuItem *
>(items[i+1]->item);
80 if (mi->enabled() && !mi->hidden())
95 YMGAMenuItem * mi =
dynamic_cast<YMGAMenuItem *
>(i->item);
97 if (mi->enabled() && !mi->hidden())
104 for (uint i=items.size()-1; i >0 ; i--)
106 if (items[i]->item == selected->item)
112 YMGAMenuItem * mi =
dynamic_cast<YMGAMenuItem *
>(items[i-1]->item);
114 if (mi->enabled() && !mi->hidden())
123 YMGANCMenuBar::YMGANCMenuBar( YWidget * parent )
124 : YMGAMenuBar( parent )
134 yuiDebug() << std::endl;
138 YMGANCMenuBar::~YMGANCMenuBar()
146 yuiDebug() << std::endl;
150 int YMGANCMenuBar::preferredWidth()
152 return wGetDefsze().W;
156 int YMGANCMenuBar::preferredHeight()
158 return wGetDefsze().H;
163 void YMGANCMenuBar::setSize(
int newwidth,
int newheight )
165 wRelocate( wpos( 0 ), wsze( newheight, newwidth ) );
170 yuiDebug() << key << std::endl;
172 if ( key < 0 || UCHAR_MAX < key )
175 for (YItemIterator it=itemsBegin(); it!=itemsEnd(); it++)
177 NClabel label = NCstring((*it)->label());
179 yuiDebug() << label << std::endl;
180 if (label.hasHotkey() && (tolower( key ) == tolower(label.hotkey())))
187 NCursesEvent YMGANCMenuBar::wHandleHotkey( wint_t key )
189 yuiDebug() << key << std::endl;
190 NCursesEvent ret = NCursesEvent::none;
194 if ( (tolower(i->hotkey)) == tolower(key))
202 YMGAMenuItem *item =
dynamic_cast<YMGAMenuItem *
>(sel->item);
204 if (!item->enabled())
205 return NCursesEvent::none;
214 NCursesEvent YMGANCMenuBar::wHandleInput( wint_t key )
216 yuiDebug() <<
"wHandleInput " << key << std::endl;
217 NCursesEvent ret = NCursesEvent::none;
219 if (itemsBegin() != itemsEnd())
224 d->selected = d->getPrevious();
228 d->selected = d->getNext();
246 if (itemsBegin() == itemsEnd())
249 YMGAMenuBar::addItem(item);
253 d->items.push_back(it);
255 NClabel label( NCstring( item->label() ));
258 unsigned int h = defsze.H > 0 ? defsze.H : 0;
259 defsze = wsze( h < label.height() ? label.height() : h,
260 defsze.W + label.width()+5 );
261 yuiDebug() <<
"label: " << label <<
" defsze: " << defsze << std::endl;
263 item->setIndex( ++(d->nextSerialNo) );
265 if ( item->hasChildren() )
266 assignUniqueIndex( item->childrenBegin(), item->childrenEnd() );
271 YSelectionWidget::addItems(itemCollection);
277 void YMGANCMenuBar::wRedraw()
282 if (itemsBegin() == itemsEnd())
289 for ( YItemConstIterator it = itemsBegin() ; it != itemsEnd(); ++it )
304 const NCstyle::StWidget & style( widgetStyle(d->selected != sel) );
306 NClabel label( NCstring( (*it)->label() ));
308 YMGAMenuItem * mi =
dynamic_cast<YMGAMenuItem *
>(*it);
309 bool disabled =
false;
315 yuiDebug() << mi->label() <<
" hidden" << std::endl;
318 else if (!mi->enabled())
322 yuiDebug() << mi->label() <<
" disabled" << std::endl;
323 win->bkgdset(wStyle().disabledList.item.plain);
327 win->bkgdset( style.plain );
331 win->printw( 0, col,
"[" );
332 sel->pos = wpos( 0, col+1 );
333 sel->hotkey = label.hotkey();
335 yuiDebug() << sel->item->label() <<
" pos: " << sel->pos <<
" hotkey: " << sel->hotkey <<
" defsize: " << defsze << std::endl;
338 label.drawAt( *win, wStyle().disabled, sel->pos, wsze( -1, label.width() + 3 ), NC::CENTER );
340 label.drawAt( *win, style, sel->pos, wsze( -1, label.width() + 3 ), NC::CENTER );
341 col = col + label.width() + 4;
342 win->printw( 0, col,
"]" );
344 haveUtf8() ? win->add_wch( 0, col - 1, WACS_DARROW )
345 : win->addch( 0, col - 1, ACS_DARROW );
347 if (col < win->width())
350 win->bkgdset( style.plain );
356 win->vline(
' ', win->maxx() - col +1);
357 win->vline( 0, win->maxx() - 1, win->height(),
' ' );
358 if ( h > 1 )win->vline( 0, win->maxx() - 1, win->height(),
' ' );
360 win->box( wrect( 0, win->size() - wsze( 0, 1 ) ) );
366 NCursesEvent YMGANCMenuBar::postMenu()
369 return NCursesEvent::none;
371 YMGAMenuItem *item =
dynamic_cast<YMGAMenuItem *
>(d->selected->item);
373 if (!item->enabled())
374 return NCursesEvent::none;
377 wpos at( ScreenPos() + wpos( 1, d->selected->pos.C ) );
378 yuiWarning() <<
" position " << ScreenPos() <<
" menu position " << at <<std::endl;
382 YUI_CHECK_NEW( dialog );
384 int selection = dialog->post();
388 YDialog::deleteTopmostDialog();
389 return NCursesEvent::none;
392 NCursesEvent ret = NCursesEvent::menu;
393 ret.selection = findMenuItem( selection );
394 yuiMilestone() <<
"selection " << selection <<
" " << (ret.selection ? ret.selection->label() :
"---") << std::endl;
397 YDialog::deleteTopmostDialog();
398 return NCursesEvent::none;
401 yuiMilestone() << dialog->isTopmostDialog() << std::endl;
403 YDialog::deleteTopmostDialog();
411 YMenuItem * YMGANCMenuBar::findMenuItem(
int index )
413 return findMenuItem( index, itemsBegin(), itemsEnd() );
417 YMenuItem * YMGANCMenuBar::findMenuItem(
int wantedIndex, YItemConstIterator begin, YItemConstIterator end )
419 for ( YItemConstIterator it = begin; it != end; ++it )
421 YMenuItem * item =
dynamic_cast<YMenuItem *
> (*it);
425 if ( item->index() == wantedIndex )
428 if ( item->hasChildren() )
430 YMenuItem * result = findMenuItem( wantedIndex, item->childrenBegin(), item->childrenEnd() );
441 void YMGANCMenuBar::setEnabled(
bool do_bv )
443 NCWidget::setEnabled( do_bv );
449 void YMGANCMenuBar::assignUniqueIndex( YItemIterator begin, YItemIterator end )
451 for ( YItemIterator it = begin; it != end; ++it )
455 item->setIndex( ++(d->nextSerialNo) );
457 if ( item->hasChildren() )
458 assignUniqueIndex( item->childrenBegin(), item->childrenEnd() );
465 YMGAMenuBar::enableItem(menu_item, enable);
470 YMGAMenuBar::hideItem(menu_item, invisible);
481 YSelectionWidget::deleteAllItems();
487 static void resolveShortcutsConflictFlat(YItemConstIterator begin, YItemConstIterator end)
489 bool used[
sizeof( char ) << 8 ];
490 for (
unsigned i=0; i <
sizeof( char ) << 8; i++ )
492 std::vector<YMenuItem*> conflicts;
494 for ( YItemConstIterator it = begin; it != end; ++it )
496 YMenuItem * item =
dynamic_cast<YMenuItem *
> (*it);
500 if ( item->hasChildren() )
502 resolveShortcutsConflictFlat(item->childrenBegin(), item->childrenEnd() );
505 char shortcut = YShortcut::normalized(YShortcut::findShortcut(item->label()));
509 conflicts.push_back(item);
510 yuiMilestone() <<
"No or invalid shortcut found " << item->label() << endl;
512 else if (used[(
unsigned)shortcut])
514 conflicts.push_back(item);
515 yuiWarning() <<
"Conflicting shortcut found " << item->label() << endl;
519 used[(unsigned)shortcut] =
true;
524 yuiWarning() <<
"non menu item used in call " << (*it)->label() << endl;
529 for(YMenuItem *i: conflicts)
531 std::string clean = YShortcut::cleanShortcutString(i->label());
535 for (; index < clean.size(); ++index)
537 char ch = YShortcut::normalized(clean[index]);
539 if (ch != 0 && !used[(
unsigned)ch])
542 used[(unsigned)ch] =
true;
549 clean.insert(index, 1, YShortcut::shortcutMarker());
550 yuiMilestone() <<
"New label used: " << clean << endl;