Ribbon button items with large images - mfc

Ribbon buttons can have items within them. But they only, as far as I know, accept small images. I am trying to add large images to these sub items.
Does anyone know how this can be done?
Thanks,
Edit:

Use the SetAlwaysLargeImage() member function in the menu subitems, which are usually CMFCRibbonButtons themselves:
std::auto_ptr<CMFCRibbonButton> apBtn3(new CMFCRibbonButton(ID_RIBBON_BTN_3, _T("Split Button"), 2, 2));
apBtn3->SetMenu(IDR_RIBBON_MENU_1, TRUE);
apBtn3->SetAlwaysLargeImage();
apBtn3->RemoveSubItem(0);
std::auto_ptr<CMFCRibbonButton> apSubButton(new CMFCRibbonButton(ID_RIBBON_MBTN_1, _T("Item 1"), 2, 2)); // <-- !!!
apSubButton->SetAlwaysLargeImage(); // <-- !!!
apBtn3->AddSubItem(apSubButton.release(), 0); // <-- !!!
pPanel1->Add(apBtn3.release());
(modified code from the RibbonGadgets sample)

This seems to be a CMFCRibbonGallery, not a CMFCRibbonButton. Code example:
pPanel1->Add(new CMFCRibbonGallery(ID_RIBBON_PBTN_1, _T("Embedded"), 0, 0, IDB_RIBBON_PALETTE_1, 64));
CMFCRibbonGallery* pBtn2 = new CMFCRibbonGallery(ID_RIBBON_PBTN_2, _T("Button"), 1, 1, IDB_RIBBON_PALETTE_1, 64);
pBtn2->SetButtonMode();
pBtn2->SetAlwaysLargeImage();
pPanel1->Add(pBtn2);
(taken from the RibbonGadgets sample)
[Edit: This is the wrong answer. Check (and upvote) my other answer. I only leave this one undeleted to honor the comments.]

Related

How to allign text on ribbon button?

as adding a ribbon button, I am also supplying the name for it. It is performing its desired action, but placement of string is absurd. It should not be over the image, but under it. Any suggestions please. Adding code snippet and screenshot.
RibbonButtonProp* mRibbonProperties;
bool m_bsetlargeimage = FALSE;
if (ButtonProp.Lookup(m_nMenuItemID, mRibbonProperties) != 0)
{
if (ButtonProp[m_nMenuItemID]->m_bIfSmallButton == FALSE)
{
m_PanelImage.SetImageSize(CSize(32, 32));
m_PanelImage.Load(ButtonProp[m_nMenuItemID]->m_nImageResourceId);
m_bsetlargeimage = TRUE;
}
else
{
m_PanelImage.SetImageSize(CSize(16, 16));
m_PanelImage.Load(ButtonProp[m_nMenuItemID]->m_nImageResourceId);
m_bsetlargeimage = FALSE;
}
pRibbonButton = new CMFCRibbonButton(m_nMenuItemID, m_strMenuItemName, m_PanelImage.ExtractIcon(ButtonProp[m_nMenuItemID]->m_nImageIndex));
pRibbonButton->SetAlwaysLargeImage(m_bsetlargeimage);
Print should be just under the image
There is no way to change this. This is the way ribbons are shown and drawn.
A button text in "large-mode" is always drawn below the icon. I see nothing in the code to change this behavior AND I would never change this, because it is the default behavior people want/expect to see in a standard ribbon.
Earlier
AddCategory(m_strMenuName, NULL, NULL, NULL, NULL, i, NULL);
Now
AddCategory(m_strMenuName, NULL, NULL, CSize(16,16), CSize(32, 32), i, NULL);
Explanation: It was placing the text assuming that all the image size is small only as it was not defined already while calling create.

GTK+2.0 Combo Box - How to get the position of an entry?

#include <gtk/gtk.h>
//Defined a comboBox like this
combo = gtk_combo_box_new_text();
//Added entries like this
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "string");
//How to get a particular entry deleted from the list of entries in the ComboBox combo?
How do I delete a particular entry in the comboBox? For example - The ComboBox dropdown has entries like "Foo", "Boo", "Hoo" etc. Now I want to select "Boo" and then remove it? How do I do that ?
//Segmentation fault while removal error
mcve -
fixed = gtk_fixed_new();
combo = gtk_combo_box_new_text();
gtk_fixed_put(GTK_FIXED(fixed), combo, 50, 50);
label = gtk_label_new("Rooms");
gtk_fixed_put(GTK_FIXED(fixed), label, 50, 30 );
gtk_table_attach_defaults (GTK_TABLE (table), fixed, 2, 3, 0, 2);
g_signal_connect(G_OBJECT(combo), "changed", G_CALLBACK(combo_selected), (gpointer) label);
In this callback function I just copy the current selection to a globally declared string. Next, in some other function I try to run this -
gtk_combo_box_remove_text (GTK_COMBO_BOX(combo), gtk_combo_box_get_active (GTK_COMBO_BOX(combo))); //statement where seg fault occurs
The gtk_combo_box_get_active gives me the appropriate index entry to be removed. Note - GtkWidget *combo is globally defined in the program.
The id of the active(that is currently selected) entry in a combo box can be obtained via gtk_combo_box_get_active and it can be removed with help of gtk_combo_box_text_remove or gtk_combo_box_remove_text
(Depending on which version of the api is used. The former(gtk_combo_box_text_remove) is more up to date).
gtk_combo_box_get_active returns -1 if there is no active item and should therefore be checked before passing it to one of the remove functions. This is especially important if, as in the case presented above, the removing happens in a signal handler. According to the documentation the "changed" signal
[...] is emitted when the active item is changed. This can be due to the user selecting a different item from the list, or due to a call to gtk_combo_box_set_active_iter(). It will also be emitted while typing into the entry of a combo box with an entry. [...]
As far as i understand this includes when the item is deselected(which will presumably happen if it is deleted).
Your handler should therefore look somehow like this:
void combo_selected(GtkComboBox *widget, gpointer user_data)
{
int active_id=gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
if(active_id!=-1)
{
//do real work...
}
}

