First working version of an application menu

This commit is contained in:
Markus Gans 2015-11-01 22:45:23 +01:00
parent ff8394d9f3
commit 18a7d991ff
14 changed files with 435 additions and 105 deletions

View File

@ -1,3 +1,8 @@
2015-11-01 Markus Gans <guru.mail@muenster.de>
* First working version of an application menu,
it uses the new classes FMenuBar, FMenu and FMenuItem
(alpha state)
2015-10-29 Markus Gans <guru.mail@muenster.de> 2015-10-29 Markus Gans <guru.mail@muenster.de>
* Support for the menu key * Support for the menu key

View File

@ -4,6 +4,7 @@ Bugs
Improvements Improvements
~~~~~~~~~~~~ ~~~~~~~~~~~~
- Stabilize the application menu classes (FMenuBar, FMenu, FMenuItem)
- If t_exit_underline_mode == "\E[24m" - If t_exit_underline_mode == "\E[24m"
-> implement t_exit_bold_mode with "\E[21m" -> implement t_exit_bold_mode with "\E[21m"
-> implement t_exit_reverse_mode with "\E[27m" -> implement t_exit_reverse_mode with "\E[27m"
@ -15,11 +16,6 @@ Improvements
Missing Features Missing Features
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
- application menu
- FMenuBar()
- FMenu()
- FMenuItem()
- list/tree view with Columns - list/tree view with Columns
- FListView() - FListView()
--------------------------------------- ---------------------------------------

View File

@ -347,8 +347,11 @@ void FApplication::processKeyboardEvent()
} }
else else
{ {
// send key down event
FKeyEvent k_down_ev (KeyDown_Event, key); FKeyEvent k_down_ev (KeyDown_Event, key);
sendEvent (widget, &k_down_ev); sendEvent (widget, &k_down_ev);
// send key press event
FKeyEvent k_press_ev (KeyPress_Event, key); FKeyEvent k_press_ev (KeyPress_Event, key);
sendEvent (widget, &k_press_ev); sendEvent (widget, &k_press_ev);
@ -384,6 +387,7 @@ void FApplication::processKeyboardEvent()
} }
fifo_offset = int(strlen(fifo_buf)); fifo_offset = int(strlen(fifo_buf));
} }
// send key up event
FKeyEvent k_up_ev (KeyUp_Event, key); FKeyEvent k_up_ev (KeyUp_Event, key);
sendEvent (widget, &k_up_ev); sendEvent (widget, &k_up_ev);
key = 0; key = 0;

View File

