Is it easy to create GLUT pop-up menus for my OpenGL application? If yes, how?
Creating and using pop-up menus with GLUT is very simple. Here is a code sample that creates a pop-up menu with 4 options:
// Menu items
enum MENU_TYPE
{
MENU_FRONT,
MENU_SPOT,
MENU_BACK,
MENU_BACK_FRONT,
};
// Assign a default value
MENU_TYPE show = MENU_BACK_FRONT;
// Menu handling function declaration
void menu(int);
int main()
{
// ...
// Create a menu
glutCreateMenu(menu);
// Add menu items
glutAddMenuEntry("Show Front", MENU_FRONT);
glutAddMenuEntry("Show Back", MENU_BACK);
glutAddMenuEntry("Spotlight", MENU_SPOT);
glutAddMenuEntry("Blend 'em all", MENU_BACK_FRONT);
// Associate a mouse button with menu
glutAttachMenu(GLUT_RIGHT_BUTTON);
// ...
return;
}
// Menu handling function definition
void menu(int item)
{
switch (item)
{
case MENU_FRONT:
case MENU_SPOT:
case MENU_DEPTH:
case MENU_BACK:
case MENU_BACK_FRONT:
{
show = (MENU_TYPE) item;
}
break;
default:
{ /* Nothing */ }
break;
}
glutPostRedisplay();
return;
}
Related
I have a custom class, CustomButton that extends Fl_Button. On my screen there are a bunch of Fl_Input and CustomButton widgets that I want to be able to navigate between using a tab keypress. Tabbing between input fields works fine, but once a CustomButton gets focus, I can't seem to tab away from it.
Here's my handle function
int CustomButton::handle ( int event )
{
int is_event_handled = 0;
switch (event)
{
case FL_KEYBOARD:
// If the keypress was enter, toggle the button on/off
if (Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter)
{
// Do stuff...
}
is_event_handled = 1;
break;
case FL_FOCUS:
case FL_UNFOCUS:
// The default Fl_Button handling does not allow Focus/Unfocus
// for the button so mark the even as handled to skip the Fl_Button processing
is_event_handled = 1;
break;
default:
is_event_handled = 0;
break;
}
if ( is_event_handled == 1 ) return 1;
return Fl_Round_Button::handle ( event );
}
I am using fltk 1.1.10.
For a very simple, minimal example which demonstrates how to control the focus, please check the navigation.cxx test file.
Maybe your widget did get the focus (check this with Fl::focus()), but it does not show that up (you need to handle the FL_FOCUS and/or FL_UNFOCUS events)?
My problem was my CustomButton::handle() returning 1 after a FL_KEYBOARD event without actually using the tab key press.
Moving is_event_handled = 1 into the if statement lets me consume the FL_Enter keypress only and lets other widgets (i.e. the Fl_Group that controls navigation) take any other keypresses.
Alternatively get rid of the if and replace with something like
switch(Fl::event_key())
{
case FL_Enter:
case FL_KP_Enter:
// Do stuff
is_event_handled = 1;
break;
default:
is_event_handled = 0;
break;
}
I have an application with a ribbon UI. In this UI a button exists with a menu attached to it. What I wish to do is access the menu from the button handler to dynamically add and remove menu items.
void
CMyScrollView::OnMenuButtonHandler ()
{
// TODO: Add your command handler code here
CMFCRibbonBar *pRibbon = ((CMDIFrameWndEx*)GetTopLevelFrame())GetRibbonBar()
// Control ID_BTN_EDIT_MENU
// This where I would like to isolate and vary menu contents
}
In the CMainFRame window create a handler for the AFX_WM_ON_BEFORE_SHOW_RIBBON_ITEM_MENU message (ON_REGISTERED_MESSAGE).
Check for the Id of the button. Remove all previous items and add the one, you want.
LRESULT CMainFrame::OnBeforeShowRibbonItemMenu(WPARAM,LPARAM lp)
{
CMFCRibbonBaseElement *pElement = reinterpret_cast<CMFCRibbonBaseElement*>(lp);
// Try to get our menu button
switch (pElement->GetID())
{
case ID_RIBBON_DROPDOWN_BUTTON:
{
CMFCRibbonButton *pButton = DYNAMIC_DOWNCAST(CMFCRibbonButton, pElement);
if (pButton)
{
// MY_LIST copntains members with the ID and the text: m_uiCmdId, m_strTitle
const MY_LIST &list = ....;
if (list.size()!=0)
{
pButton->RemoveAllSubItems();
for (it = list.begin(); it!=list.end(); ++it)
pButton->AddSubItem(new CSomeKindOfRibbonButton(it->m_uiCmdId, it->m_strTitle));
}
}
...
I am pretty new to cocos2d-x.I have created a button and i wanted to change the state of the button when i tap the button . i am having trouble changing the state from play to pause similar to a music player.Below is the code.
void Gallery::buttonUI(Size visibleSize,Vec2 origin)
{
button = Button::create("play.png");
//button->loadTextures("pause.png","play.png","pause.png");
button->setPosition(Point((visibleSize.width/2)+origin.x,(visibleSize.height/2)+origin.y-80));
button->setContentSize(Size(100.0f, button->getVirtualRendererSize().height));
button->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
switch (type)
{
case Widget::TouchEventType::BEGAN:
break;
case Widget::TouchEventType::ENDED:
CCLOG("Characters: %c %c", 'a', 65);
if (!flag)
Gallery::pauseSong();
else
Gallery::resumeSong();
break;
default:
break;
}
});
this->addChild(button);
}
void Gallery::playSong()
{
CocosDenshion::SimpleAudioEngine::getInstance()->preloadBackgroundMusic("1.mp3");
CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic("1.mp3");
flag = false;
}
void Gallery::pauseSong()
{
CocosDenshion::SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
flag = true;
}
void Gallery::resumeSong()
{
CocosDenshion::SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
flag = false;
}
I don’t know of such methods for the ui::Button. But I don’t see the use of specific ui::Button items (capinsets, different methods for different touch events etc.) in your method also.
So, I think the MenuItemImage is better in your case:
bool flag = true;
MenuItemImage *button = MenuItemImage::create("play.png", "play_pressed.png", CC_CALLBACK_0(Gallery::playSong, this));
button->setPosition(Vec2((visibleSize.width/2)+origin.x,(visibleSize.height/2)+origin.y-80)); // better is use Vec2, Point can be ambiguous
Menu* menu = Menu::create(button, NULL); // add created button on Menu
menu ->setPosition(0,0);
this->addChild(menu);
And then set the images in handler pressing:
void Gallery::playSong()
{
if(flag)
{
// preload better move to AppDelegate.cpp
// CocosDenshion::SimpleAudioEngine::getInstance()->preloadBackgroundMusic("1.mp3");
flag = false;
CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic("1.mp3");
button->setNormalImage(Sprite::create(“pause.png”));
button->setSelectedImage(Sprite::create(“pause_pressed.png”)); // if you use selected image
}
else
{
flag = true;
CocosDenshion::SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
button->setNormalImage(Sprite::create(“play.png”));
button->setSelectedImage(Sprite::create(“play_pressed.png”));
}
}
In cocos 3.x use property: setHighlighted(bool)
Example:
When press a key: button->setHighlighted(true);
When release the key:
button->setHighlighted(false);
Sorry for the newbie question, but can anyone point me at sample code that illustrates the use of the CMFCMenuButton? The Microsoft help refers to "New Controls samples", but these samples seem to be in the Visual Studio 2008 "Feature Pack", and this refuses to install on my system since I'm running VS 2013 and don't have VS 2008. I haven't been able to find the samples as stand-alone code.
To be specific, I have a dialog bar in which I want a button labelled Save with drop-down options of Save All and Save Visible (with Save All the default). But any working code would at least get me started.
Declare data members:
CMFCMenuButton m_button_menu;
CMenu m_menu;
Also add the button's id to message map and data exchange:
BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
ON_BN_CLICKED(IDC_MFCMENUBUTTON1, OnButtonMenu)
...
END_MESSAGE_MAP
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_MFCMENUBUTTON1, m_button_menu);
}
Define:
BOOL CMyDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
//...
m_menu.LoadMenu(IDR_MENU1);
m_button_menu.m_hMenu = m_menu.GetSubMenu(0)->GetSafeHmenu();
return TRUE;
}
Where IDR_MENU1 is a regular menu bar and we get its first submenu. For example:
IDR_MENU1 MENU
BEGIN
POPUP "Dummy"
BEGIN
MENUITEM "&Item1", ID_FILE_ITEM1
MENUITEM "&Item2", ID_FILE_ITEM2
END
END
If button's drop-down arrow is clicked, a popup menu appears, menu result is passed to OnButtonMenu. If left side of button is clicked, then OnButtonMenu is called directly, without showing a popup menu.
void CMyDialog::OnButtonMenu()
{
CString str;
switch (m_button_menu.m_nMenuResult)
{
case ID_FILE_ITEM1:
str = L"first menu item clicked";
break;
case ID_FILE_ITEM2:
str = L"second menu item clicked";
break;
default:
str = L"Button click (popup menu did not appear, or menu ID is not handled)";
break;
}
MessageBox(str);
}
** When working with docking controls, dialog bars, etc. MFC may run its own subclass, I don't think DoDataExchange gets called. m_button_menu could be invalid. GetDlgItem can be used to find the correct pointer:
CMFCMenuButton* CMyDlgBar::GetButtonMenu()
{
CMFCMenuButton* pButton = &m_button_menu;
if (!IsWindow(pButton->m_hWnd))
pButton = (CMFCMenuButton*)GetDlgItem(IDC_MFCMENUBUTTON1);
return pButton;
}
Everywhere else we use GetButtonMenu() instead of m_button_menu. For example:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
//...
m_dlgbar.Create(...);
m_dlgbar.m_menu.LoadMenu(IDR_MENU1);
m_dlgbar.GetButtonMenu()->m_hMenu = m_dlgbar.m_menu.GetSubMenu(0)->GetSafeHmenu();
return 0;
}
void CMainFrame::OnButtonMenu()
{
CString str;
switch (GetButtonMenu()->m_nMenuResult)
...
}
What if the Drop-Down Arrow does not show?
Then read the answer here that explains the changes needed to your RC file.
I'm trying get all the button child widgets of a window. The buttons were created through QDialogButtonBox. How do I get the which one is the cancel/ok/save button?
I have:
QWidget *pWin = QApplication::activeWindow();
QList<QPushButton *> allPButtons = pWin->findChildren<QPushButton *>();
QListIterator<QPushButton*> i(allPButtons);
while( i.hasNext() )
{
//identify which button is cancel/ok/save button here
/*Note: This is where I'm having trouble, getting the text of the
button here returns NULL. Any other way of Identifying which is
which?
Is it a special case when buttons are created through QDialogButtonBox?
*/
}
You should use the QDialogButtonBox::button() method, to get the button of the corresponding role.
For instance :
QPushButton* pOkButton = pButtonBox->button(QDialogButtonBox::Ok);
QPushButton* pCancelButton = pButtonBox->button(QDialogButtonBox::Cancel);
// and so on...
Generally speaking, I would say it's a bad idea to find a button from it's text, as this text might change when you app is internationalized.
One way is by text parameter from constructor such as QPushButton(const QString & text, QWidget * parent = 0):
QPushButton* buttonSave = new QPushButton("Save");
// etc..
while( i.hasNext() )
{
//identify which button is cancel/ok/save button here
if(i.next()->text() == "Save") {
// do something to save push button
}
}
Another alternative solution:
Use QDialogButtonBox's buttons function to return a list of all the buttons that have been added to the button box, then iterate over the list and identify each button using QDialogButtonBox's standardButton.
auto buttons = ui->buttonBox->buttons();
for (auto button : buttons) {
switch (ui->buttonBox->standardButton(button)) {
case QDialogButtonBox::Ok:
// do something
break;
case QDialogButtonBox::Cancel:
// do something
break;
case QDialogButtonBox::Save:
// do something
break;
default:
break;
}
}
For non-standard buttons
Map each button to an enum:
.h file:
private:
enum class NonStandardButton { Undo, Redo };
// map of non-standard buttons to enum class NonStandardButton
QHash<QAbstractButton*, NonStandardButton> buttonsMap;
.cpp file:
// in constructor
auto undoQPushButton =
ui->buttonBox->addButton("Undo", QDialogButtonBox::ActionRole);
auto redoQPushButton =
ui->buttonBox->addButton("Redo", QDialogButtonBox::ActionRole);
buttonsMap.insert(undoQPushButton, NonStandardButton::Undo);
buttonsMap.insert(redoQPushButton, NonStandardButton::Redo);
Then use QDialogButtonBox::NoButton to identify non-standard buttons:
switch (ui->buttonBox->standardButton(button)) {
case QDialogButtonBox::NoButton:
switch (buttonsMap.value(button)) {
case NonStandardButton::Undo:
// do something
break;
case NonStandardButton::Redo:
// do something
break;
default:
break;
}
default:
break;
}