osgWidget label within frame won't trigger the callback

Here's my problem
I'm new to osg and I'm trying to create something like a dropdown list by adding osgWidget::Labels to a osgWidget::Box and then setting this same box as a osgWidget::Frame's window and all this works fine until the part where my callback "labelClicked" is never actually triggered once I click the label.
I tried adding this callback to other widgets such as an input and even the actual frame where I keep the box with the labels, and both worked fine.
Here's the functions that I use to add labels to my dropdown list:
osgWidget::Label* DropdownInput::createLabel(const std::string& l, unsigned int size) {
osgWidget::Label* label = new osgWidget::Label("", "");
label->setFont("fonts/Vera.ttf");
label->setFontSize(size);
label->setFontColor(1.0f, 1.0f, 1.0f, 1.0f);
label->setLabel(l);
return label;
}
void DropdownInput::addLabel(string text){
osg::ref_ptr<osgWidget::Label> label1 = createLabel(text,15);
label1->setName(text);
label1->setPadding(2.0f);
label1->setColor(1,1,1, 1);
label1->setSize(300.0f, 40);
label1->setImage( "img.png" );
label1->addCallback( new osgWidget::Callback(&DropdownInput::labelClicked, this, osgWidget::EVENT_MOUSE_PUSH) );
dropdownContent.push_back(label1); //list where I store the labels for flitering purposes
this->dropdownBox->addWidget(label1);
}
and the callback:
bool DropdownInput::labelClicked(osgWidget::Event& ev) {
cout<<"label clicked!"<<endl;
return true;
}
Already tried to place the labels inside a box inside a frame and adding the callback to this frame instead, and then adding it to the main box but not only did it not resize correctly but also caused lag when filtering the labels which is not an option.
Also tried with other types of events like mouse over and such and still no answer from the label.
I was asked to avoid using other UI libraries, so if possible I would prefer osgWidget based solutions.
So, now I'm a bit lost, any help would be greatly appreciated.
If you didn't find my explanation to be comprehensible enough don't hesitate telling me since it's my first time posting here :)
For labels you should first add the push event to the label event mask:
label->addEventMask(osgWidget::EVENT_MOUSE_PUSH);
Otherwise label->canMousePush() will return false and the callback will never be called.

