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.
Related
how I'm going to fix the if-statement on line 31. It just don't want to work. I'm using a source code that enables me to easy create 3D objects. Here's the code:
<script src="http://koda.nu/simple3d.js">
ambientLight("white");
var debug = false;
var player = {x: 0, y: 0, z: 500, item: box(0, 0, 500, 200, 200, 1, "red"), speed: 7};
var ball = {x: 0, y: 0, z: -200, item: sphere(0, 0, -200, 100, "yellow"), xSpeed: 0, ySpeed: 0, zSpeed: -15};
var enemy = {x: 0, y: 0, z: -700, item: box(0, 0, -700, 200, 200, 1, "red"), speed: 7};
box(450, 0, -100, 1, 875, 1200, "blue");
box(-450, 0, -100, 1, 875, 1200, "blue");
box(0, 450, -100, 875, 1, 1200, "blue");
box(0, -450, -100, 875, 1, 1200, "blue");
function update() {
if (keyboard.w && player.y < 350) {
player.item.translateY(player.speed);
player.y += player.speed;
}
if (keyboard.s && player.y > -350) {
player.item.translateY(-player.speed);
player.y -= player.speed;
}
if (keyboard.d && player.x < 350) {
player.item.translateX(player.speed);
player.x += player.speed;
}
if (keyboard.a && player.x > -350) {
player.item.translateX(-player.speed);
player.x -= player.speed;
}
/*(This line just don't want to work ---->)*/ if (ball.z == enemy.z) { ball.zSpeed *= -1; }
if (keyboard.shift && keyboard.y) {
debug = true;
}
ball.x += ball.xSpeed;
ball.item.translateX(ball.xSpeed);
ball.y += ball.ySpeed;
ball.item.translateY(ball.ySpeed);
ball.z += ball.zSpeed;
ball.item.translateZ(ball.zSpeed);
while (debug) {
if (keyboard.up) {
moveCameraZ(-player.speed);
}
if (keyboard.down) {
moveCameraZ(player.speed);
}
if (keyboard.left) {
moveCameraX(-player.speed);
}
if (keyboard.right) {
moveCameraX(player.speed);
}
if (keyboard.shift && keyboard.y) {
debug = True;
}
}
}
</script>
your code is very messy, i think it must be instead of { debug = True; } it must be { debug = False; }
In swift I have an array like this:
var array = [ 70, 75, 0, 0, 0, 87, 90, 85, 0]
What I want to do is when the value is 0 it will copy the previous first value which is not equal to 0. So the output will become:
[ 70, 75,75, 75, 75, 87, 90, 85, 85]
I’ve tried this code below:
func fillingEmpValues(dataArray:[Int]) -> [Int?] {
var newValue = [Int]()
var array = dataArray
for (index, var element) in array.reversed().enumerated() {
if (element == 0) { // if element is 0
if(index != 0) { // if the index is not 0 proceed
array[index] = (dataArray.reversed()[index-1])
}
}
}
return newValue
}
But the codes above is not working as I expected the output is still the same. What am i MISSING? Thanks
Your code does not work because nothing is appended to newValue. Please notice the yellow warnings.
My suggestion uses a temporary variable (temp).
In the loop
if the value != 0 the value is appended and the temporary variable is set to the value.
if the value == 0 the temporary variable is appended.
func fillingEmpValues(dataArray:[Int]) -> [Int] {
var newValue = [Int]()
var temp = 0
for element in dataArray {
if element != 0 {
newValue.append(element)
temp = element
} else {
newValue.append(temp)
}
}
return newValue
}
let array = [ 70, 75, 0, 0, 0, 87, 90, 85, 0]
let filledArray = fillingEmpValues(dataArray: array) // [70, 75, 75, 75, 75, 87, 90, 85, 85]
Note: Why is your return value [Int?]? Optionals are not involved at all.
Edit:
The other condition in the comments can be accomplished with
func fillingEmpValues(dataArray:[Int]) -> [Int] {
var newValue = [Int]()
var temp = dataArray.first{ $0 != 0 } ?? 0
for (index, element) in dataArray.enumerated() {
if element != 0 {
newValue.append(element)
} else {
temp = dataArray.dropFirst(index).first{ $0 != 0 } ?? temp
newValue.append(temp)
}
}
return newValue
}
let array = [ 0, 0, 83, 0, 0, 87, 90, 85, 0]
let filledArray = fillingEmpValues(dataArray: array) // [83, 83, 83, 87, 87, 87, 90, 85, 85]
I might suggest using reduce(into:):
let array = [70, 75, 0, 0, 0, 87, 90, 85, 0]
let array2 = array.reduce(into: [Int]()) { (result, value) in
if value == 0 {
result.append(result.last ?? 0)
} else {
result.append(value)
}
}
Yielding:
[70, 75, 75, 75, 75, 87, 90, 85, 85]
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 to do an exercise in C++ and I have a this kind of array-structure and I have never seen it before and I don't know how to use it, if someone can explain me please.
struct Fighter{
string type; // TIE Fighter, X-Wing, ...
int velocity;
int attack; // attack power
int shield; // current shield status.
int cost; // cost in credits};
const Fighter FIGHTERTABLE[] = {
{ "TIE-Fighter", 150, 75, 30, 45 },
{ "TIE-Bomber", 80, 150, 45, 75 },
{ "TIE-Interceptor", 180, 65, 30, 55 },
{ "TIE-Advanced", 160, 80, 90, 95 },
{ "X-Wing", 175, 90, 75, 65 },
{ "Y-Wing", 90, 150, 90, 90 },
{ "A-Wing", 200, 60, 50, 45 },
{ "B-Wing", 120, 200, 90, 100 }
};
const string FIGHTERABR[]= { "tf", "tb", "ti", "ta",
"xw", "yw", "aw", "bw"
};
What you have is an initialized array of structure 'Fighter',
as to how would you use it or access values?
it will be same as normal array
i.e.
string type = FIGHTERTABLE[0].type // type will be equal to "TIE-Fighter"
type = FIGHTERTABLE[0].type // now type will be equal to "TIE-Bomber"
exactly like a normal array, hope this clears things a bit.
It is an array of the type Fighter. So each element is a Fighter and is initialized using an initializer list {std::string,int,int,int,int}.
Read more about initializer-list
I am delving into Layouts & trying to understand how they work. Is a Layout anything like a JPanel in Java Swing? Ie, where we declare a main panel & add all out widgets to that?
One thing I do not understand is when we create a mobile app, we create a Layout & a Listbox. What is the relationship between those 2 objects?
Does the Layout object contain the Listbox, then we add all the widgets to the listbox?
Or does the Listbox have a Layout defined, then we add the widgets to the Listbox & they aligned according to the Layout
Or do we add all widgets to the layout like in Java Swing?
PS: With my experimentation below, my widgets are not shown? Its just a blank black screen. Why does this happen?
#include <MAUtil/Moblet.h>
#include <MAUI/Layout.h>
#include <MAUI/ListBox.h>
#include <MAUI/Label.h>
#include <MAUI/EditBox.h>
#include <MAUI/Screen.h>
#include <MAUtil/Environment.h>
#include <madmath.h>
#include <conprint.h>
using namespace MAUtil;
using namespace MAUI;
class TemperatureScreen : public Screen //, public PointerListener
{
public:
TemperatureScreen()
{
MAExtent screenDim = maGetScrSize();
Layout* mainLayout = new Layout( 0, 0, EXTENT_X(screenDim), EXTENT_Y(screenDim), NULL, 1, 3 );
ListBox* mainListBox = new ListBox( 0, 0, 100, 200, mainLayout,
ListBox::LBO_VERTICAL, ListBox::LBA_LINEAR,
true );
mainListBox -> setPaddingLeft( 10 );
mainListBox -> setPaddingRight( 10 );
mainListBox -> setPaddingTop( 10 );
mainListBox -> setPaddingBottom( 10 );
mainListBox -> setBackgroundColor( 900 );
mainLayout -> setBackgroundColor( 300 );
Label *celLabel = new Label( 10, 300, 50, 20, mainLayout );
Label *fahLabel = new Label( 10, 300, 50, 20, mainLayout );
EditBox *celEdit = new EditBox( 10, 300, 50, 20, mainLayout );
EditBox *fahEdit = new EditBox( 10, 300, 50, 20, mainLayout );
Label *toCelsiusRb = new Label( 10, 300, 50, 20, mainLayout );
Label *toFahRb = new Label( 10, 300, 50, 20, mainLayout );
Label *convertLabel = new Label( 10, 300, 50, 20, mainLayout );
Label *exitLabel = new Label( 10, 300, 50, 20, mainLayout );
celLabel -> setCaption( "Celcius" );
fahLabel -> setCaption( "Fahrenheit" );
convertLabel -> setCaption( "Convert" );
exitLabel -> setCaption( "Exit" );
/*celLabel -> addPointerListener( this );
fahLabel -> addPointerListener( this );
convertLabel -> addPointerListener( this );
exitLabel -> addPointerListener( this );*/
mainLayout -> add( celLabel );
mainLayout -> add( fahLabel );
mainLayout -> add( convertLabel );
mainLayout -> add( exitLabel );
}
};
class TemperatureMoblet : public Moblet
{
public:
TemperatureMoblet()
{
instance = new TemperatureScreen();
instance -> show();
}
~TemperatureMoblet()
{
delete instance;
}
void keyPressEvent(int keyCode, int nativeCode)
{
// todo: handle key presses
printf( "Blah" );
}
void keyReleaseEvent(int keyCode, int nativeCode)
{
// todo: handle key releases
}
private:
TemperatureScreen *instance;
};
extern "C" int MAMain()
{
Moblet::run(new TemperatureMoblet());
return 0;
};
Try putting an maUpdateScreen() in a timer event or in the key listener, just to see what happens.
If you need more help just get back to me.
You could try the new version 2.6 of mosync at:
http://www.mosync.com/documentation/manualpages/whats-new-mosync-26-pyramid
/Tony