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 + -
显示快捷键?