diff --git a/ChangeLog b/ChangeLog index 96ff4d85..b85cbec4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,13 @@ -2017-12-21 Markus Gans +2017-12-27 Markus Gans + * Refactoring FLineEdit::onKeyPress + * Refactoring FMenu::onKeyPress + * Refactoring FDialog::onKeyPress + * Refactoring FDialog::drawTitleBar + * New FDialog methods moveUp(), moveDown(), moveLeft(), + moveRight(), reduceHeight(), expandHeight(), reduceWidth(), + and expandWidth() + +2017-12-25 Markus Gans * Refactoring FButton::draw * Passing more strings by reference diff --git a/include/final/fbutton.h b/include/final/fbutton.h index 11d757b4..637d5244 100644 --- a/include/final/fbutton.h +++ b/include/final/fbutton.h @@ -180,7 +180,7 @@ class FButton : public FWidget uChar non_flat_shadow : 1; uChar no_underline : 1; uChar : 2; // padding bits - } is; + } is; }; #pragma pack(pop) diff --git a/include/final/fdialog.h b/include/final/fdialog.h index d89876af..663ca208 100644 --- a/include/final/fdialog.h +++ b/include/final/fdialog.h @@ -118,7 +118,15 @@ class FDialog : public FWindow int exec(); void setPos (int, int, bool = true); void move (int, int); + bool moveUp (int); + bool moveDown (int); + bool moveLeft (int); + bool moveRight (int); void setSize (int, int, bool = true); + bool reduceHeight (int); + bool expandHeight (int); + bool reduceWidth (int); + bool expandWidth (int); void activateDialog(); // Event handlers @@ -145,6 +153,10 @@ class FDialog : public FWindow virtual void onClose (FCloseEvent*); private: + // Constant + static const int MENU_BTN = 3; + static const bool PRINT_WIN_NUMBER = false; // Only for debug + // Using-declaration using FWidget::drawBorder; @@ -158,10 +170,16 @@ class FDialog : public FWindow void init(); virtual void drawBorder(); void drawTitleBar(); + void drawBarButton(); + void drawZoomButton(); + void drawTextBar(); void leaveMenu(); void openMenu(); void selectFirstMenuItem(); void setZoomItem(); + void moveSizeKey (FKeyEvent*); + void acceptMoveSize(); + void cancelMoveSize(); static void addDialog (FWidget*); static void delDialog (FWidget*); @@ -175,6 +193,8 @@ class FDialog : public FWindow int result_code; bool zoom_button_pressed; bool zoom_button_active; + bool setPos_error; + bool setSize_error; FPoint titlebar_click_pos; FPoint resize_click_pos; FRect save_geometry; // required by keyboard move/size diff --git a/include/final/flineedit.h b/include/final/flineedit.h index 4c68bb63..77a4a94c 100644 --- a/include/final/flineedit.h +++ b/include/final/flineedit.h @@ -155,6 +155,15 @@ class FLineEdit : public FWidget bool hasHotkey(); void draw(); void drawInputField(); + void keyLeft(); + void keyRight(); + void keyHome(); + void keyEnd(); + void keyDel(); + void keyBackspace(); + void keyInsert(); + void keyEnter(); + bool keyInput (int); void processActivate(); void processChanged(); diff --git a/include/final/fmenu.h b/include/final/fmenu.h index a5cd3a7f..f94cf1b1 100644 --- a/include/final/fmenu.h +++ b/include/final/fmenu.h @@ -191,8 +191,8 @@ class FMenu : public FWindow, public FMenuList FMenu* superMenuAt (int, int); bool selectNextItem(); bool selectPrevItem(); - void keypressMenuBar (FKeyEvent*&); - bool hotkeyMenu (FKeyEvent*&); + void keypressMenuBar (FKeyEvent*); + bool hotkeyMenu (FKeyEvent*); int getHotkeyPos (wchar_t[], wchar_t[], uInt); void draw(); void drawItems(); @@ -205,6 +205,12 @@ class FMenu : public FWindow, public FMenuList void drawTrailingSpaces (int); void setLineAttributes (FMenuItem*, int); void setCursorToHotkeyPosition (FMenuItem*); + void keyUp(); + void keyDown(); + void keyLeft (FKeyEvent*); + void keyRight (FKeyEvent*); + void keyEnter(); + void keyEscape(); void processActivate(); // Friend classes diff --git a/include/final/fterm.h b/include/final/fterm.h index 12bb6cf3..02ee3bdf 100644 --- a/include/final/fterm.h +++ b/include/final/fterm.h @@ -414,6 +414,16 @@ class FTerm uChar blue; } dacreg; + typedef struct + { + char* string1; + char* string2; + char* string3; + char* string4; + char* string5; + char* string6; + } colorEnv; + // Constants static const int NEED_MORE_DATA = -1; // parseKeyString return value @@ -483,6 +493,8 @@ class FTerm static void init_global_values(); static void detectTerminal(); static void termtypeAnalysis(); + static bool get256colorEnvString (colorEnv&); + static char* termtype_256color_quirks (colorEnv&); static char* init_256colorTerminal(); static char* determineMaxColor (char[]); static char* parseAnswerbackMsg (char[]); diff --git a/src/fbutton.cpp b/src/fbutton.cpp index 669ca387..40b98eaa 100644 --- a/src/fbutton.cpp +++ b/src/fbutton.cpp @@ -690,7 +690,7 @@ inline void FButton::drawButtonTextLine (wchar_t button_text[]) if ( ! is.active && isMonochron() ) setReverse(true); // Light background - + if ( is.active_focus && (isMonochron() || getMaxColor() < 16) ) setBold(); @@ -760,12 +760,12 @@ void FButton::draw() if ( isMonochron() ) setReverse(true); // Light background - // Click animation preprocessing + // Click animation preprocessing indent = clickAnimationIndent (parent_widget); // Clear right margin after animation clearRightMargin (parent_widget); - + if ( ! is.active && isMonochron() ) space = fc::MediumShade; // ▒ simulates greyed out at Monochron diff --git a/src/fdialog.cpp b/src/fdialog.cpp index b3bc2093..677c3ea3 100644 --- a/src/fdialog.cpp +++ b/src/fdialog.cpp @@ -37,6 +37,8 @@ FDialog::FDialog (FWidget* parent) , result_code(FDialog::Reject) , zoom_button_pressed(false) , zoom_button_active(false) + , setPos_error(false) + , setSize_error(false) , titlebar_click_pos() , resize_click_pos() , save_geometry() @@ -57,6 +59,8 @@ FDialog::FDialog (const FString& txt, FWidget* parent) , result_code(FDialog::Reject) , zoom_button_pressed(false) , zoom_button_active(false) + , setPos_error(false) + , setSize_error(false) , titlebar_click_pos() , resize_click_pos() , save_geometry() @@ -199,19 +203,29 @@ void FDialog::setPos (int x, int y, bool) { int rsw, bsh, width, height; FRect old_geometry; + setPos_error = false; if ( getX() == x && getY() == y ) + { + setPos_error = true; return; + } width = getWidth(); height = getHeight(); // Avoid to move widget completely outside the terminal if ( x + width <= 1 || x > getMaxWidth() || y < 1 || y > getMaxHeight() ) + { + setPos_error = true; return; + } if ( isZoomed() ) + { + setPos_error = true; return; + } int dx = getX() - x , dy = getY() - y @@ -302,20 +316,55 @@ void FDialog::setPos (int x, int y, bool) } //---------------------------------------------------------------------- -void FDialog::move (int dx, int dy) +inline void FDialog::move (int dx, int dy) { setPos (getX() + dx, getY() + dy); } +//---------------------------------------------------------------------- +inline bool FDialog::moveUp (int n) +{ + move (0, -n); + return ! setPos_error; +} + +//---------------------------------------------------------------------- +inline bool FDialog::moveDown (int n) +{ + move (0, n); + return ! setPos_error; +} + +//---------------------------------------------------------------------- +inline bool FDialog::moveLeft (int n) +{ + move (-n, 0); + return ! setPos_error; +} + +//---------------------------------------------------------------------- +inline bool FDialog::moveRight (int n) +{ + move (n, 0); + return ! setPos_error; +} + //---------------------------------------------------------------------- void FDialog::setSize (int w, int h, bool adjust) { + setSize_error = false; if ( getWidth() == w && getHeight() == h ) + { + setSize_error = true; return; + } if ( isZoomed() ) + { + setSize_error = true; return; + } int x = getTermX() , y = getTermY() @@ -380,6 +429,46 @@ void FDialog::setSize (int w, int h, bool adjust) } } +//---------------------------------------------------------------------- +bool FDialog::reduceHeight (int n) +{ + if ( ! isResizeable() ) + return false; + + setSize (getWidth(), getHeight() - n); + return ! setSize_error; +} + +//---------------------------------------------------------------------- +bool FDialog::expandHeight (int n) +{ + if ( ! isResizeable() || getHeight() + getY() > getMaxHeight() ) + return false; + + setSize (getWidth(), getHeight() + n); + return ! setSize_error; +} + +//---------------------------------------------------------------------- +bool FDialog::reduceWidth (int n) +{ + if ( ! isResizeable() ) + return false; + + setSize (getWidth() - n, getHeight()); + return ! setSize_error; +} + +//---------------------------------------------------------------------- +bool FDialog::expandWidth (int n) +{ + if ( ! isResizeable() || getWidth() + getX() > getMaxWidth() ) + return false; + + setSize (getWidth() + n, getHeight()); + return ! setSize_error; +} + //---------------------------------------------------------------------- void FDialog::activateDialog() { @@ -437,98 +526,7 @@ void FDialog::onKeyPress (FKeyEvent* ev) } if ( getMoveSizeWidget() ) - { - switch ( ev->key() ) - { - case fc::Fkey_up: - move (0, -1); - ev->accept(); - break; - - case fc::Fkey_down: - move (0, 1); - ev->accept(); - break; - - case fc::Fkey_left: - move (-1, 0); - ev->accept(); - break; - - case fc::Fkey_right: - move (1, 0); - ev->accept(); - break; - - case fc::Fmkey_up: - case fc::Fkey_sr: - if ( isResizeable() ) - { - setSize (getWidth(), getHeight() - 1); - ev->accept(); - } - break; - - case fc::Fmkey_down: - case fc::Fkey_sf: - if ( isResizeable() && getHeight() + getY() <= getMaxHeight() ) - { - setSize (getWidth(), getHeight() + 1); - ev->accept(); - } - break; - - case fc::Fmkey_left: - case fc::Fkey_sleft: - if ( isResizeable() ) - { - setSize (getWidth() - 1, getHeight()); - ev->accept(); - } - break; - - case fc::Fmkey_right: - case fc::Fkey_sright: - if ( isResizeable() && getWidth() + getX() <= getMaxWidth() ) - { - setSize (getWidth() + 1, getHeight()); - ev->accept(); - } - break; - - case fc::Fkey_return: - case fc::Fkey_enter: - setMoveSizeWidget(0); - - if ( tooltip ) - delete tooltip; - - tooltip = 0; - redraw(); - ev->accept(); - break; - - case fc::Fkey_escape: - case fc::Fkey_escape_mintty: - setMoveSizeWidget(0); - - if ( tooltip ) - delete tooltip; - - tooltip = 0; - setPos (save_geometry.getPos()); - - if ( isResizeable() ) - setSize (save_geometry.getWidth(), save_geometry.getHeight()); - - redraw(); - ev->accept(); - return; - - default: - break; - } - } + moveSizeKey(ev); if ( this == getMainWidget() ) return; @@ -1226,13 +1224,30 @@ void FDialog::drawBorder() //---------------------------------------------------------------------- void FDialog::drawTitleBar() { - static const int menu_btn = 3; - int i - , x - , length - , zoom_btn; + // Draw the title button + drawBarButton(); + // Print the text bar + drawTextBar(); + // Draw the zoom/unzoom button + drawZoomButton(); - // draw the title button + if ( isMonochron() ) + setReverse(false); + +#if DEBUG + if ( PRINT_WIN_NUMBER ) + { + // Print the number of window in stack + setPrintPos (getWidth() - 2, 1); + printf ("(%d)", getWindowLayer(this)); + } +#endif +} + +//---------------------------------------------------------------------- +void FDialog::drawBarButton() +{ + // Print the title button setPrintPos (1, 1); if ( dialog_menu && dialog_menu->isVisible() ) @@ -1277,8 +1292,78 @@ void FDialog::drawTitleBar() print (' '); } +} +//---------------------------------------------------------------------- +void FDialog::drawZoomButton() +{ + // Draw the zoom/unzoom button + + if ( ! isResizeable() ) + return; + + if ( zoom_button_pressed ) + setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg); + else + setColor (wc.titlebar_button_fg, wc.titlebar_button_bg); + + if ( isZoomed() ) + { + if ( isNewFont() ) + { + print (fc::NF_rev_down_pointing_triangle1); + print (fc::NF_rev_down_pointing_triangle2); + } + else + { + if ( isMonochron() ) + { + print ('['); + print (fc::BlackDownPointingTriangle); // ▼ + print (']'); + } + else + { + print (' '); + print (fc::BlackDownPointingTriangle); // ▼ + print (' '); + } + } + } + else // is not zoomed + { + if ( isNewFont() ) + { + print (fc::NF_rev_up_pointing_triangle1); + print (fc::NF_rev_up_pointing_triangle2); + } + else + { + if ( isMonochron() ) + { + print ('['); + print (fc::BlackUpPointingTriangle); // ▲ + print (']'); + } + else + { + print (' '); + print (fc::BlackUpPointingTriangle); // ▲ + print (' '); + } + } + } +} + +//---------------------------------------------------------------------- +void FDialog::drawTextBar() +{ // fill with spaces (left of the title) + int center_offset + , zoom_btn + , length + , x; + if ( getMaxColor() < 16 ) setBold(); @@ -1295,21 +1380,20 @@ void FDialog::drawTitleBar() zoom_btn = 3; length = int(tb_text.getLength()); - i = getWidth() - length - menu_btn - zoom_btn; - i = int(i/2); + center_offset = int((getWidth() - length - MENU_BTN - zoom_btn) / 2); - for (x = 1; x <= i; x++) + for (x = 1; x <= center_offset; x++) print (' '); // Print title bar text if ( tb_text ) { - if ( length <= getWidth() - menu_btn - zoom_btn ) + if ( length <= getWidth() - MENU_BTN - zoom_btn ) print (tb_text); else { // Print ellipsis - print (tb_text.left(getWidth() - menu_btn - zoom_btn - 2)); + print (tb_text.left(getWidth() - MENU_BTN - zoom_btn - 2)); print (".."); } } @@ -1320,69 +1404,6 @@ void FDialog::drawTitleBar() if ( getMaxColor() < 16 ) unsetBold(); - - // Draw the zoom/unzoom button - if ( isResizeable() ) - { - if ( zoom_button_pressed ) - setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg); - else - setColor (wc.titlebar_button_fg, wc.titlebar_button_bg); - - if ( isZoomed() ) - { - if ( isNewFont() ) - { - print (fc::NF_rev_down_pointing_triangle1); - print (fc::NF_rev_down_pointing_triangle2); - } - else - { - if ( isMonochron() ) - { - print ('['); - print (fc::BlackDownPointingTriangle); // ▼ - print (']'); - } - else - { - print (' '); - print (fc::BlackDownPointingTriangle); // ▼ - print (' '); - } - } - } - else // is not zoomed - { - if ( isNewFont() ) - { - print (fc::NF_rev_up_pointing_triangle1); - print (fc::NF_rev_up_pointing_triangle2); - } - else - { - if ( isMonochron() ) - { - print ('['); - print (fc::BlackUpPointingTriangle); // ▲ - print (']'); - } - else - { - print (' '); - print (fc::BlackUpPointingTriangle); // ▲ - print (' '); - } - } - } - } - - if ( isMonochron() ) - setReverse(false); - -/* Print the number of window in stack */ -//setPrintPos (getWidth() - 2, 1); -//printf ("(%d)", getWindowLayer(this)); } //---------------------------------------------------------------------- @@ -1466,6 +1487,101 @@ void FDialog::setZoomItem() } } +//---------------------------------------------------------------------- +inline void FDialog::moveSizeKey (FKeyEvent* ev) +{ + switch ( ev->key() ) + { + case fc::Fkey_up: + if ( moveUp(1) ) + ev->accept(); + break; + + case fc::Fkey_down: + if ( moveDown(1) ) + ev->accept(); + break; + + case fc::Fkey_left: + if ( moveLeft(1) ) + ev->accept(); + break; + + case fc::Fkey_right: + if ( moveRight(1) ) + ev->accept(); + break; + + case fc::Fmkey_up: + case fc::Fkey_sr: + if ( reduceHeight(1) ) + ev->accept(); + break; + + case fc::Fmkey_down: + case fc::Fkey_sf: + if ( expandHeight(1) ) + ev->accept(); + break; + + case fc::Fmkey_left: + case fc::Fkey_sleft: + if ( reduceWidth(1) ) + ev->accept(); + break; + + case fc::Fmkey_right: + case fc::Fkey_sright: + if ( expandWidth(1) ) + ev->accept(); + break; + + case fc::Fkey_return: + case fc::Fkey_enter: + acceptMoveSize(); + ev->accept(); + break; + + case fc::Fkey_escape: + case fc::Fkey_escape_mintty: + cancelMoveSize(); + ev->accept(); + return; + + default: + break; + } +} + +//---------------------------------------------------------------------- +inline void FDialog::acceptMoveSize() +{ + setMoveSizeWidget(0); + + if ( tooltip ) + delete tooltip; + + tooltip = 0; + redraw(); +} + +//---------------------------------------------------------------------- +inline void FDialog::cancelMoveSize() +{ + setMoveSizeWidget(0); + + if ( tooltip ) + delete tooltip; + + tooltip = 0; + setPos (save_geometry.getPos()); + + if ( isResizeable() ) + setSize (save_geometry.getWidth(), save_geometry.getHeight()); + + redraw(); +} + //---------------------------------------------------------------------- void FDialog::addDialog (FWidget* obj) { diff --git a/src/flineedit.cpp b/src/flineedit.cpp index a01b028b..183289fe 100644 --- a/src/flineedit.cpp +++ b/src/flineedit.cpp @@ -340,97 +340,49 @@ void FLineEdit::clear() //---------------------------------------------------------------------- void FLineEdit::onKeyPress (FKeyEvent* ev) { - int len = int(text.getLength()); int key = ev->key(); switch ( key ) { case fc::Fkey_left: - cursor_pos--; - - if ( cursor_pos < 0 ) - cursor_pos = 0; - - if ( cursor_pos < text_offset ) - text_offset--; - + keyLeft(); ev->accept(); break; case fc::Fkey_right: - cursor_pos++; - - if ( cursor_pos >= len ) - cursor_pos = len; - - if ( cursor_pos - text_offset >= getWidth() - 2 - && text_offset <= len - getWidth() + 1 ) - text_offset++; - + keyRight(); ev->accept(); break; case fc::Fkey_home: - cursor_pos = 0; - text_offset = 0; + keyHome(); ev->accept(); break; case fc::Fkey_end: - cursor_pos = len; - if ( cursor_pos >= getWidth() - 1 ) - text_offset = len - getWidth() + 2; + keyEnd(); ev->accept(); break; case fc::Fkey_dc: // del key - if ( len > 0 && cursor_pos < len ) - { - text.remove(uInt(cursor_pos), 1); - processChanged(); - } - - if ( cursor_pos >= len ) - cursor_pos = len; - - if ( cursor_pos < 0 ) - cursor_pos = 0; - - if ( text_offset > 0 && len - text_offset < getWidth() - 1 ) - text_offset--; - + keyDel(); ev->accept(); break; case fc::Fkey_erase: case fc::Fkey_backspace: - if ( len > 0 && cursor_pos > 0 ) - { - text.remove(uInt(cursor_pos - 1), 1); - processChanged(); - cursor_pos--; - - if ( text_offset > 0 ) - text_offset--; - } - + keyBackspace(); ev->accept(); break; case fc::Fkey_ic: // insert key - insert_mode = not insert_mode; - - if ( insert_mode ) - setInsertCursorStyle(); - else - unsetInsertCursorStyle(); - + keyInsert(); ev->accept(); break; case fc::Fkey_return: case fc::Fkey_enter: - processActivate(); + keyEnter(); ev->accept(); break; @@ -439,36 +391,8 @@ void FLineEdit::onKeyPress (FKeyEvent* ev) break; default: - if ( key >= 0x20 && key <= 0x10fff ) - { - if ( cursor_pos == len ) - { - text += wchar_t(key); - processChanged(); - } - else if ( len > 0 ) - { - if ( insert_mode ) - text.insert(wchar_t(key), uInt(cursor_pos)); - else - text.overwrite(wchar_t(key), uInt(cursor_pos)); - - processChanged(); - } - else - { - text = wchar_t(key); - processChanged(); - } - cursor_pos++; - - if ( cursor_pos >= getWidth() - 1 ) - text_offset++; - + if ( keyInput(key) ) ev->accept(); - } - else - ev->ignore(); } // end of switch @@ -877,6 +801,138 @@ void FLineEdit::drawInputField() setCursorPos (2 + cursor_pos - text_offset, 1); } +//---------------------------------------------------------------------- +inline void FLineEdit::keyLeft() +{ + cursor_pos--; + + if ( cursor_pos < 0 ) + cursor_pos = 0; + + if ( cursor_pos < text_offset ) + text_offset--; +} + +//---------------------------------------------------------------------- +inline void FLineEdit::keyRight() +{ + int len = int(text.getLength()); + cursor_pos++; + + if ( cursor_pos >= len ) + cursor_pos = len; + + if ( cursor_pos - text_offset >= getWidth() - 2 + && text_offset <= len - getWidth() + 1 ) + text_offset++; +} + +//---------------------------------------------------------------------- +inline void FLineEdit::keyHome() +{ + cursor_pos = 0; + text_offset = 0; +} + +//---------------------------------------------------------------------- +inline void FLineEdit::keyEnd() +{ + int len = int(text.getLength()); + cursor_pos = len; + + if ( cursor_pos >= getWidth() - 1 ) + text_offset = len - getWidth() + 2; +} + +//---------------------------------------------------------------------- +inline void FLineEdit::keyDel() +{ + int len = int(text.getLength()); + + if ( len > 0 && cursor_pos < len ) + { + text.remove(uInt(cursor_pos), 1); + processChanged(); + } + + if ( cursor_pos >= len ) + cursor_pos = len; + + if ( cursor_pos < 0 ) + cursor_pos = 0; + + if ( text_offset > 0 && len - text_offset < getWidth() - 1 ) + text_offset--; +} + +//---------------------------------------------------------------------- +inline void FLineEdit::keyBackspace() +{ + if ( text.getLength() > 0 && cursor_pos > 0 ) + { + text.remove(uInt(cursor_pos - 1), 1); + processChanged(); + cursor_pos--; + + if ( text_offset > 0 ) + text_offset--; + } +} + +//---------------------------------------------------------------------- +inline void FLineEdit::keyInsert() +{ + insert_mode = not insert_mode; + + if ( insert_mode ) + setInsertCursorStyle(); + else + unsetInsertCursorStyle(); +} + +//---------------------------------------------------------------------- +inline void FLineEdit::keyEnter() +{ + processActivate(); +} + +//---------------------------------------------------------------------- +inline bool FLineEdit::keyInput (int key) +{ + if ( key >= 0x20 && key <= 0x10fff ) + { + int len = int(text.getLength()); + + if ( cursor_pos == len ) + { + text += wchar_t(key); + processChanged(); + } + else if ( len > 0 ) + { + if ( insert_mode ) + text.insert(wchar_t(key), uInt(cursor_pos)); + else + text.overwrite(wchar_t(key), uInt(cursor_pos)); + + processChanged(); + } + else + { + text = wchar_t(key); + processChanged(); + } + cursor_pos++; + + if ( cursor_pos >= getWidth() - 1 ) + text_offset++; + + return true; + } + else + return false; +} + //---------------------------------------------------------------------- void FLineEdit::processActivate() { diff --git a/src/fmenu.cpp b/src/fmenu.cpp index 88f2fda8..ac711c17 100644 --- a/src/fmenu.cpp +++ b/src/fmenu.cpp @@ -162,100 +162,30 @@ void FMenu::onKeyPress (FKeyEvent* ev) switch ( ev->key() ) { - case fc::Fkey_return: - case fc::Fkey_enter: - if ( hasSelectedItem() ) - { - FMenuItem* sel_item = getSelectedItem(); - - if ( sel_item->hasMenu() ) - openSubMenu (sel_item->getMenu(), SELECT_ITEM); - else - { - unselectItem(); - hide(); - hideSuperMenus(); - sel_item->processClicked(); - } - } - break; - case fc::Fkey_up: - selectPrevItem(); + keyUp(); break; case fc::Fkey_down: - selectNextItem(); + keyDown(); break; case fc::Fkey_left: - if ( isSubMenu() ) - { - FMenu* smenu = static_cast(getSuperMenu()); - hideSubMenus(); - hide(); - - if ( smenu->getSelectedItem() ) - smenu->getSelectedItem()->setFocus(); - - smenu->redraw(); - - if ( getStatusBar() ) - getStatusBar()->drawMessage(); - - updateTerminal(); - flush_out(); - } - else - keypressMenuBar(ev); // select previous menu + keyLeft(ev); break; case fc::Fkey_right: - if ( hasSelectedItem() && getSelectedItem()->hasMenu() ) - { - FMenu* sub_menu = getSelectedItem()->getMenu(); + keyRight(ev); + break; - if ( ! sub_menu->isVisible() ) - openSubMenu (sub_menu, SELECT_ITEM); - else - keypressMenuBar(ev); // select next menu - } - else - keypressMenuBar(ev); // select next menu + case fc::Fkey_return: + case fc::Fkey_enter: + keyEnter(); break; case fc::Fkey_escape: case fc::Fkey_escape_mintty: - unselectItem(); - hideSubMenus(); - hide(); - - if ( isSubMenu() ) - { - FMenu* smenu = static_cast(getSuperMenu()); - - if ( smenu->getSelectedItem() ) - smenu->getSelectedItem()->setFocus(); - - smenu->redraw(); - } - else - { - FWidget* super = getSuperMenu(); - hideSuperMenus(); - - if ( getStatusBar() ) - getStatusBar()->clearMessage(); - - if ( ! (super && isWindowsMenu(super)) ) - switchToPrevWindow(); - } - - if ( getStatusBar() ) - getStatusBar()->drawMessage(); - - updateTerminal(); - flush_out(); + keyEscape(); break; case fc::Fmkey_1: @@ -1230,7 +1160,7 @@ bool FMenu::selectPrevItem() } //---------------------------------------------------------------------- -void FMenu::keypressMenuBar (FKeyEvent*& ev) +void FMenu::keypressMenuBar (FKeyEvent* ev) { FMenuBar* mbar = getMenuBar(); @@ -1239,7 +1169,7 @@ void FMenu::keypressMenuBar (FKeyEvent*& ev) } //---------------------------------------------------------------------- -bool FMenu::hotkeyMenu (FKeyEvent*& ev) +bool FMenu::hotkeyMenu (FKeyEvent* ev) { std::vector::const_iterator iter, last; iter = item_list.begin(); @@ -1637,6 +1567,113 @@ inline void FMenu::setCursorToHotkeyPosition (FMenuItem* menuitem) } } +//---------------------------------------------------------------------- +inline void FMenu::keyUp() +{ + selectPrevItem(); +} + +//---------------------------------------------------------------------- +inline void FMenu::keyDown() +{ + selectNextItem(); +} + +//---------------------------------------------------------------------- +inline void FMenu::keyLeft (FKeyEvent* ev) +{ + if ( isSubMenu() ) + { + FMenu* smenu = static_cast(getSuperMenu()); + hideSubMenus(); + hide(); + + if ( smenu->getSelectedItem() ) + smenu->getSelectedItem()->setFocus(); + + smenu->redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + updateTerminal(); + flush_out(); + } + else + keypressMenuBar(ev); // select previous menu +} + +//---------------------------------------------------------------------- +inline void FMenu::keyRight (FKeyEvent* ev) +{ + if ( hasSelectedItem() && getSelectedItem()->hasMenu() ) + { + FMenu* sub_menu = getSelectedItem()->getMenu(); + + if ( ! sub_menu->isVisible() ) + openSubMenu (sub_menu, SELECT_ITEM); + else + keypressMenuBar(ev); // select next menu + } + else + keypressMenuBar(ev); // select next menu + +} + +//---------------------------------------------------------------------- +inline void FMenu::keyEnter() +{ + if ( ! hasSelectedItem() ) + return; + + FMenuItem* sel_item = getSelectedItem(); + + if ( sel_item->hasMenu() ) + openSubMenu (sel_item->getMenu(), SELECT_ITEM); + else + { + unselectItem(); + hide(); + hideSuperMenus(); + sel_item->processClicked(); + } +} + +//---------------------------------------------------------------------- +inline void FMenu::keyEscape() +{ + unselectItem(); + hideSubMenus(); + hide(); + + if ( isSubMenu() ) + { + FMenu* smenu = static_cast(getSuperMenu()); + + if ( smenu->getSelectedItem() ) + smenu->getSelectedItem()->setFocus(); + + smenu->redraw(); + } + else + { + FWidget* super = getSuperMenu(); + hideSuperMenus(); + + if ( getStatusBar() ) + getStatusBar()->clearMessage(); + + if ( ! (super && isWindowsMenu(super)) ) + switchToPrevWindow(); + } + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + updateTerminal(); + flush_out(); +} + //---------------------------------------------------------------------- void FMenu::processActivate() { diff --git a/src/foptiattr.cpp b/src/foptiattr.cpp index 0ced3efa..1891503c 100644 --- a/src/foptiattr.cpp +++ b/src/foptiattr.cpp @@ -546,7 +546,7 @@ char* FOptiAttr::changeAttribute (char_data*& term, char_data*& next) if ( cygwin_terminal && (term->fg_color > 7 || term->bg_color > 7) ) { // reset blink and bold mode from colors > 7 - char* rst = C_STR(CSI "m"); + char rst[] = CSI "m"; append_sequence (rst); reset(term); } @@ -1046,7 +1046,7 @@ bool FOptiAttr::setTermDefaultColor (char_data*& term) } else if ( ansi_default_color ) { - char* sgr_39_49 = C_STR(CSI "39;49m"); + char sgr_39_49[] = CSI "39;49m"; append_sequence (sgr_39_49); term->fg_color = Default; term->bg_color = Default; @@ -1302,7 +1302,7 @@ void FOptiAttr::change_color (char_data*& term, char_data*& next) } else if ( fg == Default && term->fg_color != Default ) { - char* sgr_39 = C_STR(CSI "39m"); + char sgr_39[] = CSI "39m"; append_sequence (sgr_39); term->fg_color = Default; } diff --git a/src/fterm.cpp b/src/fterm.cpp index b601241a..d4ac7c4c 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -2137,7 +2137,7 @@ int FTerm::getFramebuffer_bpp () //---------------------------------------------------------------------- int FTerm::openConsole() -{ +{ static const char* terminal_devices[] = { "/proc/self/fd/0", @@ -2852,89 +2852,108 @@ void FTerm::termtypeAnalysis() netbsd_terminal = false; } +//---------------------------------------------------------------------- +bool FTerm::get256colorEnvString(colorEnv& env) +{ + // Enable 256 color capabilities + env.string1 = std::getenv("COLORTERM"); + env.string2 = std::getenv("VTE_VERSION"); + env.string3 = std::getenv("XTERM_VERSION"); + env.string4 = std::getenv("ROXTERM_ID"); + env.string5 = std::getenv("KONSOLE_DBUS_SESSION"); + env.string6 = std::getenv("KONSOLE_DCOP"); + + if ( env.string1 != 0 ) + return true; + + if ( env.string2 != 0 ) + return true; + + if ( env.string3 != 0 ) + return true; + + if ( env.string4 != 0 ) + return true; + + if ( env.string5 != 0 ) + return true; + + if ( env.string6 != 0 ) + return true; + + return false; +} + +//---------------------------------------------------------------------- +char* FTerm::termtype_256color_quirks (colorEnv& env) +{ + char* new_termtype = 0; + + if ( ! color256 ) + return new_termtype; + + if ( std::strncmp(termtype, "xterm", 5) == 0 ) + new_termtype = C_STR("xterm-256color"); + + if ( std::strncmp(termtype, "screen", 6) == 0 ) + { + new_termtype = C_STR("screen-256color"); + screen_terminal = true; + char* tmux = std::getenv("TMUX"); + + if ( tmux && std::strlen(tmux) != 0 ) + tmux_terminal = true; + } + + if ( std::strncmp(termtype, "Eterm", 5) == 0 ) + new_termtype = C_STR("Eterm-256color"); + + if ( std::strncmp(termtype, "mlterm", 6) == 0 ) + { + new_termtype = C_STR("mlterm-256color"); + mlterm_terminal = true; + } + + if ( std::strncmp(termtype, "rxvt", 4) != 0 + && env.string1 + && std::strncmp(env.string1, "rxvt-xpm", 8) == 0 ) + { + new_termtype = C_STR("rxvt-256color"); + rxvt_terminal = true; + } + + if ( (env.string5 && std::strlen(env.string5) > 0) + || (env.string6 && std::strlen(env.string6) > 0) ) + kde_konsole = true; + + if ( (env.string1 && std::strncmp(env.string1, "gnome-terminal", 14) == 0) + || env.string2 ) + { + gnome_terminal = true; + // Each gnome-terminal should be able to use 256 colors + color256 = true; + + if ( ! screen_terminal ) + new_termtype = C_STR("gnome-256color"); + } + + return new_termtype; +} + //---------------------------------------------------------------------- char* FTerm::init_256colorTerminal() { - char local256[80] = ""; char* new_termtype = 0; - char *s1, *s2, *s3, *s4, *s5, *s6; - - // Enable 256 color capabilities - s1 = std::getenv("COLORTERM"); - s2 = std::getenv("VTE_VERSION"); - s3 = std::getenv("XTERM_VERSION"); - s4 = std::getenv("ROXTERM_ID"); - s5 = std::getenv("KONSOLE_DBUS_SESSION"); - s6 = std::getenv("KONSOLE_DCOP"); - - if ( s1 != 0 ) - std::strncat (local256, s1, sizeof(local256) - std::strlen(local256) - 1); - - if ( s2 != 0 ) - std::strncat (local256, s2, sizeof(local256) - std::strlen(local256) - 1); - - if ( s3 != 0 ) - std::strncat (local256, s3, sizeof(local256) - std::strlen(local256) - 1); - - if ( s4 != 0 ) - std::strncat (local256, s4, sizeof(local256) - std::strlen(local256) - 1); - - if ( s5 != 0 ) - std::strncat (local256, s5, sizeof(local256) - std::strlen(local256) - 1); - - if ( s6 != 0 ) - std::strncat (local256, s6, sizeof(local256) - std::strlen(local256) - 1); - - if ( std::strlen(local256) > 0 ) - { - if ( std::strncmp(termtype, "xterm", 5) == 0 ) - new_termtype = C_STR("xterm-256color"); - - if ( std::strncmp(termtype, "screen", 6) == 0 ) - { - new_termtype = C_STR("screen-256color"); - screen_terminal = true; - char* tmux = std::getenv("TMUX"); - - if ( tmux && std::strlen(tmux) != 0 ) - tmux_terminal = true; - } - - if ( std::strncmp(termtype, "Eterm", 5) == 0 ) - new_termtype = C_STR("Eterm-256color"); - - if ( std::strncmp(termtype, "mlterm", 6) == 0 ) - { - new_termtype = C_STR("mlterm-256color"); - mlterm_terminal = true; - } - - if ( std::strncmp(termtype, "rxvt", 4) != 0 - && s1 - && std::strncmp(s1, "rxvt-xpm", 8) == 0 ) - { - new_termtype = C_STR("rxvt-256color"); - rxvt_terminal = true; - } + colorEnv env; + if ( get256colorEnvString(env) ) color256 = true; - } else if ( std::strstr (termtype, "256color") ) color256 = true; else color256 = false; - if ( (s5 && std::strlen(s5) > 0) || (s6 && std::strlen(s6) > 0) ) - kde_konsole = true; - - if ( (s1 && std::strncmp(s1, "gnome-terminal", 14) == 0) || s2 ) - { - gnome_terminal = true; - // Each gnome-terminal should be able to use 256 colors - color256 = true; - if ( ! screen_terminal ) - new_termtype = C_STR("gnome-256color"); - } + new_termtype = termtype_256color_quirks(env); #if DEBUG if ( new_termtype )