@ -3,7 +3,6 @@
#include "fapp.h" #include "fapp.h"
#include "fmenu.h" #include "fmenu.h"
#include "fmessagebox.h" // <----- remove later
#include "fstatusbar.h" #include "fstatusbar.h"
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -113,7 +112,16 @@ void FMenu::init(FWidget* parent)
item->setMenu(this); item->setMenu(this);
if ( parent ) if ( parent )
{
if ( isMenuBar(parent) )
{
FMenuBar* mb = dynamic_cast<FMenuBar*>(parent);
if ( mb )
mb->menu_dimension();
}
setSuperMenu(parent); setSuperMenu(parent);
}
menu_dimension();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -123,7 +131,7 @@ void FMenu::menu_dimension()
std::vector<FMenuItem*>::const_iterator iter, end; std::vector<FMenuItem*>::const_iterator iter, end;
iter = itemlist.begin(); iter = itemlist.begin();
end = itemlist.end(); end = itemlist.end();
maxItemWidth = 0; maxItemWidth = 10;
// find the max item width // find the max item width
while ( iter != end ) while ( iter != end )
@ -451,7 +459,6 @@ void FMenu::drawItems()
uInt txt_length; uInt txt_length;
int hotkeypos, to_char; int hotkeypos, to_char;
bool is_enabled = (*iter)->isEnabled(); bool is_enabled = (*iter)->isEnabled();
bool has_focus = (*iter)->hasFocus();
bool is_selected = (*iter)->isSelected(); bool is_selected = (*iter)->isSelected();
bool is_noUnderline = (((*iter)->getFlags() & NO_UNDERLINE) != 0); bool is_noUnderline = (((*iter)->getFlags() & NO_UNDERLINE) != 0);
bool is_separator = (*iter)->isSeparator(); bool is_separator = (*iter)->isSeparator();
@ -475,12 +482,16 @@ void FMenu::drawItems()
{ {
foregroundColor = wc.menu_active_fg; foregroundColor = wc.menu_active_fg;
backgroundColor = wc.menu_active_bg; backgroundColor = wc.menu_active_bg;
if ( isMonochron() )
setReverse(true);
} }
} }
else else
{ {
foregroundColor = wc.menu_inactive_fg; foregroundColor = wc.menu_inactive_fg;
backgroundColor = wc.menu_inactive_bg; backgroundColor = wc.menu_inactive_bg;
if ( isMonochron() )
setReverse(true);
} }
gotoxy (xpos+xmin, ypos+ymin+y); gotoxy (xpos+xmin, ypos+ymin+y);
setColor (foregroundColor, backgroundColor); setColor (foregroundColor, backgroundColor);
@ -494,8 +505,17 @@ void FMenu::drawItems()
to_char = int(txt_length); to_char = int(txt_length);
hotkeypos = getHotkeyPos (src, dest, 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--; txt_length--;
to_char--; to_char--;
} }
@ -534,7 +554,7 @@ void FMenu::drawItems()
setReverse(true); setReverse(true);
delete[] item_text; delete[] item_text;
} }
if ( has_focus && statusBar() ) /*if ( is_selected && statusBar() )
{ {
FString msg = (*iter)->getStatusbarMessage(); FString msg = (*iter)->getStatusbarMessage();
FString curMsg = statusBar()->getMessage(); FString curMsg = statusBar()->getMessage();
@ -543,10 +563,12 @@ void FMenu::drawItems()
statusBar()->setMessage(msg); statusBar()->setMessage(msg);
statusBar()->drawMessage(); statusBar()->drawMessage();
} }
} }*/
++iter; ++iter;
y++; y++;
} }
if ( hasFocus() )
setCursor();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -554,10 +576,14 @@ inline void FMenu::drawSeparator(int y)
{ {
gotoxy (xpos+xmin-1, ypos+ymin+y); gotoxy (xpos+xmin-1, ypos+ymin+y);
setColor (wc.menu_active_fg, wc.menu_active_bg); setColor (wc.menu_active_fg, wc.menu_active_bg);
if ( isMonochron() )
setReverse(true);
print(fc::BoxDrawingsVerticalAndRight); print(fc::BoxDrawingsVerticalAndRight);
FString line(width-2, wchar_t(fc::BoxDrawingsHorizontal)); FString line(width-2, wchar_t(fc::BoxDrawingsHorizontal));
print (line); print (line);
print(fc::BoxDrawingsVerticalAndLeft); print(fc::BoxDrawingsVerticalAndLeft);
if ( isMonochron() )
setReverse(false);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -571,6 +597,40 @@ void FMenu::processActivate()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenu::onKeyPress (FKeyEvent* ev) void FMenu::onKeyPress (FKeyEvent* ev)
{ {
// looking for a hotkey
std::vector<FMenuItem*>::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() ) switch ( ev->key() )
{ {
case fc::Fkey_return: case fc::Fkey_return:
@ -597,7 +657,7 @@ void FMenu::onKeyPress (FKeyEvent* ev)
break; break;
case fc::Fkey_left: case fc::Fkey_left:
if ( selectedListItem->hasMenu() ) if ( hasSelectedListItem() && selectedListItem->hasMenu() )
{ {
FMenu* sub_menu = selectedListItem->getMenu(); FMenu* sub_menu = selectedListItem->getMenu();
if ( sub_menu->isVisible() ) if ( sub_menu->isVisible() )
@ -611,7 +671,7 @@ void FMenu::onKeyPress (FKeyEvent* ev)
break; break;
case fc::Fkey_right: case fc::Fkey_right:
if ( selectedListItem->hasMenu() ) if ( hasSelectedListItem() && selectedListItem->hasMenu() )
{ {
FMenu* sub_menu = selectedListItem->getMenu(); FMenu* sub_menu = selectedListItem->getMenu();
if ( ! sub_menu->isVisible() ) if ( ! sub_menu->isVisible() )
@ -790,16 +850,14 @@ void FMenu::onMouseMove (FMouseEvent* ev)
y = (*iter)->getY(); y = (*iter)->getY();
mouse_x = mouse_pos.getX(); mouse_x = mouse_pos.getX();
mouse_y = mouse_pos.getY(); 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 if ( mouse_x >= x1
&& mouse_x <= x2 && mouse_x <= x2
&& mouse_y == y ) && mouse_y == y )
{ {
if ( (*iter)->isEnabled() && ! (*iter)->isSelected() ) if ( (*iter)->isEnabled()
&& ! (*iter)->isSelected()
&& ! (*iter)->isSeparator() )
{ {
FWidget* focused_widget = getFocusWidget(); FWidget* focused_widget = getFocusWidget();
FFocusEvent out (FocusOut_Event); FFocusEvent out (FocusOut_Event);
@ -829,6 +887,20 @@ FMessageBox::info (this, "Info", FString().sprintf("local(%d,%d) global(%d,%d)\n
++iter; ++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(); FWidget* menubar = getSuperMenu();
if ( menubar if ( menubar
&& isMenuBar(menubar) && isMenuBar(menubar)
@ -897,17 +969,37 @@ void FMenu::setGeometry (int xx, int yy, int ww, int hh, bool adjust)
resizeArea (vwin); resizeArea (vwin);
} }
//----------------------------------------------------------------------
void FMenu::setStatusbarMessage(FString msg)
{
FWidget::setStatusbarMessage(msg);
if ( item )
item->setStatusbarMessage(msg);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenu::selectFirstItemInList() void FMenu::selectFirstItemInList()
{ {
std::vector<FMenuItem*>::const_iterator iter, end;
iter = itemlist.begin();
end = itemlist.end();
if ( itemlist.empty() ) if ( itemlist.empty() )
return; return;
if ( ! hasSelectedListItem() ) if ( hasSelectedListItem() )
unselectItemInList();
while ( iter != end )
{ {
// select the first item if ( (*iter)->isEnabled() && ! (*iter)->isSeparator() )
itemlist[0]->setSelected(); {
selectedListItem = itemlist[0]; // select first enabled item
(*iter)->setSelected();
selectedListItem = *iter;
break;
}
++iter;
} }
} }

View File

@ -94,6 +94,7 @@ class FMenu : public FWindow, public FMenuList
// make every setGeometry from FWidget available // make every setGeometry from FWidget available
using FWidget::setGeometry; using FWidget::setGeometry;
void setGeometry (int, int, int, int, bool = true); void setGeometry (int, int, int, int, bool = true);
void setStatusbarMessage (FString);
FMenuItem* getItem() const; FMenuItem* getItem() const;
FString getText() const; FString getText() const;
bool setEnable(bool); bool setEnable(bool);

View File

@ -3,6 +3,7 @@
#include "fapp.h" #include "fapp.h"
#include "fmenubar.h" #include "fmenubar.h"
#include "fstatusbar.h"
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// class FMenuBar // class FMenuBar
@ -87,6 +88,109 @@ bool FMenuBar::isMenu (FMenuItem* mi) const
return mi->hasMenu(); return mi->hasMenu();
} }
//----------------------------------------------------------------------
bool FMenuBar::selectNextItem()
{
std::vector<FMenuItem*>::const_iterator iter, end;
iter = itemlist.begin();
end = itemlist.end();
while ( iter != end )
{
if ( (*iter)->isSelected() )
{
FMenuItem* next;
std::vector<FMenuItem*>::const_iterator next_element;
next_element = iter;
do
{
++next_element;
if ( next_element == itemlist.end() )
next_element = itemlist.begin();
next = static_cast<FMenuItem*>(*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<FMenuItem*>::const_iterator iter, begin;
iter = itemlist.end();
begin = itemlist.begin();
do
{
--iter;
if ( (*iter)->isSelected() )
{
FMenuItem* prev;
std::vector<FMenuItem*>::const_iterator prev_element;
prev_element = iter;
do
{
if ( prev_element == itemlist.begin() )
prev_element = itemlist.end();
--prev_element;
prev = static_cast<FMenuItem*>(*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) int FMenuBar::getHotkeyPos (wchar_t*& src, wchar_t*& dest, uInt length)
{ {
@ -147,16 +251,17 @@ void FMenuBar::drawItems()
wchar_t* item_text; wchar_t* item_text;
FString txt; FString txt;
uInt txt_length; uInt txt_length;
int hotkeypos, to_char; int hotkeypos, startpos, to_char;
bool is_Active, is_Selected, is_NoUnderline; bool is_active, is_selected, is_noUnderline;
is_Active = (*iter)->isEnabled(); startpos = x + 1;
is_Selected = (*iter)->isSelected(); is_active = (*iter)->isEnabled();
is_NoUnderline = (((*iter)->getFlags() & NO_UNDERLINE) != 0); 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() ) if ( isMonochron() )
setReverse(false); setReverse(false);
@ -175,8 +280,12 @@ void FMenuBar::drawItems()
backgroundColor = wc.menu_inactive_bg; backgroundColor = wc.menu_inactive_bg;
} }
setColor (foregroundColor, backgroundColor); setColor (foregroundColor, backgroundColor);
x++;
print (vmenubar, ' '); if ( x < screenWidth )
{
x++;
print (vmenubar, ' ');
}
txt = (*iter)->getText(); txt = (*iter)->getText();
txt_length = uInt(txt.getLength()); txt_length = uInt(txt.getLength());
@ -196,10 +305,13 @@ void FMenuBar::drawItems()
txt_length--; txt_length--;
to_char--; to_char--;
} }
x += int(txt_length); x += int(txt_length);
for (int z=0; z < to_char; z++) for (int z=0; z < to_char; z++)
{ {
if ( startpos > screenWidth-z )
break;
if ( ! iswprint(wint_t(item_text[z])) ) if ( ! iswprint(wint_t(item_text[z])) )
{ {
if ( ! isNewFont() && ( int(item_text[z]) < fc::NF_rev_left_arrow2 if ( ! isNewFont() && ( int(item_text[z]) < fc::NF_rev_left_arrow2
@ -208,13 +320,13 @@ void FMenuBar::drawItems()
item_text[z] = L' '; 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); setColor (wc.menu_hotkey_fg, wc.menu_hotkey_bg);
if ( ! is_NoUnderline ) if ( ! is_noUnderline )
setUnderline(); setUnderline();
print (vmenubar, item_text[z]); print (vmenubar, item_text[z]);
if ( ! is_NoUnderline ) if ( ! is_noUnderline )
unsetUnderline(); unsetUnderline();
setColor (foregroundColor, backgroundColor); setColor (foregroundColor, backgroundColor);
} }
@ -222,19 +334,28 @@ void FMenuBar::drawItems()
print (vmenubar, item_text[z]); print (vmenubar, item_text[z]);
} }
if ( x > screenWidth ) if ( x > screenWidth+1 )
{ {
print (vmenubar, txt.left(uInt(int(txt_length)+screenWidth-x-1))); if ( startpos < screenWidth )
print (vmenubar, ".."); {
gotoxy(screenWidth-1,1);
print (vmenubar, "..");
}
else if ( startpos-2 < screenWidth )
{
gotoxy(screenWidth,1);
print (vmenubar, ' ');
}
} }
else
if ( x < screenWidth )
{ {
x++; x++;
print (vmenubar, ' '); print (vmenubar, ' ');
} }
setColor (wc.menu_active_fg, wc.menu_active_bg); setColor (wc.menu_active_fg, wc.menu_active_bg);
if ( isMonochron() && is_Active && is_Selected ) if ( isMonochron() && is_active && is_selected )
setReverse(true); setReverse(true);
delete[] item_text; delete[] item_text;
@ -248,6 +369,17 @@ void FMenuBar::drawItems()
setReverse(false); setReverse(false);
setUpdateVTerm(true); 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() ) 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: case fc::Fkey_left:
beep(); selectPrevItem();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_right: case fc::Fkey_right:
beep(); selectNextItem();
ev->accept(); ev->accept();
break; break;
@ -288,22 +441,11 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
if ( ev->getButton() != LeftButton ) if ( ev->getButton() != LeftButton )
{ {
mouse_down = false; mouse_down = false;
if ( ! itemlist.empty() ) if ( ! itemlist.empty() )
{ {
std::vector<FMenuItem*>::const_iterator iter, end; unselectItemInMenu();
iter = itemlist.begin(); redraw();
end = itemlist.end();
while ( iter != end )
{
(*iter)->unsetSelected();
if ( selectedMenuItem == *iter )
selectedMenuItem = 0;
++iter;
}
} }
redraw();
return; return;
} }
@ -340,10 +482,17 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
{ {
if ( (*iter)->isEnabled() && ! (*iter)->isSelected() ) if ( (*iter)->isEnabled() && ! (*iter)->isSelected() )
{ {
FWidget* focused_widget = getFocusWidget();
FFocusEvent out (FocusOut_Event);
FApplication::queueEvent(focused_widget, &out);
(*iter)->setSelected(); (*iter)->setSelected();
//FMessageBox::info (this, "Info", (*iter)->getStatusbarMessage());
(*iter)->setFocus(); (*iter)->setFocus();
//FMessageBox::info (this, "Info", statusBar()->getMessage());
selectedMenuItem = *iter; selectedMenuItem = *iter;
focus_changed = true; focus_changed = true;
if ( focused_widget )
focused_widget->redraw();
} }
if ( (*iter)->hasMenu() ) if ( (*iter)->hasMenu() )
{ {
@ -351,9 +500,12 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
if ( menu->hasSelectedListItem() ) if ( menu->hasSelectedListItem() )
{ {
menu->unselectItemInList(); menu->unselectItemInList();
(*iter)->setFocus();
menu->redraw(); menu->redraw();
focus_changed = true;
} }
} }
} }
else else
{ {
@ -369,6 +521,8 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
} }
++iter; ++iter;
} }
if ( statusBar() )
statusBar()->drawMessage();
if ( focus_changed ) if ( focus_changed )
redraw(); redraw();
} }
@ -411,9 +565,15 @@ void FMenuBar::onMouseUp (FMouseEvent* ev)
FMenu* menu = (*iter)->getMenu(); FMenu* menu = (*iter)->getMenu();
if ( ! menu->hasSelectedListItem() ) if ( ! menu->hasSelectedListItem() )
{ {
FMenuItem* first_item;
menu->selectFirstItemInList(); menu->selectFirstItemInList();
menu->getSelectedListItem()->setFocus(); first_item = menu->getSelectedListItem();
if ( first_item )
first_item->setFocus();
menu->redraw(); menu->redraw();
if ( statusBar() )
statusBar()->drawMessage();
redraw();
} }
} }
else else
@ -464,20 +624,28 @@ void FMenuBar::onMouseMove (FMouseEvent* ev)
{ {
if ( (*iter)->isEnabled() && ! (*iter)->isSelected() ) if ( (*iter)->isEnabled() && ! (*iter)->isSelected() )
{ {
FWidget* focused_widget = getFocusWidget();
FFocusEvent out (FocusOut_Event);
FApplication::queueEvent(focused_widget, &out);
(*iter)->setSelected(); (*iter)->setSelected();
(*iter)->setFocus(); (*iter)->setFocus();
selectedMenuItem = *iter; selectedMenuItem = *iter;
focus_changed = true; 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() ) else if ( statusBar() )
{ statusBar()->clearMessage();
FMenu* menu = (*iter)->getMenu();
if ( menu->hasSelectedListItem() )
{
menu->unselectItemInList();
menu->redraw();
}
}
} }
else else
{ {
@ -492,6 +660,7 @@ void FMenuBar::onMouseMove (FMouseEvent* ev)
} }
else if ( hasSelectedMenuItem() && selectedMenuItem->hasMenu() ) else if ( hasSelectedMenuItem() && selectedMenuItem->hasMenu() )
{ {
// Mouse event handover to the menu
FMenu* menu = selectedMenuItem->getMenu(); FMenu* menu = selectedMenuItem->getMenu();
const FRect& menu_geometry = menu->getGeometryGlobal(); const FRect& menu_geometry = menu->getGeometryGlobal();
@ -508,6 +677,8 @@ void FMenuBar::onMouseMove (FMouseEvent* ev)
} }
++iter; ++iter;
} }
if ( statusBar() )
statusBar()->drawMessage();
if ( focus_changed ) if ( focus_changed )
redraw(); redraw();
} }
@ -535,6 +706,14 @@ void FMenuBar::hide()
delete[] blank; delete[] blank;
} }
//----------------------------------------------------------------------
void FMenuBar::unselectItemInMenu()
{
if ( hasSelectedMenuItem() )
selectedMenuItem->unsetSelected();
selectedMenuItem = 0;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenuBar::setGeometry (int xx, int yy, int ww, int hh, bool adjust) void FMenuBar::setGeometry (int xx, int yy, int ww, int hh, bool adjust)
{ {

View File

@ -54,6 +54,8 @@ class FMenuBar : public FWindow, public FMenuList
void init(); void init();
void menu_dimension(); void menu_dimension();
bool isMenu (FMenuItem*) const; bool isMenu (FMenuItem*) const;
bool selectNextItem();
bool selectPrevItem();
int getHotkeyPos (wchar_t*&, wchar_t*&, uInt); int getHotkeyPos (wchar_t*&, wchar_t*&, uInt);
void draw(); void draw();
void drawItems(); void drawItems();
@ -64,17 +66,19 @@ class FMenuBar : public FWindow, public FMenuList
virtual ~FMenuBar(); // destructor virtual ~FMenuBar(); // destructor
virtual const char* getClassName() const; virtual const char* getClassName() const;
void onKeyPress (FKeyEvent*); void onKeyPress (FKeyEvent*);
void onMouseDown (FMouseEvent*); void onMouseDown (FMouseEvent*);
void onMouseUp (FMouseEvent*); void onMouseUp (FMouseEvent*);
void onMouseMove (FMouseEvent*); void onMouseMove (FMouseEvent*);
void hide(); void hide();
bool hasSelectedMenuItem() const; void unselectItemInMenu();
FMenuItem* getSelectedMenuItem() const;
bool hasSelectedMenuItem() const;
// make every setGeometry from FWidget available // make every setGeometry from FWidget available
using FWidget::setGeometry; using FWidget::setGeometry;
void setGeometry (int, int, int, int, bool = true); void setGeometry (int, int, int, int, bool = true);
void cb_item_activated (FWidget*, void*); void cb_item_activated (FWidget*, void*);
void cb_item_deactivated (FWidget*, void*); void cb_item_deactivated (FWidget*, void*);
private: private:
friend class FMenu; friend class FMenu;
@ -88,6 +92,10 @@ class FMenuBar : public FWindow, public FMenuList
inline const char* FMenuBar::getClassName() const inline const char* FMenuBar::getClassName() const
{ return "FMenuBar"; } { return "FMenuBar"; }
//----------------------------------------------------------------------
inline FMenuItem* FMenuBar::getSelectedMenuItem() const
{ return selectedMenuItem; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenuBar::hasSelectedMenuItem() const inline bool FMenuBar::hasSelectedMenuItem() const
{ return selectedMenuItem; } { return selectedMenuItem; }

View File

@ -87,7 +87,7 @@ FMenuItem::~FMenuItem() // destructor
void FMenuItem::init (FWidget* parent) void FMenuItem::init (FWidget* parent)
{ {
text_length = text.getLength(); text_length = text.getLength();
hotkey = getHotkey(); hotkey = hotKey();
if ( hotkey ) if ( hotkey )
text_length--; text_length--;
setGeometry (1,1,int(text_length+2),1, false); 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; uInt length;
@ -338,14 +338,17 @@ void FMenuItem::onAccel (FAccelEvent* ev)
FMenuBar* mb = dynamic_cast<FMenuBar*>(super_menu); FMenuBar* mb = dynamic_cast<FMenuBar*>(super_menu);
if ( mb ) if ( mb )
{ {
if ( mb->selectedMenuItem )
mb->selectedMenuItem->unsetSelected();
setSelected();
mb->selectedMenuItem = this;
mb->redraw();
if ( menu && ! menu->hasSelectedListItem() ) if ( menu && ! menu->hasSelectedListItem() )
{ {
FWidget* focused_widget = static_cast<FWidget*>(ev->focusedWidget()); FWidget* focused_widget;
if ( mb->getSelectedMenuItem() )
mb->getSelectedMenuItem()->unsetSelected();
setSelected();
mb->selectedMenuItem = this;
focused_widget = static_cast<FWidget*>(ev->focusedWidget());
FFocusEvent out (FocusOut_Event); FFocusEvent out (FocusOut_Event);
FApplication::queueEvent(focused_widget, &out); FApplication::queueEvent(focused_widget, &out);
menu->selectFirstItemInList(); menu->selectFirstItemInList();
@ -355,6 +358,14 @@ void FMenuItem::onAccel (FAccelEvent* ev)
menu->redraw(); menu->redraw();
if ( statusBar() ) if ( statusBar() )
statusBar()->drawMessage(); statusBar()->drawMessage();
mb->redraw();
}
else
{
unsetSelected();
mb->selectedMenuItem = 0;
mb->redraw();
processClicked();
} }
ev->accept(); ev->accept();
} }
@ -417,13 +428,13 @@ bool FMenuItem::setFocus (bool on)
if ( isEnabled() ) if ( isEnabled() )
{ {
/*if ( statusBar() ) if ( statusBar() )
{ {
FString msg = getStatusbarMessage(); FString msg = getStatusbarMessage();
FString curMsg = statusBar()->getMessage(); FString curMsg = statusBar()->getMessage();
if ( curMsg != msg ) if ( curMsg != msg )
statusBar()->setMessage(msg); statusBar()->setMessage(msg);
}*/ }
} }
} }
else else
@ -458,7 +469,7 @@ void FMenuItem::setText (FString& txt)
{ {
text = txt; text = txt;
text_length = text.getLength(); text_length = text.getLength();
hotkey = getHotkey(); hotkey = hotKey();
if ( hotkey ) if ( hotkey )
text_length--; text_length--;
setWidth(int(text_length)); setWidth(int(text_length));

View File

@ -57,7 +57,7 @@ class FMenuItem : public FWidget
FMenuItem (const FMenuItem&); FMenuItem (const FMenuItem&);
FMenuItem& operator = (const FMenuItem&); FMenuItem& operator = (const FMenuItem&);
void init (FWidget*); void init (FWidget*);
uChar getHotkey(); uChar hotKey();
bool isMenuBar (FWidget*) const; bool isMenuBar (FWidget*) const;
bool isMenu (FWidget*) const; bool isMenu (FWidget*) const;
FWidget* getSuperMenu() const; FWidget* getSuperMenu() const;
@ -96,6 +96,7 @@ class FMenuItem : public FWidget
void setChecked(); void setChecked();
void unsetChecked(); void unsetChecked();
bool isChecked() const; bool isChecked() const;
int getHotkey() const;
bool hasHotkey() const; bool hasHotkey() const;
FMenu* getMenu() const; FMenu* getMenu() const;
void setMenu(FMenu*); void setMenu(FMenu*);
@ -162,6 +163,10 @@ inline void FMenuItem::unsetChecked()
inline bool FMenuItem::isChecked() const inline bool FMenuItem::isChecked() const
{ return checked; } { return checked; }
//----------------------------------------------------------------------
inline int FMenuItem::getHotkey() const
{ return hotkey; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenuItem::hasHotkey() const inline bool FMenuItem::hasHotkey() const
{ return bool(hotkey != 0); } { return bool(hotkey != 0); }

View File

@ -25,7 +25,6 @@ FMenuList::~FMenuList() // destructor
while ( iter != itemlist.end() ) while ( iter != itemlist.end() )
{ {
(*iter)->setSuperMenu(0); (*iter)->setSuperMenu(0);
//delAccelerator (*iter);
iter = itemlist.erase(iter); iter = itemlist.erase(iter);
} }
} }

View File

@ -1554,6 +1554,7 @@ void FTerm::init()
setPalette (fc::DarkGray, 0x50, 0x50, 0x50); setPalette (fc::DarkGray, 0x50, 0x50, 0x50);
setPalette (fc::LightBlue, 0x80, 0xa4, 0xec); setPalette (fc::LightBlue, 0x80, 0xa4, 0xec);
setPalette (fc::LightGreen, 0xd4, 0xd4, 0xd4); setPalette (fc::LightGreen, 0xd4, 0xd4, 0xd4);
setPalette (fc::LightCyan, 0x49, 0xc9, 0xe3);
setPalette (fc::LightRed, 0xff, 0x54, 0x54); setPalette (fc::LightRed, 0xff, 0x54, 0x54);
setPalette (fc::Yellow, 0xff, 0xff, 0x54); setPalette (fc::Yellow, 0xff, 0xff, 0x54);
setPalette (fc::White, 0xff, 0xff, 0xff); setPalette (fc::White, 0xff, 0xff, 0xff);

View File

@ -964,6 +964,12 @@ FMenuBar* FWidget::menuBar()
return 0; return 0;
} }
//----------------------------------------------------------------------
void FWidget::setStatusbarMessage (FString msg)
{
statusbar_message = msg;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FWidget::addCallback ( FString cb_signal void FWidget::addCallback ( FString cb_signal
, FWidget::FCallback cb_handler , FWidget::FCallback cb_handler

View File

@ -343,7 +343,7 @@ class FWidget : public FObject, public FTerm
static FStatusBar* statusBar(); static FStatusBar* statusBar();
static FMenuBar* menuBar(); static FMenuBar* menuBar();
void setStatusbarMessage (FString); virtual void setStatusbarMessage (FString);
void clearStatusbarMessage(); void clearStatusbarMessage();
FString getStatusbarMessage(); FString getStatusbarMessage();
@ -501,10 +501,6 @@ inline FWidget* FWidget::parentWidget() const
inline bool FWidget::isRootWidget() const inline bool FWidget::isRootWidget() const
{ return (! hasParent()); } { return (! hasParent()); }
//----------------------------------------------------------------------
inline void FWidget::setStatusbarMessage(FString msg)
{ statusbar_message = msg; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FWidget::clearStatusbarMessage() inline void FWidget::clearStatusbarMessage()
{ statusbar_message.clear(); } { statusbar_message.clear(); }

View File

@ -192,33 +192,53 @@ MyDialog::MyDialog (FWidget* parent)
: FDialog(parent) : FDialog(parent)
, myList() , myList()
{ {
/* .--------------------------------------------. */ // menu bar
/* v This Code is working in progress v */
FMenuBar* Menubar = new FMenuBar(this); FMenuBar* Menubar = new FMenuBar(this);
// menu bar items
FMenu* File = new FMenu("&File", Menubar); FMenu* File = new FMenu("&File", Menubar);
File->setStatusbarMessage("File management commands"); File->setStatusbarMessage("File management commands");
FMenu* Edit = new FMenu("&Edit", Menubar); FMenu* Edit = new FMenu("&Edit", Menubar);
Edit->setStatusbarMessage("Cut-and-paste editing commands");
FMenu* View = new FMenu("&View", Menubar); FMenu* View = new FMenu("&View", Menubar);
View->setStatusbarMessage("Show internal informations");
FMenuItem* Options = new FMenuItem("&Options", Menubar); FMenuItem* Options = new FMenuItem("&Options", Menubar);
Options->setStatusbarMessage("Set program defaults");
Options->setDisable(); Options->setDisable();
FMenuItem* Help = new FMenuItem("&Help", Menubar); FMenuItem* Help = new FMenuItem("&Help", Menubar);
Help->setStatusbarMessage("Show version and copyright information");
// "File" menu items
FMenuItem* Open = new FMenuItem("&Open...", File); FMenuItem* Open = new FMenuItem("&Open...", File);
Open->setStatusbarMessage("Locate and open a text file"); Open->setStatusbarMessage("Locate and open a text file");
FMenuItem* Line = new FMenuItem(File); FMenuItem* Line1 = new FMenuItem(File);
Line->setSeparator(); Line1->setSeparator();
FMenuItem* Quit = new FMenuItem("&Quit", File); FMenuItem* Quit = new FMenuItem("&Quit", File);
Quit->setStatusbarMessage("Exit the program"); 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); 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); FMenuItem* Copy = new FMenuItem("&Copy", Edit);
Copy->setStatusbarMessage("Copy the input text into the clipboad");
FMenuItem* Paste = new FMenuItem("&Paste", Edit); 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); FMenuItem* Env = new FMenuItem("&Terminal info...", View);
Env->setStatusbarMessage("Informations about this terminal");
FMenuItem* Drive = new FMenuItem("&Drive symbols...", View); FMenuItem* Drive = new FMenuItem("&Drive symbols...", View);
Drive->setStatusbarMessage("Show drive symbols");
// Menu function callbacks
Open->addCallback Open->addCallback
( (
"clicked", "clicked",
@ -244,6 +264,11 @@ MyDialog::MyDialog (FWidget* parent)
"clicked", "clicked",
_METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg) _METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg)
); );
Clear->addCallback
(
"clicked",
_METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg)
);
Env->addCallback Env->addCallback
( (
"clicked", "clicked",
@ -254,20 +279,13 @@ MyDialog::MyDialog (FWidget* parent)
"clicked", "clicked",
_METHOD_CALLBACK (this, &MyDialog::cb_drives) _METHOD_CALLBACK (this, &MyDialog::cb_drives)
); );
Options->addCallback
(
"clicked",
_METHOD_CALLBACK (this, &MyDialog::cb_exitApp)
);
Help->addCallback Help->addCallback
( (
"clicked", "clicked",
_METHOD_CALLBACK (this, &MyDialog::cb_about) _METHOD_CALLBACK (this, &MyDialog::cb_about)
); );
/* ^ This Code is working in progress ^ */ // Buttons
/* '--------------------------------------------' */
FButton* MyButton1 = new FButton(this); FButton* MyButton1 = new FButton(this);
MyButton1->setGeometry(3, 3, 5, 1); MyButton1->setGeometry(3, 3, 5, 1);
MyButton1->setText(L"&SIN"); MyButton1->setText(L"&SIN");
@ -291,6 +309,7 @@ MyDialog::MyDialog (FWidget* parent)
MyButton3->setNoUnderline(); MyButton3->setNoUnderline();
MyButton3->setFlat(); MyButton3->setFlat();
// Radio buttons in a group
FButtonGroup* radioButtonGroup = new FButtonGroup("Button", this); FButtonGroup* radioButtonGroup = new FButtonGroup("Button", this);
radioButtonGroup->setGeometry(3, 8, 14, 4); radioButtonGroup->setGeometry(3, 8, 14, 4);
//radioButtonGroup->unsetBorder(); //radioButtonGroup->unsetBorder();
@ -306,6 +325,7 @@ MyDialog::MyDialog (FWidget* parent)
radio2->setChecked(); radio2->setChecked();
//radio2->setDisable(); //radio2->setDisable();
// Checkboxes in a group
FButtonGroup* checkButtonGroup = new FButtonGroup("Options", this); FButtonGroup* checkButtonGroup = new FButtonGroup("Options", this);
checkButtonGroup->setGeometry(3, 12, 14, 4); checkButtonGroup->setGeometry(3, 12, 14, 4);
@ -318,6 +338,7 @@ MyDialog::MyDialog (FWidget* parent)
check2->setChecked(); check2->setChecked();
check2->setNoUnderline(); check2->setNoUnderline();
// A text input field
FLineEdit* MyLineEdit = new FLineEdit(this); FLineEdit* MyLineEdit = new FLineEdit(this);
MyLineEdit->setGeometry(22, 1, 10, 1); MyLineEdit->setGeometry(22, 1, 10, 1);
MyLineEdit->setText( FString("EnTry").toLower()); MyLineEdit->setText( FString("EnTry").toLower());
@ -325,6 +346,7 @@ MyDialog::MyDialog (FWidget* parent)
MyLineEdit->setStatusbarMessage("Press Enter to set the title"); MyLineEdit->setStatusbarMessage("Press Enter to set the title");
MyLineEdit->setShadow(); MyLineEdit->setShadow();
// Buttons
FButton* MyButton4 = new FButton(this); FButton* MyButton4 = new FButton(this);
MyButton4->setGeometry(20, 8, 12, 1); MyButton4->setGeometry(20, 8, 12, 1);
MyButton4->setText(L"&Get input"); MyButton4->setText(L"&Get input");
@ -346,6 +368,7 @@ MyDialog::MyDialog (FWidget* parent)
MyButton6->setShadow(); MyButton6->setShadow();
MyButton6->addAccelerator('x'); MyButton6->addAccelerator('x');
// A multiple selection listbox
myList = new FListBox(this); myList = new FListBox(this);
myList->setGeometry(38, 1, 14, 17); myList->setGeometry(38, 1, 14, 17);
myList->setText("Items"); myList->setText("Items");
@ -354,6 +377,7 @@ MyDialog::MyDialog (FWidget* parent)
for (int z=1; z < 100; z++) for (int z=1; z < 100; z++)
myList->insert( FString().setNumber(z) + L" placeholder" ); myList->insert( FString().setNumber(z) + L" placeholder" );
// Text labels
FLabel* headline = new FLabel(this); FLabel* headline = new FLabel(this);
headline->setGeometry(21, 3, 10, 1); headline->setGeometry(21, 3, 10, 1);
headline->setText(L"List items"); headline->setText(L"List items");
@ -375,11 +399,14 @@ MyDialog::MyDialog (FWidget* parent)
sum_count->setGeometry(29, 5, 5, 3); sum_count->setGeometry(29, 5, 5, 3);
sum_count->setNumber(myList->count()); sum_count->setNumber(myList->count());
// Statusbar at the bottom
FStatusBar* statusbar = new FStatusBar(this); FStatusBar* statusbar = new FStatusBar(this);
// Statusbar keys
FStatusKey* key_F1 = new FStatusKey(fc::Fkey_f1, "About", statusbar); FStatusKey* key_F1 = new FStatusKey(fc::Fkey_f1, "About", statusbar);
FStatusKey* key_F2 = new FStatusKey(fc::Fkey_f2, "View", statusbar); FStatusKey* key_F2 = new FStatusKey(fc::Fkey_f2, "View", statusbar);
FStatusKey* key_F3 = new FStatusKey(fc::Fkey_f3, "Quit", statusbar); FStatusKey* key_F3 = new FStatusKey(fc::Fkey_f3, "Quit", statusbar);
// Add some function callbacks
MyButton1->addCallback MyButton1->addCallback
( (
"clicked", "clicked",