I'm using this code to create a combo box with colored background/text:
GtkListStore *liststore;
GtkWidget *combo;
GtkCellRenderer *column;
liststore = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
for(int i=0; i<10; i++) {
gtk_list_store_insert_with_values(liststore, NULL, -1, 0, "Default", 1, "white", 2, "black", -1);
}
combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(liststore));
g_object_unref(liststore);
column = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), column, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), column, "text", 0, "foreground", 1, "background", 2, NULL);
and it works. It looks like this:
My question is, how can I set the background of the liststore or the combo box so that there is no whitespace as seen in the picture?
Thanks!
I'm using Numix theme, so the "border" is red. You can use css to override theme styles:
GtkCssProvider *provider;
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider, "menuitem { background: #000; } menuitem:hover { background: #FFF; } .combo { background: #000; }", -1, NULL);
gtk_style_context_add_provider (
GTK_STYLE_CONTEXT (gtk_widget_get_style_context (GTK_WIDGET (combo))),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
gtk_style_context_add_provider_for_screen (gtk_widget_get_screen (combo),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref (provider);
Here's result:
And here is the full source code:
https://pastebin.com/wDeUpb8A
Also take a look at GtkInspector, it's a handy tool for such purposes.
Hello I am new to FLTK and right now I have a very simple program, if you run the program, click create then robot part you will see several options choose one. A new window will open with several FL_Input boxes and one enter button I want to make a callback so that when the user presses enter the text entered into in the FL_Input boxes is saved to a string, for example someone enters Space head into the FL_Input and then that value is assigned to a string. I primarily don't need help with the callback just setting a string equal to a FL_Input. Thank you very much for your help
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <FL/Fl.H>
#include <FL/Fl_Text_Display.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Window.H>
#include <FL/filename.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Slider.H>
#include <string>
#include <FL/Fl_Int_Input.H>
#include <list>
#include <FL/Fl_Color_Chooser.H>
#include <vector>
#include <FL/Fl_Button.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Menu_Bar.H>
#include <FL/Fl_Output.H>
#include <cstdlib>
using namespace std;
void Change_CB(Fl_Widget *w, void *) {
Fl_Menu_Bar *menu = (Fl_Menu_Bar*)w;
Fl_Menu_Item *p;
// Change submenu name
p = (Fl_Menu_Item*)menu->find_item("Edit/Submenu");
if (p) p->label("New Submenu Name");
// Change item name
p = (Fl_Menu_Item*)menu->find_item("Edit/New Submenu Name/Aaa");
if (p) p->label("New Aaa Name");
}
void Quit_CB(Fl_Widget *, void *) {
exit(0);
}
void head_window(Fl_Widget *, void *) {
Fl_Window *head = new Fl_Window(300, 200, "Head");
Fl_Input *input = new Fl_Input(110, 0, 100, 30, "Name");
Fl_Input *input1 = new Fl_Input(110, 40, 100, 30, "Part-Number");
Fl_Input *input2 = new Fl_Input(110, 80, 100, 30, "Weight");
Fl_Input *input3 = new Fl_Input(110, 120, 100, 30, "Cost");
Fl_Button *enter = new Fl_Button(110, 160, 100, 30, "Enter");
head->show();
}
void torso_window(Fl_Widget *, void *) {
Fl_Window *head = new Fl_Window(350, 250, "Torso");
Fl_Input *input = new Fl_Input(150, 0, 100, 30, "Name");
Fl_Input *input1 = new Fl_Input(150, 40, 100, 30, "Part-Number");
Fl_Input *input2 = new Fl_Input(150, 80, 100, 30, "Weight");
Fl_Input *input3 = new Fl_Input(150, 120, 100, 30, "Cost");
Fl_Input *input4 = new Fl_Input(150, 160, 100, 30, "Battery Compartments");
Fl_Button *enter = new Fl_Button(150, 200, 100, 30, "Enter");
head->show();
}
void locomotor_window(Fl_Widget *, void *) {
Fl_Window *head = new Fl_Window(350, 300, "Locomotor");
Fl_Input *input = new Fl_Input(150, 0, 100, 30, "Name");
Fl_Input *input1 = new Fl_Input(150, 40, 100, 30, "Part-Number");
Fl_Input *input2 = new Fl_Input(150, 80, 100, 30, "Weight");
Fl_Input *input3 = new Fl_Input(150, 120, 100, 30, "Cost");
Fl_Input *input4 = new Fl_Input(150, 160, 100, 30, "Speed(MPH)");
Fl_Input *input5 = new Fl_Input(150, 200, 100, 30, "Power Consumed(W)");
Fl_Button *enter = new Fl_Button(150, 240, 100, 30, "Enter");
head->show();
}
void arm_window(Fl_Widget *, void *) {
Fl_Window *head = new Fl_Window(350, 250, "Arm");
Fl_Input *input = new Fl_Input(150, 0, 100, 30, "Name");
Fl_Input *input1 = new Fl_Input(150, 40, 100, 30, "Part-Number");
Fl_Input *input2 = new Fl_Input(150, 80, 100, 30, "Weight");
Fl_Input *input3 = new Fl_Input(150, 120, 100, 30, "Cost");
Fl_Input *input4 = new Fl_Input(150, 160, 100, 30, "Power Consumed(W)");
Fl_Button *enter = new Fl_Button(150, 200, 100, 30, "Enter");
head->show();
}
void battery_window(Fl_Widget *, void *) {
Fl_Window *head = new Fl_Window(350, 250, "Battery");
Fl_Input *input = new Fl_Input(150, 0, 100, 30, "Name");
Fl_Input *input1 = new Fl_Input(150, 40, 100, 30, "Part-Number");
Fl_Input *input2 = new Fl_Input(150, 80, 100, 30, "Weight");
Fl_Input *input3 = new Fl_Input(150, 120, 100, 30, "Cost");
Fl_Input *input4 = new Fl_Input(150, 160, 100, 30, "Energy Stored");
Fl_Button *enter = new Fl_Button(150, 200, 100, 30, "Enter");
head->show();
}
void manual_window(Fl_Widget *, void *) {
Fl_Window *win = new Fl_Window(400, 275);
Fl_Text_Buffer *buff = new Fl_Text_Buffer();
Fl_Text_Display *disp = new Fl_Text_Display(20, 20, 350 , 250 , "Manual");
disp->buffer(buff);
win->resizable(*disp);
win->show();
buff->text("You may click the file button to open a dropdown\nmenu and you will get a button to exit the window\nor press CTRL + v\n"
"You may click create and you get two options either\nto make a robot part or robot model\n"
"Clicking on robot part that shows the parts you may\ncreate and their associated shortcuts\n"
"If you have any questions click help then click on\nmanual to open the manual\n"
);
win->show();
}
int main() {
Fl_Window *win = new Fl_Window(600, 300, "Robot Shop" );
Fl_Menu_Bar *menu = new Fl_Menu_Bar(0, 0, 600, 25);
menu->add("File/Quit", FL_CTRL + 'v', Quit_CB);
menu->add("Create/Robot Part/Head" , FL_CTRL + 'h' , head_window );
menu->add("Create/Robot Part/Torso" , FL_CTRL + 't' , torso_window);
menu->add("Create/Robot Part/Arm" , FL_CTRL + 'a' , arm_window);
menu->add("Create/Robot Part/Battery" , FL_CTRL + 'b' , battery_window);
menu->add("Create/Robot Part/Locomotor" , FL_CTRL + 'l' , locomotor_window);
menu->add("Create/Robot Model");
menu->add("Help/Manual", FL_CTRL + 'm' , manual_window);
win->show();
return(Fl::run());
}
Sorry this is coming late but i think the below will work.
Fl_Input * inp1; //This is a global declaration
Fl_Button * sav1;
static void sav1_cb(Fl_Button *theButton, void*) // The callback function
{
string Surname = inp1 -> value();
cout << Surname;
}
inp1 = new Fl_Input (170+100, 50, 200, 20,"Surname"); // The input field which must be in a window
sav1 = new Fl_Button (170+310, 50 + 280, 100, 30,"Save"); // The save button
sav1->callback((Fl_Callback*)sav1_cb); //Attaching the callback to the save button
What to note is that the "value()" function is what I use to manipulate the data stored or written in the input field. This is just a sample.
Hope it helps.
You need to store your data somewhere. Suggest something like
enum EData
{
EDHeadWeight,
EDHeadCost,
...
EDMax
};
std::string data[EDMax];
Option 1: Change your Fl_Button (enter) to Fl_Return_Button then set the callback for the button to save all the values. This assumes that when the user presses return, they have entered all the values.
Option 2: If you want to capture enter on each input, use when(FL_WHEN_ENTER_KEY)
Fl_Input *input4 = new Fl_Input(150, 160, 100, 30, "Battery Compartments");
input4->when(FL_WHEN_ENTER_KEY);
input4->callback(grab, &data[EDTorsoBattery]);
...
void grab(Fl_Widget* w, void* param)
{
std::string& rv = *((std::string*)param);
Fl_Input* inp = dynamic_cast<Fl_Input*>(w);
rv = inp->value();
}
The problem here is that it requires you to store inp->value() into a const char* yet constants can't be modified... I am completely confused.
For this sub-window I have created a button, but when I click on the button nothing happens. I want to exit the sub-window once I click on the button, but I am not sure how to do that.
void model(Fl_Widget *, void *) {
Fl_Window *head = new Fl_Window(400, 350, "Robot Model: ");
Fl_Input *input = new Fl_Input(200, 0, 100, 30, "Name: ");
Fl_Input *input1 = new Fl_Input(200, 40, 100, 30, "Part-Number: ");
Fl_Input *input2 = new Fl_Input(200, 80, 100, 30, "How much is the Weight: ");
Fl_Input *input3 = new Fl_Input(200, 120, 100, 30, "The Cost: ");
Fl_Input *input4 = new Fl_Input(200, 160, 100, 30, "Brief Description: ");
Fl_Button *enter = new Fl_Button(150, 200, 100, 30, "Enter");
head->show();
}
int main(){
Fl_Window *win = new Fl_Window(600, 500, "Robot Workshop");
Fl_Box *box = new Fl_Box(0, 10, 600, 100, "Welcome to Robot Workshop!");
box->box(FL_UP_BOX);
box->labelsize(36);
box->labelfont(FL_BOLD + FL_ITALIC);
box->labeltype(FL_SHADOW_LABEL);
Fl_Menu_Bar *menu = new Fl_Menu_Bar(0, 0, 600, 25);
menu->add("Exit/Quit", FL_CTRL + 'v', Quit_CB);
menu->add("Project Manager/Robot Part/Head", FL_CTRL + 'h', head);
menu->add("Project Manager/Robot Part/Torso", FL_CTRL + 't', torso);
menu->add("Project Manager/Robot Part/Arm", FL_CTRL + 'a', arm);
menu->add("Project Manager/Robot Part/Battery", FL_CTRL + 'b', battery);
menu->add("Project Manager/Robot Part/Locomotor", FL_CTRL + 'l', locomotor);
menu->add("Project Manager/Robot Model" ,FL_CTRL + 'w', model);
menu->add("Beloved Customer/Browse Catalog", FL_CTRL + 'z', catalog);
menu->add("Beloved Customer/Part Pictures", FL_CTRL + 'v', pic);
menu->add("Manual", FL_CTRL + 'm', manual_window);
win->show();
return(Fl::run());
}
If you want a callback you need to add a callback function. See http://www.fltk.org/doc-1.3/common.html
void xyz_callback(Fl_Widget *w, void *data) {
...
}
You can pass anything you like to data and cast it back to its original type. Then modify your button with
button->callback(xyz_callback, &xyz_data);
I have the following:
Action* actions[];
within an ActionBar class.
I would like in its constructor to do something like this:
actions = {
new Action( new Image( gfx, "Images/ActionBar/Push001.png", 200, 200, TRUE ), 0, 200, 200, 200, 200 ),
new Action( new Image( gfx, "Images/ActionBar/Pull001.png", 200, 200, TRUE ), 1, 200, 200, 200, 200 )
};
Originally I was doing:
Action* actions[ 2 ];
Then in constructor:
actions[ 0 ] = new Action( new Image( gfx, "Images.....
actions[ 1 ] = new Action( new Image( gfx, "Images.....
What's the best way of doing this? so that in the end I can in my game loop do something like
SomeFunctionIPassAnActionInto( actionBar->actions[ 0 ] );
Edit:: changed the question slightly, I always know there will be 5 actions, so if I did
Actions* actions [ 5 ];
How would I declare the array elements like this:
actions = {
new Action( "push" ),
new Action( "pull" ),
new Action( "bla" ),
new Action( "ble" ),
new Action( "blo" )
}
kind of thing
In C++11, you can initialize arrays in the ctor-initializer.
ActionBar::ActionBar()
: actions {
new Action( new Image( gfx, "Images/ActionBar/Push001.png", 200, 200, TRUE ), 0, 200, 200, 200, 200 ),
new Action( new Image( gfx, "Images/ActionBar/Pull001.png", 200, 200, TRUE ), 1, 200, 200, 200, 200 )
}
{
}
How would I declare the array elements like this:
actions = {
new Action( "push" ),
new Action( "pull" ),
new Action( "bla" ),
new Action( "ble" ),
new Action( "blo" )
}
The simplest way to get this to work would be to define a constructor for Action that takes one of char const*, char const* const* or std::string const& that then forwards this argument (possibly with some sort of translation from the examples you've show) to the Image constructor (since image is a member, you'd need to do something in the initializer list like _image(new Image(translate(arg))) where translate is a function you defined that turns push into Images/ActionBar/Push001.png).
Here's my code:
public Form getMenuForm()
{
if ( menuForm == null )
{
Form menuForm = new Form( "Tracking Main Menu" );
menuForm.setLayout( new BoxLayout( BoxLayout.Y_AXIS ) );
menuForm.setScrollable( true );
menuForm.setScrollableY( true );
menuForm.addComponent( this.getMenuList() );
for(int i=0;i<30;i++)
{
Label lblTest = new Label("hello guys");
menuForm.addComponent( lblTest );
}
menuForm.addCommand( new Command( "Exit" ) );
menuForm.setTransitionOutAnimator( CommonTransitions.createSlide( CommonTransitions.SLIDE_HORIZONTAL, true,
200 ) );
menuForm.addCommandListener( this );
}
return menuForm;
}
public List getMenuList()
{
String[] menuItems = { "Find Person", "Person Registration", "Message", "Setting" };
if ( menuList == null )
{
menuList = new List( menuItems );
menuList.setListCellRenderer( new DefaultListCellRenderer( false ) );
menuList.setSmoothScrolling( true );
menuList.setFixedSelection( List.FIXED_NONE );
menuList.addActionListener( this );
}
return menuList;
}
I only can select 4 options of list, and I CAN'T scroll down to see the bottom of screen. Do I miss something here, please help me...
You need to set menuForm to scrollable false and let the list's scrollability take over. You have nested scrollables one in another and that produces a bad user experience.
Maybe you need to do this:
menuList.setScroable(true);