menu_window.cpp

来自「ncbi源码」· C++ 代码 · 共 1,678 行 · 第 1/4 页

CPP
1,678
字号
    bool b_pushed = false;    if(x_IsSubMenuPushed()) {        b_focused = (m_Selected == &item)  &&  item.IsEnabled();    } else if(x_IsItemPushed())   {        b_focused = (m_Selected != m_PushedItem)  &&  (m_PushedItem == &item);        b_pushed = (m_Selected == m_PushedItem)  && (m_PushedItem == &item);    } else {        b_focused = (m_Selected == &item)  &&              (! x_IsHorizontal()  ||  Fl::belowmouse() == &GetWidget() ||  x_IsKeyActivated());    }    bool b_check = item.IsChecked()  ||  item.IsRadioSelected(); // item checked        Fl_Color back_color = FL_RED;     if(b_focused  ||  b_pushed)   { // draw focused item with frame                EColorType color = (x_IsHorizontal()  &&  item.IsSubmenu())                            ? (m_PushedItem ? ePopupBack : eFocusedBack)                            : (b_pushed ? ePushedBack : eFocusedBack);        back_color = sm_Props.GetColor(color);        fl_color(back_color);        fl_rectf(x, y, w, h);        // draw focused frame        fl_color(sm_Props.GetColor(x_IsItemPushed() ? eFocusedFrame : eFrame));        fl_rect(x, y, w, h);    } else { // draw unfocused item                back_color = sm_Props.GetColor(m_BackColor);        if(x_IsHorizontal())    {                if(b_check)    {                fl_color(sm_Props.GetColor(eCheckedBack));                fl_rectf(x, y, w, h);                fl_color(sm_Props.GetColor(eFocusedFrame));                fl_rect(x, y, w, h);            } else {                                fl_color(back_color);                fl_rectf(x, y, w, h);            }                    } else {                        fl_color(back_color);            fl_rectf(x + icon_w, y, w - icon_w, h); // fill text background            back_color = sm_Props.GetColor(eIconArea);            fl_color(back_color);                        fl_rectf(x, y, icon_w, h); // draw icon placeholder        }     }    int y_c = y + h / 2;                if(item.IsSeparator())  { //draw separation line                fl_color(sm_Props.GetColor(eDisabledText));            if(x_IsHorizontal())    {            int x_c = x + w / 2;            fl_line(x_c, y + 1, x_c, y + h - 2); // horz line        } else {            fl_line(x + icon_w + 1, y_c, x + w - 2, y_c); // vert line        }    } else {          // draw Icon        int x_off = x_IsHorizontal() ? (item.IsItem() ? kItemOffsetX : kSubmenuOffsetX)                                     : kSpace;        x_DrawItemIcon(entry, x + x_off, y_c - m_IconSize / 2, back_color);                 // draw Label adn Accelerator Label        EColorType text_color = b_focused ? eFocusedDisabledText : eDisabledText;        if(item.IsEnabled())    {            text_color = b_pushed ? ePushedText : eText;        }        fl_color(sm_Props.GetColor(text_color));        int text_off = x_off;        if(x_IsHorizontal())    {            text_off += b_icon ? (icon_w + kSpace) : 0;        } else {            text_off = icon_w + kSpace * 2;        }            x_DrawItemText(entry, x + text_off, y, w, h);                      // draw submenu marker        if(! x_IsHorizontal()  &&  item.IsSubmenu())    {             int N = kSubMarkerH / 2;            int m_x = x + (w - 1) - kSubMarkerOffset;            int y_c = y + h / 2;                        fl_color(sm_Props.GetColor(eText));            for( int i = 0; i <= N; i++ )    { // draw triangle as series of lines                fl_line(m_x - i, y_c - i, m_x - i, y_c + i);            }        }    }}/// draws item's label and accelerator label (if any)void    CMenu::x_DrawItemText(const CMenu::SItemEntry& entry, int x, int y, int w, int h){        const CMenuItem& item = *entry.m_Item;    const string& text = item.GetLabel();    int text_x = x;    int y_c = y + h / 2;    int text_y = y_c + fl_height() / 2 - 2;       int label_len = 0;    string::size_type pos = text.find(kAccessKeyMarker); // find accelerator marker    if(pos != string::npos  &&  pos + 1 < text.size())   { // there is an accelerator                int line_x = text_x;        if(pos > 0) {            fl_draw(text.c_str(), pos, text_x, text_y); // draw all the text before marker            line_x += (int) ceil(fl_width(text.c_str(), pos));        }                int line_len = (int) ceil(fl_width(text.c_str() + pos + 1, 1));        fl_draw(text.c_str() + pos + 1, line_x, text_y); // draw text after Marker                int line_y = text_y + 2;        fl_line(line_x, line_y, line_x + line_len - 1, line_y); // draw Underscore    }    else { // no accelerator - draw plain text        fl_draw(text.c_str(), text_x, text_y);    }    // draw accelerator label    if(! x_IsHorizontal())  {        int len = (int) ceil(fl_width(entry.m_AccelLabel.c_str()));        fl_draw(entry.m_AccelLabel.c_str(), x + m_MaxLabelW - len, text_y);    }}void    CMenu::x_DrawItemIcon(CMenu::SItemEntry& entry, int x, int y, Fl_Color back_color){    CMenuItem& item = *entry.m_Item;    CFLTKImageHandle hIcon;    if(item.IsChecked())    {        hIcon = m_hCheckIcon;    } else if(item.IsRadioSelected())    {        hIcon = m_hRadioIcon;    } else {        hIcon = entry.m_hIcon;                }    if(hIcon) { //draw icon if any        Fl_Image* image = &(*hIcon);        bool disabled = ! item.IsEnabled();        CPNGImageExt* ext_image = dynamic_cast<CPNGImageExt*>(image);        if(ext_image)   {            ext_image->DrawTransparent(back_color, x, y, m_IconSize, m_IconSize, disabled);        } else {            if(disabled)    {                image = image->copy();                image->inactive();            }            image->draw(x, y, m_IconSize, m_IconSize);            if(disabled)    {                delete image;            }        }    } }void    CMenu::x_MeasureItem(const SItemEntry& entry, int& text_w) const{    CMenuItem& item = *entry.m_Item;    if(item.IsSeparator())  {        text_w = 0;    } else {        fl_font(sm_Props.m_FontType, sm_Props.m_FontSize);        const string& text = item.GetLabel();        text_w = (int) ceil(fl_width(text.c_str()));        string::size_type pos = text.find(kAccessKeyMarker); // find accelerator marker        if(pos != string::npos  &&  pos + 1 < text.size())   { // there is an accelerator                    text_w -= (int) ceil(fl_width("&"));        }        if(! x_IsHorizontal())  {            // measure accelerator label            text_w += kAccelSpace;            text_w += (int) ceil(fl_width(entry.m_AccelLabel.c_str()));        }    }}CRect    CMenu::x_GetPopupItemRect(const CMenuItem& r_item){    bool b_horz = x_IsHorizontal();    int pos = m_Border;    if(m_RootItem) {             for( size_t i = 0;  i < m_Entries.size();  i++  )  {            const CMenuItem* item = m_Entries[i].m_Item;            int size = m_Entries[i].m_Size;                        if(item == &r_item)    { // found r_item                if(b_horz)  {                    return CRect(pos, m_Border, pos + size - 1, m_Height - m_Border - 1);                } else {                    return CRect(m_Border, pos, m_Width - m_Border - 1, pos + size - 1);                }                break;            } else {                pos += size;            }        }    }    return CRect(0, 0);}// returns item containing (x, y) pointCMenuItem*      CMenu::x_HitTest(int x, int y){        Fl_Widget& wid = GetWidget();    bool b_horz = x_IsHorizontal();        // to local coords    x -= wid.x();    y -= wid.y();    int i_x = m_Border;    int i_y = m_Border;                bool b_hit_rect = (b_horz && y >= m_Border  &&  y < m_Border + m_Height)                         || (! b_horz  &&  x >= m_Border  &&  x < m_Border + m_Width);    if(b_hit_rect  &&  m_RootItem) {        fl_font(sm_Props.m_FontType, sm_Props.m_FontSize);        int i = 0;        for( CMenuItem::TChildItem_I it =  m_RootItem->SubItemsBegin();                                   it != m_RootItem->SubItemsEnd(); ++it, i++  ) {            CMenuItem& item = *(*it)->GetValue();            int size = m_Entries[i].m_Size;            if(b_horz)  {                if(x >= i_x  &&  x < i_x + size)  {                    return &item;                } else  i_x += size;            } else {                if(y >= i_y  &&  y < i_y + size)  {                    return &item;                } else  i_y += size;            }        }    }    return NULL;}void    CMenu::x_ExecuteCommand(const CMenuItem& item){    if(item.IsEnabled()  &&  item.IsItem())  {        TCmdID cmd = item.GetCommand();                if(GetCmdTarget())  {            GetCmdTarget()->OnCommand(cmd);        } else {            ERR_POST("CMenu - cannot execute command, not command target specified");        }    }     }void    WidgetToScreen(const Fl_Widget& widget, int& wx, int& wy){    for( Fl_Window* w = widget.window(); w; w = w->window())   {        wx += w->x();        wy += w->y();    } }////////////////////////////////////////////////////////////////////////////////// CMenuCmdUICMenuCmdUI::CMenuCmdUI(CMenuItem& item): m_Item(item){}TCmdID  CMenuCmdUI::GetCommand() const{    return m_Item.GetCommand();}void    CMenuCmdUI::Enable(bool en){    m_Item.Enable(en);}void    CMenuCmdUI::SetCheck(bool set){    m_Item.SetCheck(set);}void    CMenuCmdUI::SetRadio(bool set){    m_Item.SelectRadio(set);}void    CMenuCmdUI::SetLabel(const string& label){    m_Item.SetLabel(label);}////////////////////////////////////////////////////////////////////////////////// CPopupMenu1CPopupMenu1::TPopupVector    CPopupMenu1::sm_Popups;CMenuItem*      CPopupMenu1::sm_CurrItem = NULL;CPopupMenu1*    CPopupMenu1::sm_CurrPopup = NULL;CPopupMenu1::EState          CPopupMenu1::sm_State;bool            CPopupMenu1::sm_bMenubar;CPopupMenu1::CPopupMenu1(int x, int y, CMenuItem* root_item,                          CCommandTarget* target, IMenuHintListener* listener):   TPopupMenuParent(x, y, 0, 0){    x_Init(x, y, x, y, root_item, target, listener, true);}CPopupMenu1::CPopupMenu1(int x, int y, const SMenuItemRec* items,                          CCommandTarget* target, IMenuHintListener* listener):   TPopupMenuParent(x, y, 0, 0){    CMenuItem* root_item = CreateMenuItems(items);    x_Init(x, y, x, y, root_item, target, listener, true);}// this is a protected constructor used only within CMenu subsystem// creates a child popup menu. CPopupMenu1::CPopupMenu1(int x, int y, int left, int top, CMenuItem* root_item,                         CCommandTarget* target, IMenuHintListener* listener):   TPopupMenuParent(x, y, 0, 0){      x_Init(x, y, left, top, root_item, target, listener, false);}void    CPopupMenu1::x_Init(int x, int y, int left, int top, CMenuItem* root_item,                             CCommandTarget* target, IMenuHintListener* listener, bool root_popup){    m_MenuBar = NULL; // popup mode    position(x, y);    m_Left = left;    m_Top = top;        m_bSkipFirstRelease = root_popup;        m_Cmd = eCmdInvalid;    m_Border = kBorderSize;     m_BackColor = ePopupBack;  // override standard color      end(); // prevent adding child widgets    set_modal();        clear_border(); // hide frame    x_SetItems(root_item, root_popup); // own items only if this is a root popup menu    SetCmdTarget(target);    SetHintListener(listener);}/// Creates root popup menu stub for a menubarCPopupMenu1::CPopupMenu1(CMenuBar1& menubar, CMenuItem* root_item, CMenuItem* sel_item,                         IMenuHintListener* listener):   TPopupMenuParent(0, 0, 0, 0),    m_Left(0), m_Top(0),    m_MenuBar(&menubar),    m_bSkipFirstRelease(true),    m_Cmd(eCmdInvalid){    end(); // prevent adding child widgets    set_modal();        clear_border(); // hide frame        m_Border = m_MenuBar->GetBorder();        m_bKeyActivated = menubar.m_bKeyActivated;    x_SetItems(root_item, false); // share items with the caller    SetSelected(sel_item);    SetHintListener(listener);}void    CPopupMenu1::x_AdjustRectangle(){    if(m_MenuBar)    {            CRect rc = m_MenuBar->GetPopupRect();                const Fl_Widget& wid = m_MenuBar->GetWidget();        int x = 0, y = 0;        WidgetToScreen(wid, x,y); // upper-left corner to screen coords        rc.Offset(x, y);        resize(rc.Left(), rc.Top(), rc.Width(), rc.Height());    } else {        // adjsut size        TPopupMenuParent::size(m_Width, m_Height);            int X = x(), Y = y();        //adjust position on screen        if(X + m_Width > Fl::w())  { // not enough space to the right            if(m_Left == X)   {                X = Fl::w() - m_Width;            } else  {                X = m_Left - (m_Width -1); // place to the left            }        }        X = max(X, 0);        x(X);            if(Y + m_Height > Fl::h())   { // not enought space to the bottom            if(m_Top == Y)    {                Y = Fl::h() - m_Height; // scroll up            } else  {                Y = m_Top - (m_Height - 1); // flip up            }        }        Y = max(Y, 0);        y(Y);    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?