diff --git a/ChangeLog b/ChangeLog index a1714ee7..a537fadc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2015-11-01 Markus Gans + * First working version of an application menu, + it uses the new classes FMenuBar, FMenu and FMenuItem + (alpha state) + 2015-10-29 Markus Gans * Support for the menu key diff --git a/doc/TODO b/doc/TODO index 0b47365f..5f3ed342 100644 --- a/doc/TODO +++ b/doc/TODO @@ -4,6 +4,7 @@ Bugs Improvements ~~~~~~~~~~~~ +- Stabilize the application menu classes (FMenuBar, FMenu, FMenuItem) - If t_exit_underline_mode == "\E[24m" -> implement t_exit_bold_mode with "\E[21m" -> implement t_exit_reverse_mode with "\E[27m" @@ -15,11 +16,6 @@ Improvements Missing Features ~~~~~~~~~~~~~~~~ -- application menu - - FMenuBar() - - FMenu() - - FMenuItem() - - list/tree view with Columns - FListView() --------------------------------------- diff --git a/src/fapp.cpp b/src/fapp.cpp index b7293ec3..afbb47ed 100644 --- a/src/fapp.cpp +++ b/src/fapp.cpp @@ -347,8 +347,11 @@ void FApplication::processKeyboardEvent() } else { + // send key down event FKeyEvent k_down_ev (KeyDown_Event, key); sendEvent (widget, &k_down_ev); + + // send key press event FKeyEvent k_press_ev (KeyPress_Event, key); sendEvent (widget, &k_press_ev); @@ -384,6 +387,7 @@ void FApplication::processKeyboardEvent() } fifo_offset = int(strlen(fifo_buf)); } + // send key up event FKeyEvent k_up_ev (KeyUp_Event, key); sendEvent (widget, &k_up_ev); key = 0; diff --git a/src/fmenu.cpp b/src/fmenu.cpp index 8946d49f..d00de056 100644 --- a/src/fmenu.cpp +++ b/src/fmenu.cpp @@ -3,7 +3,6 @@ #include "fapp.h" #include "fmenu.h" -#include "fmessagebox.h" // <----- remove later #include "fstatusbar.h" //---------------------------------------------------------------------- @@ -113,7 +112,16 @@ void FMenu::init(FWidget* parent) item->setMenu(this); if ( parent ) + { + if ( isMenuBar(parent) ) + { + FMenuBar* mb = dynamic_cast(parent); + if ( mb ) + mb->menu_dimension(); + } setSuperMenu(parent); + } + menu_dimension(); } //---------------------------------------------------------------------- @@ -123,7 +131,7 @@ void FMenu::menu_dimension() std::vector::const_iterator iter, end; iter = itemlist.begin(); end = itemlist.end(); - maxItemWidth = 0; + maxItemWidth = 10; // find the max item width while ( iter != end ) @@ -451,7 +459,6 @@ void FMenu::drawItems() uInt txt_length; int hotkeypos, to_char; bool is_enabled = (*iter)->isEnabled(); - bool has_focus = (*iter)->hasFocus(); bool is_selected = (*iter)->isSelected(); bool is_noUnderline = (((*iter)->getFlags() & NO_UNDERLINE) != 0); bool is_separator = (*iter)->isSeparator(); @@ -475,12 +482,16 @@ void FMenu::drawItems() { foregroundColor = wc.menu_active_fg; backgroundColor = wc.menu_active_bg; + if ( isMonochron() ) + setReverse(true); } } else { foregroundColor = wc.menu_inactive_fg; backgroundColor = wc.menu_inactive_bg; + if ( isMonochron() ) + setReverse(true); } gotoxy (xpos+xmin, ypos+ymin+y); setColor (foregroundColor, backgroundColor); @@ -494,8 +505,17 @@ void FMenu::drawItems() to_char = int(txt_length); hotkeypos = getHotkeyPos (src, dest, txt_length); - if ( hotkeypos != -1 ) + if ( hotkeypos == -1 ) { + if ( is_selected ) + setCursorPos ( xpos+xmin+1 + , ypos+ymin+y ); // first character + } + else + { + if ( is_selected ) + setCursorPos ( xpos+xmin+1+hotkeypos + , ypos+ymin+y ); // hotkey txt_length--; to_char--; } @@ -534,7 +554,7 @@ void FMenu::drawItems() setReverse(true); delete[] item_text; } - if ( has_focus && statusBar() ) + /*if ( is_selected && statusBar() ) { FString msg = (*iter)->getStatusbarMessage(); FString curMsg = statusBar()->getMessage(); @@ -543,10 +563,12 @@ void FMenu::drawItems() statusBar()->setMessage(msg); statusBar()->drawMessage(); } - } + }*/ ++iter; y++; } + if ( hasFocus() ) + setCursor(); } //---------------------------------------------------------------------- @@ -554,10 +576,14 @@ inline void FMenu::drawSeparator(int y) { gotoxy (xpos+xmin-1, ypos+ymin+y); setColor (wc.menu_active_fg, wc.menu_active_bg); + if ( isMonochron() ) + setReverse(true); print(fc::BoxDrawingsVerticalAndRight); FString line(width-2, wchar_t(fc::BoxDrawingsHorizontal)); print (line); print(fc::BoxDrawingsVerticalAndLeft); + if ( isMonochron() ) + setReverse(false); } //---------------------------------------------------------------------- @@ -571,6 +597,40 @@ void FMenu::processActivate() //---------------------------------------------------------------------- void FMenu::onKeyPress (FKeyEvent* ev) { + // looking for a hotkey + std::vector::const_iterator iter, end; + iter = itemlist.begin(); + end = itemlist.end(); + + while ( iter != end ) + { + if ( (*iter)->hasHotkey() ) + { + bool found = false; + int hotkey = (*iter)->getHotkey(); + int key = ev->key(); + + if ( isalpha(hotkey) || isdigit(hotkey) ) + { + if ( tolower(hotkey) == key || toupper(hotkey) == key ) + found = true; + } + else if ( hotkey == key ) + found = true; + + if ( found ) + { + unselectItemInList(); + hide(); + hideSuperMenus(); + ev->accept(); + (*iter)->processClicked(); + return; + } + } + ++iter; + } + switch ( ev->key() ) { case fc::Fkey_return: @@ -597,7 +657,7 @@ void FMenu::onKeyPress (FKeyEvent* ev) break; case fc::Fkey_left: - if ( selectedListItem->hasMenu() ) + if ( hasSelectedListItem() && selectedListItem->hasMenu() ) { FMenu* sub_menu = selectedListItem->getMenu(); if ( sub_menu->isVisible() ) @@ -611,7 +671,7 @@ void FMenu::onKeyPress (FKeyEvent* ev) break; case fc::Fkey_right: - if ( selectedListItem->hasMenu() ) + if ( hasSelectedListItem() && selectedListItem->hasMenu() ) { FMenu* sub_menu = selectedListItem->getMenu(); if ( ! sub_menu->isVisible() ) @@ -790,16 +850,14 @@ void FMenu::onMouseMove (FMouseEvent* ev) y = (*iter)->getY(); mouse_x = mouse_pos.getX(); mouse_y = mouse_pos.getY(); -/* -FMessageBox::info (this, "Info", FString().sprintf("local(%d,%d) global(%d,%d)\n" - "iter x1=%d, x2=%d, y=%d" - , ev->getX(),ev->getY(),ev->getGlobalX(), ev->getGlobalY() - , x1, x2, y) );*/ + if ( mouse_x >= x1 && mouse_x <= x2 && mouse_y == y ) { - if ( (*iter)->isEnabled() && ! (*iter)->isSelected() ) + if ( (*iter)->isEnabled() + && ! (*iter)->isSelected() + && ! (*iter)->isSeparator() ) { FWidget* focused_widget = getFocusWidget(); FFocusEvent out (FocusOut_Event); @@ -829,6 +887,20 @@ FMessageBox::info (this, "Info", FString().sprintf("local(%d,%d) global(%d,%d)\n ++iter; } + // Mouse is over border or separator + if ( ! selectedListItem && statusBar() + && getGeometryGlobal().contains(ev->getGlobalPos()) ) + { + FString msg = getStatusbarMessage(); + FString curMsg = statusBar()->getMessage(); + if ( curMsg != msg ) + { + statusBar()->setMessage(msg); + statusBar()->drawMessage(); + } + } + + // Mouse event handover to the menu bar FWidget* menubar = getSuperMenu(); if ( menubar && isMenuBar(menubar) @@ -897,17 +969,37 @@ void FMenu::setGeometry (int xx, int yy, int ww, int hh, bool adjust) resizeArea (vwin); } +//---------------------------------------------------------------------- +void FMenu::setStatusbarMessage(FString msg) +{ + FWidget::setStatusbarMessage(msg); + if ( item ) + item->setStatusbarMessage(msg); +} + //---------------------------------------------------------------------- void FMenu::selectFirstItemInList() { + std::vector::const_iterator iter, end; + iter = itemlist.begin(); + end = itemlist.end(); + if ( itemlist.empty() ) return; - if ( ! hasSelectedListItem() ) + if ( hasSelectedListItem() ) + unselectItemInList(); + + while ( iter != end ) { - // select the first item - itemlist[0]->setSelected(); - selectedListItem = itemlist[0]; + if ( (*iter)->isEnabled() && ! (*iter)->isSeparator() ) + { + // select first enabled item + (*iter)->setSelected(); + selectedListItem = *iter; + break; + } + ++iter; } } diff --git a/src/fmenu.h b/src/fmenu.h index 497fae64..4db2d0b4 100644 --- a/src/fmenu.h +++ b/src/fmenu.h @@ -94,6 +94,7 @@ class FMenu : public FWindow, public FMenuList // make every setGeometry from FWidget available using FWidget::setGeometry; void setGeometry (int, int, int, int, bool = true); + void setStatusbarMessage (FString); FMenuItem* getItem() const; FString getText() const; bool setEnable(bool); diff --git a/src/fmenubar.cpp b/src/fmenubar.cpp index 78bf9719..4d8b01a8 100644 --- a/src/fmenubar.cpp +++ b/src/fmenubar.cpp @@ -3,6 +3,7 @@ #include "fapp.h" #include "fmenubar.h" +#include "fstatusbar.h" //---------------------------------------------------------------------- // class FMenuBar @@ -87,6 +88,109 @@ bool FMenuBar::isMenu (FMenuItem* mi) const return mi->hasMenu(); } +//---------------------------------------------------------------------- +bool FMenuBar::selectNextItem() +{ + std::vector::const_iterator iter, end; + iter = itemlist.begin(); + end = itemlist.end(); + + while ( iter != end ) + { + if ( (*iter)->isSelected() ) + { + FMenuItem* next; + std::vector::const_iterator next_element; + + next_element = iter; + do + { + ++next_element; + if ( next_element == itemlist.end() ) + next_element = itemlist.begin(); + next = static_cast(*next_element); + } while ( ! next->isEnabled() + || ! next->acceptFocus() + || ! next->isVisible() + || next->isSeparator() ); + if ( next == *iter ) + return false; + unselectItemInMenu(); + next->setSelected(); + next->setFocus(); + if ( next->hasMenu() ) + { + FMenuItem* first_item; + FMenu* menu = next->getMenu(); + menu->selectFirstItemInList(); + first_item = menu->getSelectedListItem(); + if ( first_item ) + first_item->setFocus(); + menu->redraw(); + } + if ( statusBar() ) + statusBar()->drawMessage(); + selectedMenuItem = next; + redraw(); + break; + } + ++iter; + } + return true; +} + +//---------------------------------------------------------------------- +bool FMenuBar::selectPrevItem() +{ + std::vector::const_iterator iter, begin; + iter = itemlist.end(); + begin = itemlist.begin(); + + do + { + --iter; + if ( (*iter)->isSelected() ) + { + FMenuItem* prev; + std::vector::const_iterator prev_element; + + prev_element = iter; + do + { + if ( prev_element == itemlist.begin() ) + prev_element = itemlist.end(); + --prev_element; + prev = static_cast(*prev_element); + } while ( ! prev->isEnabled() + || ! prev->acceptFocus() + || ! prev->isVisible() + || prev->isSeparator() ); + if ( prev == *iter ) + return false; + unselectItemInMenu(); + prev->setSelected(); + prev->setFocus(); + if ( prev->hasMenu() ) + { + FMenuItem* first_item; + FMenu* menu = prev->getMenu(); + menu->selectFirstItemInList(); + first_item = menu->getSelectedListItem(); + if ( first_item ) + first_item->setFocus(); + menu->redraw(); + } + if ( statusBar() ) + statusBar()->drawMessage(); + selectedMenuItem = prev; + redraw(); + break; + } + } while ( iter != begin ); + + return true; +} + //---------------------------------------------------------------------- int FMenuBar::getHotkeyPos (wchar_t*& src, wchar_t*& dest, uInt length) { @@ -147,16 +251,17 @@ void FMenuBar::drawItems() wchar_t* item_text; FString txt; uInt txt_length; - int hotkeypos, to_char; - bool is_Active, is_Selected, is_NoUnderline; + int hotkeypos, startpos, to_char; + bool is_active, is_selected, is_noUnderline; - is_Active = (*iter)->isEnabled(); - is_Selected = (*iter)->isSelected(); - is_NoUnderline = (((*iter)->getFlags() & NO_UNDERLINE) != 0); + startpos = x + 1; + is_active = (*iter)->isEnabled(); + is_selected = (*iter)->isSelected(); + is_noUnderline = (((*iter)->getFlags() & NO_UNDERLINE) != 0); - if ( is_Active ) + if ( is_active ) { - if ( is_Selected ) + if ( is_selected ) { if ( isMonochron() ) setReverse(false); @@ -175,8 +280,12 @@ void FMenuBar::drawItems() backgroundColor = wc.menu_inactive_bg; } setColor (foregroundColor, backgroundColor); - x++; - print (vmenubar, ' '); + + if ( x < screenWidth ) + { + x++; + print (vmenubar, ' '); + } txt = (*iter)->getText(); txt_length = uInt(txt.getLength()); @@ -196,10 +305,13 @@ void FMenuBar::drawItems() txt_length--; to_char--; } + x += int(txt_length); for (int z=0; z < to_char; z++) { + if ( startpos > screenWidth-z ) + break; if ( ! iswprint(wint_t(item_text[z])) ) { if ( ! isNewFont() && ( int(item_text[z]) < fc::NF_rev_left_arrow2 @@ -208,13 +320,13 @@ void FMenuBar::drawItems() item_text[z] = L' '; } } - if ( (z == hotkeypos) && is_Active && ! is_Selected ) + if ( (z == hotkeypos) && is_active && ! is_selected ) { setColor (wc.menu_hotkey_fg, wc.menu_hotkey_bg); - if ( ! is_NoUnderline ) + if ( ! is_noUnderline ) setUnderline(); print (vmenubar, item_text[z]); - if ( ! is_NoUnderline ) + if ( ! is_noUnderline ) unsetUnderline(); setColor (foregroundColor, backgroundColor); } @@ -222,19 +334,28 @@ void FMenuBar::drawItems() print (vmenubar, item_text[z]); } - if ( x > screenWidth ) + if ( x > screenWidth+1 ) { - print (vmenubar, txt.left(uInt(int(txt_length)+screenWidth-x-1))); - print (vmenubar, ".."); + if ( startpos < screenWidth ) + { + gotoxy(screenWidth-1,1); + print (vmenubar, ".."); + } + else if ( startpos-2 < screenWidth ) + { + gotoxy(screenWidth,1); + print (vmenubar, ' '); + } } - else + + if ( x < screenWidth ) { x++; print (vmenubar, ' '); } setColor (wc.menu_active_fg, wc.menu_active_bg); - if ( isMonochron() && is_Active && is_Selected ) + if ( isMonochron() && is_active && is_selected ) setReverse(true); delete[] item_text; @@ -248,6 +369,17 @@ void FMenuBar::drawItems() setReverse(false); setUpdateVTerm(true); +/* + if ( hasSelectedMenuItem() && statusBar() ) + { + FString msg = getSelectedMenuItem()->getStatusbarMessage(); + FString curMsg = statusBar()->getMessage(); + if ( curMsg != msg ) + { + statusBar()->setMessage(msg); + statusBar()->drawMessage(); + } + }*/ } //---------------------------------------------------------------------- @@ -267,13 +399,34 @@ void FMenuBar::onKeyPress (FKeyEvent* ev) { switch ( ev->key() ) { + case fc::Fkey_return: + case fc::Fkey_enter: + if ( hasSelectedMenuItem() ) + { + FMenuItem* sel_menu = getSelectedMenuItem(); + if ( ! sel_menu->hasMenu() ) + { + sel_menu->unsetSelected(); + selectedMenuItem = 0; + redraw(); + sel_menu->processClicked(); + } + } + ev->accept(); + break; + + case fc::Fkey_up: // avoid focusNextChild() or focusPrevChild() + case fc::Fkey_down: + ev->accept(); + break; + case fc::Fkey_left: - beep(); + selectPrevItem(); ev->accept(); break; case fc::Fkey_right: - beep(); + selectNextItem(); ev->accept(); break; @@ -288,22 +441,11 @@ void FMenuBar::onMouseDown (FMouseEvent* ev) if ( ev->getButton() != LeftButton ) { mouse_down = false; - if ( ! itemlist.empty() ) { - std::vector::const_iterator iter, end; - iter = itemlist.begin(); - end = itemlist.end(); - - while ( iter != end ) - { - (*iter)->unsetSelected(); - if ( selectedMenuItem == *iter ) - selectedMenuItem = 0; - ++iter; - } + unselectItemInMenu(); + redraw(); } - redraw(); return; } @@ -340,10 +482,17 @@ void FMenuBar::onMouseDown (FMouseEvent* ev) { if ( (*iter)->isEnabled() && ! (*iter)->isSelected() ) { + FWidget* focused_widget = getFocusWidget(); + FFocusEvent out (FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); (*iter)->setSelected(); +//FMessageBox::info (this, "Info", (*iter)->getStatusbarMessage()); (*iter)->setFocus(); +//FMessageBox::info (this, "Info", statusBar()->getMessage()); selectedMenuItem = *iter; focus_changed = true; + if ( focused_widget ) + focused_widget->redraw(); } if ( (*iter)->hasMenu() ) { @@ -351,9 +500,12 @@ void FMenuBar::onMouseDown (FMouseEvent* ev) if ( menu->hasSelectedListItem() ) { menu->unselectItemInList(); + (*iter)->setFocus(); menu->redraw(); + focus_changed = true; } } + } else { @@ -369,6 +521,8 @@ void FMenuBar::onMouseDown (FMouseEvent* ev) } ++iter; } + if ( statusBar() ) + statusBar()->drawMessage(); if ( focus_changed ) redraw(); } @@ -411,9 +565,15 @@ void FMenuBar::onMouseUp (FMouseEvent* ev) FMenu* menu = (*iter)->getMenu(); if ( ! menu->hasSelectedListItem() ) { + FMenuItem* first_item; menu->selectFirstItemInList(); - menu->getSelectedListItem()->setFocus(); + first_item = menu->getSelectedListItem(); + if ( first_item ) + first_item->setFocus(); menu->redraw(); + if ( statusBar() ) + statusBar()->drawMessage(); + redraw(); } } else @@ -464,20 +624,28 @@ void FMenuBar::onMouseMove (FMouseEvent* ev) { if ( (*iter)->isEnabled() && ! (*iter)->isSelected() ) { + FWidget* focused_widget = getFocusWidget(); + FFocusEvent out (FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); (*iter)->setSelected(); (*iter)->setFocus(); selectedMenuItem = *iter; focus_changed = true; + if ( focused_widget ) + focused_widget->redraw(); + + if ( (*iter)->hasMenu() ) + { + FMenu* menu = (*iter)->getMenu(); + if ( menu->hasSelectedListItem() ) + { + menu->unselectItemInList(); + menu->redraw(); + } + } } - if ( (*iter)->hasMenu() ) - { - FMenu* menu = (*iter)->getMenu(); - if ( menu->hasSelectedListItem() ) - { - menu->unselectItemInList(); - menu->redraw(); - } - } + else if ( statusBar() ) + statusBar()->clearMessage(); } else { @@ -492,6 +660,7 @@ void FMenuBar::onMouseMove (FMouseEvent* ev) } else if ( hasSelectedMenuItem() && selectedMenuItem->hasMenu() ) { + // Mouse event handover to the menu FMenu* menu = selectedMenuItem->getMenu(); const FRect& menu_geometry = menu->getGeometryGlobal(); @@ -508,6 +677,8 @@ void FMenuBar::onMouseMove (FMouseEvent* ev) } ++iter; } + if ( statusBar() ) + statusBar()->drawMessage(); if ( focus_changed ) redraw(); } @@ -535,6 +706,14 @@ void FMenuBar::hide() delete[] blank; } +//---------------------------------------------------------------------- +void FMenuBar::unselectItemInMenu() +{ + if ( hasSelectedMenuItem() ) + selectedMenuItem->unsetSelected(); + selectedMenuItem = 0; +} + //---------------------------------------------------------------------- void FMenuBar::setGeometry (int xx, int yy, int ww, int hh, bool adjust) { diff --git a/src/fmenubar.h b/src/fmenubar.h index 6a657280..28606879 100644 --- a/src/fmenubar.h +++ b/src/fmenubar.h @@ -54,6 +54,8 @@ class FMenuBar : public FWindow, public FMenuList void init(); void menu_dimension(); bool isMenu (FMenuItem*) const; + bool selectNextItem(); + bool selectPrevItem(); int getHotkeyPos (wchar_t*&, wchar_t*&, uInt); void draw(); void drawItems(); @@ -64,17 +66,19 @@ class FMenuBar : public FWindow, public FMenuList virtual ~FMenuBar(); // destructor virtual const char* getClassName() const; - void onKeyPress (FKeyEvent*); - void onMouseDown (FMouseEvent*); - void onMouseUp (FMouseEvent*); - void onMouseMove (FMouseEvent*); - void hide(); - bool hasSelectedMenuItem() const; + void onKeyPress (FKeyEvent*); + void onMouseDown (FMouseEvent*); + void onMouseUp (FMouseEvent*); + void onMouseMove (FMouseEvent*); + void hide(); + void unselectItemInMenu(); + FMenuItem* getSelectedMenuItem() const; + bool hasSelectedMenuItem() const; // make every setGeometry from FWidget available using FWidget::setGeometry; - void setGeometry (int, int, int, int, bool = true); - void cb_item_activated (FWidget*, void*); - void cb_item_deactivated (FWidget*, void*); + void setGeometry (int, int, int, int, bool = true); + void cb_item_activated (FWidget*, void*); + void cb_item_deactivated (FWidget*, void*); private: friend class FMenu; @@ -88,6 +92,10 @@ class FMenuBar : public FWindow, public FMenuList inline const char* FMenuBar::getClassName() const { return "FMenuBar"; } +//---------------------------------------------------------------------- +inline FMenuItem* FMenuBar::getSelectedMenuItem() const +{ return selectedMenuItem; } + //---------------------------------------------------------------------- inline bool FMenuBar::hasSelectedMenuItem() const { return selectedMenuItem; } diff --git a/src/fmenuitem.cpp b/src/fmenuitem.cpp index a5fc2f2a..5e820f05 100644 --- a/src/fmenuitem.cpp +++ b/src/fmenuitem.cpp @@ -87,7 +87,7 @@ FMenuItem::~FMenuItem() // destructor void FMenuItem::init (FWidget* parent) { text_length = text.getLength(); - hotkey = getHotkey(); + hotkey = hotKey(); if ( hotkey ) text_length--; setGeometry (1,1,int(text_length+2),1, false); @@ -147,7 +147,7 @@ void FMenuItem::init (FWidget* parent) } //---------------------------------------------------------------------- -uChar FMenuItem::getHotkey() +uChar FMenuItem::hotKey() { uInt length; @@ -338,14 +338,17 @@ void FMenuItem::onAccel (FAccelEvent* ev) FMenuBar* mb = dynamic_cast(super_menu); if ( mb ) { - if ( mb->selectedMenuItem ) - mb->selectedMenuItem->unsetSelected(); - setSelected(); - mb->selectedMenuItem = this; - mb->redraw(); if ( menu && ! menu->hasSelectedListItem() ) { - FWidget* focused_widget = static_cast(ev->focusedWidget()); + FWidget* focused_widget; + + if ( mb->getSelectedMenuItem() ) + mb->getSelectedMenuItem()->unsetSelected(); + setSelected(); + mb->selectedMenuItem = this; + + + focused_widget = static_cast(ev->focusedWidget()); FFocusEvent out (FocusOut_Event); FApplication::queueEvent(focused_widget, &out); menu->selectFirstItemInList(); @@ -355,6 +358,14 @@ void FMenuItem::onAccel (FAccelEvent* ev) menu->redraw(); if ( statusBar() ) statusBar()->drawMessage(); + mb->redraw(); + } + else + { + unsetSelected(); + mb->selectedMenuItem = 0; + mb->redraw(); + processClicked(); } ev->accept(); } @@ -417,13 +428,13 @@ bool FMenuItem::setFocus (bool on) if ( isEnabled() ) { - /*if ( statusBar() ) + if ( statusBar() ) { FString msg = getStatusbarMessage(); FString curMsg = statusBar()->getMessage(); if ( curMsg != msg ) statusBar()->setMessage(msg); - }*/ + } } } else @@ -458,7 +469,7 @@ void FMenuItem::setText (FString& txt) { text = txt; text_length = text.getLength(); - hotkey = getHotkey(); + hotkey = hotKey(); if ( hotkey ) text_length--; setWidth(int(text_length)); diff --git a/src/fmenuitem.h b/src/fmenuitem.h index 2c67546d..61442202 100644 --- a/src/fmenuitem.h +++ b/src/fmenuitem.h @@ -57,7 +57,7 @@ class FMenuItem : public FWidget FMenuItem (const FMenuItem&); FMenuItem& operator = (const FMenuItem&); void init (FWidget*); - uChar getHotkey(); + uChar hotKey(); bool isMenuBar (FWidget*) const; bool isMenu (FWidget*) const; FWidget* getSuperMenu() const; @@ -96,6 +96,7 @@ class FMenuItem : public FWidget void setChecked(); void unsetChecked(); bool isChecked() const; + int getHotkey() const; bool hasHotkey() const; FMenu* getMenu() const; void setMenu(FMenu*); @@ -162,6 +163,10 @@ inline void FMenuItem::unsetChecked() inline bool FMenuItem::isChecked() const { return checked; } +//---------------------------------------------------------------------- +inline int FMenuItem::getHotkey() const +{ return hotkey; } + //---------------------------------------------------------------------- inline bool FMenuItem::hasHotkey() const { return bool(hotkey != 0); } diff --git a/src/fmenulist.cpp b/src/fmenulist.cpp index 210e54f4..66a27369 100644 --- a/src/fmenulist.cpp +++ b/src/fmenulist.cpp @@ -25,7 +25,6 @@ FMenuList::~FMenuList() // destructor while ( iter != itemlist.end() ) { (*iter)->setSuperMenu(0); - //delAccelerator (*iter); iter = itemlist.erase(iter); } } diff --git a/src/fterm.cpp b/src/fterm.cpp index eacccb22..4d293d9d 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -1554,6 +1554,7 @@ void FTerm::init() setPalette (fc::DarkGray, 0x50, 0x50, 0x50); setPalette (fc::LightBlue, 0x80, 0xa4, 0xec); setPalette (fc::LightGreen, 0xd4, 0xd4, 0xd4); + setPalette (fc::LightCyan, 0x49, 0xc9, 0xe3); setPalette (fc::LightRed, 0xff, 0x54, 0x54); setPalette (fc::Yellow, 0xff, 0xff, 0x54); setPalette (fc::White, 0xff, 0xff, 0xff); diff --git a/src/fwidget.cpp b/src/fwidget.cpp index 15ae39ec..fd08ba9e 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -964,6 +964,12 @@ FMenuBar* FWidget::menuBar() return 0; } +//---------------------------------------------------------------------- +void FWidget::setStatusbarMessage (FString msg) +{ + statusbar_message = msg; +} + //---------------------------------------------------------------------- void FWidget::addCallback ( FString cb_signal , FWidget::FCallback cb_handler diff --git a/src/fwidget.h b/src/fwidget.h index ec2088d3..428477c1 100644 --- a/src/fwidget.h +++ b/src/fwidget.h @@ -343,7 +343,7 @@ class FWidget : public FObject, public FTerm static FStatusBar* statusBar(); static FMenuBar* menuBar(); - void setStatusbarMessage (FString); + virtual void setStatusbarMessage (FString); void clearStatusbarMessage(); FString getStatusbarMessage(); @@ -501,10 +501,6 @@ inline FWidget* FWidget::parentWidget() const inline bool FWidget::isRootWidget() const { return (! hasParent()); } -//---------------------------------------------------------------------- -inline void FWidget::setStatusbarMessage(FString msg) -{ statusbar_message = msg; } - //---------------------------------------------------------------------- inline void FWidget::clearStatusbarMessage() { statusbar_message.clear(); } diff --git a/test/ui.cpp b/test/ui.cpp index 7533d2d4..e4035315 100644 --- a/test/ui.cpp +++ b/test/ui.cpp @@ -192,33 +192,53 @@ MyDialog::MyDialog (FWidget* parent) : FDialog(parent) , myList() { - /* .--------------------------------------------. */ - /* v This Code is working in progress v */ - + // menu bar FMenuBar* Menubar = new FMenuBar(this); + // menu bar items FMenu* File = new FMenu("&File", Menubar); File->setStatusbarMessage("File management commands"); FMenu* Edit = new FMenu("&Edit", Menubar); + Edit->setStatusbarMessage("Cut-and-paste editing commands"); FMenu* View = new FMenu("&View", Menubar); + View->setStatusbarMessage("Show internal informations"); FMenuItem* Options = new FMenuItem("&Options", Menubar); + Options->setStatusbarMessage("Set program defaults"); Options->setDisable(); FMenuItem* Help = new FMenuItem("&Help", Menubar); + Help->setStatusbarMessage("Show version and copyright information"); + // "File" menu items FMenuItem* Open = new FMenuItem("&Open...", File); Open->setStatusbarMessage("Locate and open a text file"); - FMenuItem* Line = new FMenuItem(File); - Line->setSeparator(); + FMenuItem* Line1 = new FMenuItem(File); + Line1->setSeparator(); FMenuItem* Quit = new FMenuItem("&Quit", File); Quit->setStatusbarMessage("Exit the program"); + // "Edit" menu items + FMenuItem* Undo = new FMenuItem("Undo", Edit); + Undo->setDisable(); + FMenuItem* Redo = new FMenuItem("Redo", Edit); + Redo->setDisable(); + FMenuItem* Line2 = new FMenuItem(Edit); + Line2->setSeparator(); FMenuItem* Cut = new FMenuItem("Cu&t", Edit); + Cut->setStatusbarMessage("Remove the input text and put it in the clipboard"); FMenuItem* Copy = new FMenuItem("&Copy", Edit); + Copy->setStatusbarMessage("Copy the input text into the clipboad"); FMenuItem* Paste = new FMenuItem("&Paste", Edit); + Paste->setStatusbarMessage("Insert text form clipboard"); + FMenuItem* Clear = new FMenuItem("C&lear", Edit); + Clear->setStatusbarMessage("Delete input text"); + // "View" menu items FMenuItem* Env = new FMenuItem("&Terminal info...", View); + Env->setStatusbarMessage("Informations about this terminal"); FMenuItem* Drive = new FMenuItem("&Drive symbols...", View); + Drive->setStatusbarMessage("Show drive symbols"); + // Menu function callbacks Open->addCallback ( "clicked", @@ -244,6 +264,11 @@ MyDialog::MyDialog (FWidget* parent) "clicked", _METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg) ); + Clear->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg) + ); Env->addCallback ( "clicked", @@ -254,20 +279,13 @@ MyDialog::MyDialog (FWidget* parent) "clicked", _METHOD_CALLBACK (this, &MyDialog::cb_drives) ); - Options->addCallback - ( - "clicked", - _METHOD_CALLBACK (this, &MyDialog::cb_exitApp) - ); Help->addCallback ( "clicked", _METHOD_CALLBACK (this, &MyDialog::cb_about) ); - /* ^ This Code is working in progress ^ */ - /* '--------------------------------------------' */ - + // Buttons FButton* MyButton1 = new FButton(this); MyButton1->setGeometry(3, 3, 5, 1); MyButton1->setText(L"&SIN"); @@ -291,6 +309,7 @@ MyDialog::MyDialog (FWidget* parent) MyButton3->setNoUnderline(); MyButton3->setFlat(); + // Radio buttons in a group FButtonGroup* radioButtonGroup = new FButtonGroup("Button", this); radioButtonGroup->setGeometry(3, 8, 14, 4); //radioButtonGroup->unsetBorder(); @@ -306,6 +325,7 @@ MyDialog::MyDialog (FWidget* parent) radio2->setChecked(); //radio2->setDisable(); + // Checkboxes in a group FButtonGroup* checkButtonGroup = new FButtonGroup("Options", this); checkButtonGroup->setGeometry(3, 12, 14, 4); @@ -318,6 +338,7 @@ MyDialog::MyDialog (FWidget* parent) check2->setChecked(); check2->setNoUnderline(); + // A text input field FLineEdit* MyLineEdit = new FLineEdit(this); MyLineEdit->setGeometry(22, 1, 10, 1); MyLineEdit->setText( FString("EnTry").toLower()); @@ -325,6 +346,7 @@ MyDialog::MyDialog (FWidget* parent) MyLineEdit->setStatusbarMessage("Press Enter to set the title"); MyLineEdit->setShadow(); + // Buttons FButton* MyButton4 = new FButton(this); MyButton4->setGeometry(20, 8, 12, 1); MyButton4->setText(L"&Get input"); @@ -346,6 +368,7 @@ MyDialog::MyDialog (FWidget* parent) MyButton6->setShadow(); MyButton6->addAccelerator('x'); + // A multiple selection listbox myList = new FListBox(this); myList->setGeometry(38, 1, 14, 17); myList->setText("Items"); @@ -354,6 +377,7 @@ MyDialog::MyDialog (FWidget* parent) for (int z=1; z < 100; z++) myList->insert( FString().setNumber(z) + L" placeholder" ); + // Text labels FLabel* headline = new FLabel(this); headline->setGeometry(21, 3, 10, 1); headline->setText(L"List items"); @@ -375,11 +399,14 @@ MyDialog::MyDialog (FWidget* parent) sum_count->setGeometry(29, 5, 5, 3); sum_count->setNumber(myList->count()); + // Statusbar at the bottom FStatusBar* statusbar = new FStatusBar(this); + // Statusbar keys FStatusKey* key_F1 = new FStatusKey(fc::Fkey_f1, "About", statusbar); FStatusKey* key_F2 = new FStatusKey(fc::Fkey_f2, "View", statusbar); FStatusKey* key_F3 = new FStatusKey(fc::Fkey_f3, "Quit", statusbar); + // Add some function callbacks MyButton1->addCallback ( "clicked",