Raphael bar chart - bc.bars.length always returning 1

Hi I am using Raphael to generate a bar chart on my web and would like to attach an index to the bars following the replies in this page
https://stackoverflow.com/questions/4057035/raphaeljs-charts-bar-index-fetching?answertab=votes#tab-top.
In order to do this, I will need to fetch the value of bc.bars.length. However, no matter how many bars are in my bar chart, bc.bars.length always returning 1.
Here is my code:
//Create a bar chart using the values in the selected objects
r = Raphael("bar");
txtattr = { font: "12px arial" };
r.text(160, 10, "Title").attr(txtattr);
var bc = r.barchart(10, 10, 300, 220, [myData]).hover(fin, fout);
alert(bc.bars.length); //always returning 1
Anyone knows what is going wrong here? Thanks in advance.
this might be a little late, but for anyone out there, you know, I found myself in the same situation, so let me share my answer and the things I noticed:
(I'm using graphael 0.5.1)
-I noticed that when you use and array for the bars, it returns 1, like what you have:
var bc = r.barchart(10, 10, 300, 220, [myData])
alert(bc.bars.length); //always returning 1
-BUT if you put the values directly, like:
var bc = r.barchart(10, 10, 300, 220, [100,450,340,500])
alert(bc.bars.length); //seems to return 4
-BUT ! that doesn't work if you are getting dinamic data!
so THE SOLUTION I'VE FOUND IS THIS:
//after creating the barchart, let's loop it
var i = 1;
bc.each(function() {
i++;
console.log("bar: "+ i);
});
var total_bars=i-1;
console.log('total_bars: '+total_bars)
I hope this helps other people =), this is a nice library to chart, but it's a shame it's a little buggy with each new version, like the labels and such =(

MFC RIbbon - Multiple CMFCRibbonComboBox on the same panel, respond to selectitem action performed on any onComboBox

I have 2 CMFCRibbonComboBox on the same Panel in a Ribbon- Eg:
CMFCRibbonComboBox *individualComputers =
new CMFCRibbonComboBox(-1,FALSE, 100, "Individual Computers", -1);
individualComputers->AddItem("Computer 1");
individualComputers->AddItem("Computer 2");
individualComputers->AddItem("Computer 3");
individualComputers->SelectItem(0);
CMFCRibbonComboBox * groupNames =
new CMFCRibbonComboBox (-1, FALSE, 100, "Computer Group Names", -1);
groupNames->AddItem("GROUP 1");
groupNames->AddItem("GROUP 2");
groupNames->AddItem("GROUP 3");
groupNames->SelectItem(0);
CMFCRibbonPanel* pComputerGroups = cComputerGroups->AddPanel("All Groups");
//cComputerGroups is a Category
pComputerGroups->Add(individualComputers);
pComputerGroups->Add(groupNames);
The problem is that , when I select "Group 1" in the groupNames comboBox from the UI(USer Interface) , then even "Computer 1" from the group individualComputers is selected. How do I make each combobox group independent of the other? Thanks.
I suspect you didn't want add your combobox to itself individualComputers->Add(individualComputers); should perhaps be pComputerGroups->Add(individualComputers);
Otherwise your bug is probably elsewhere in your command or updateUI handling code not shown. This is likely as you are using the same ID of -1 to identify both combo boxes.
Furthermore there is no overloaded constructor for CMFCRibbonComboBox which takes an additional two parameters as you have shown for groupNames.
In the future please show actual code which follows SSCCE
Edit: Made previously unaddressed comment bold as it is likely to be your remaining issue. Consider using const UINT CB_COMP_ID = 1; and const UINT CB_GROUP_ID = 2; then you can reference each combo box separately using CB_COMP_ID or CB_GROUP_ID in the message map etc.