mirror of https://github.com/fltk/fltk
3934 lines
120 KiB
C++
3934 lines
120 KiB
C++
//
|
|
// Widget type code for the Fast Light Tool Kit (FLTK).
|
|
//
|
|
// Copyright 1998-2023 by Bill Spitzak and others.
|
|
//
|
|
// This library is free software. Distribution and use rights are outlined in
|
|
// the file "COPYING" which should have been included with this file. If this
|
|
// file is missing or damaged, see the license at:
|
|
//
|
|
// https://www.fltk.org/COPYING.php
|
|
//
|
|
// Please see the following page on how to report bugs and issues:
|
|
//
|
|
// https://www.fltk.org/bugs.php
|
|
//
|
|
|
|
#include "Fl_Widget_Type.h"
|
|
|
|
#include "fluid.h"
|
|
#include "Fl_Window_Type.h"
|
|
#include "Fl_Group_Type.h"
|
|
#include "Fl_Menu_Type.h"
|
|
#include "Fl_Function_Type.h"
|
|
#include "file.h"
|
|
#include "code.h"
|
|
#include "Fluid_Image.h"
|
|
#include "settings_panel.h"
|
|
#include "widget_panel.h"
|
|
#include "undo.h"
|
|
#include "mergeback.h"
|
|
|
|
#include <FL/Fl.H>
|
|
#include <FL/Fl_Group.H>
|
|
#include <FL/Fl_Table.H>
|
|
#include <FL/Fl_Input.H>
|
|
#include <FL/fl_message.H>
|
|
#include <FL/Fl_Slider.H>
|
|
#include <FL/Fl_Spinner.H>
|
|
#include <FL/Fl_Window.H>
|
|
#include <FL/fl_show_colormap.H>
|
|
#include "../src/flstring.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
// Make an Fl_Widget_Type subclass instance.
|
|
// It figures out the automatic size and parent of the new widget,
|
|
// creates the Fl_Widget (by calling the virtual function _make),
|
|
// adds it to the Fl_Widget hierarchy, creates a new Fl_Type
|
|
// instance, sets the widget pointers, and makes all the display
|
|
// update correctly...
|
|
|
|
int Fl_Widget_Type::is_widget() const {return 1;}
|
|
int Fl_Widget_Type::is_public() const {return public_;}
|
|
|
|
const char* subclassname(Fl_Type* l) {
|
|
if (l->is_a(ID_Menu_Bar)) {
|
|
Fl_Menu_Bar_Type *mb = static_cast<Fl_Menu_Bar_Type*>(l);
|
|
if (mb->is_sys_menu_bar())
|
|
return mb->sys_menubar_name();
|
|
}
|
|
if (l->is_widget()) {
|
|
Fl_Widget_Type* p = (Fl_Widget_Type*)l;
|
|
const char* c = p->subclass();
|
|
if (c) return c;
|
|
if (l->is_class()) return "Fl_Group";
|
|
if (p->o->type() == FL_WINDOW+1) return "Fl_Double_Window";
|
|
if (p->id() == ID_Input) {
|
|
if (p->o->type() == FL_FLOAT_INPUT) return "Fl_Float_Input";
|
|
if (p->o->type() == FL_INT_INPUT) return "Fl_Int_Input";
|
|
}
|
|
}
|
|
return l->type_name();
|
|
}
|
|
|
|
// Return the ideal widget size...
|
|
void
|
|
Fl_Widget_Type::ideal_size(int &w, int &h) {
|
|
w = 120;
|
|
h = 100;
|
|
Fd_Snap_Action::better_size(w, h);
|
|
}
|
|
|
|
/**
|
|
Make a new Widget node.
|
|
\param[in] strategy is kAddAsLastChild or kAddAfterCurrent
|
|
\return new node
|
|
*/
|
|
Fl_Type *Fl_Widget_Type::make(Strategy strategy) {
|
|
Fl_Type *anchor = Fl_Type::current, *pp = anchor;
|
|
if (pp && (strategy == kAddAfterCurrent)) pp = pp->parent;
|
|
while (pp && !pp->is_a(ID_Group)) {
|
|
anchor = pp;
|
|
strategy = kAddAfterCurrent;
|
|
pp = pp->parent;
|
|
}
|
|
if (!pp || !pp->is_true_widget() || !anchor->is_true_widget()) {
|
|
fl_message("Please select a group widget or window");
|
|
return 0;
|
|
}
|
|
|
|
Fl_Widget_Type* p = (Fl_Widget_Type*)pp;
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)anchor;
|
|
|
|
// Figure out a border between widget and window:
|
|
int B = p->o->w()/2; if (p->o->h()/2 < B) B = p->o->h()/2; if (B>25) B = 25;
|
|
|
|
int ULX,ULY; // parent's origin in window
|
|
if (!p->is_a(ID_Window)) { // if it is a group, add corner
|
|
ULX = p->o->x(); ULY = p->o->y();
|
|
} else {
|
|
ULX = ULY = 0;
|
|
}
|
|
|
|
// Figure out a position and size for the widget
|
|
int X,Y,W,H;
|
|
if (is_a(ID_Group)) { // fill the parent with the widget
|
|
X = ULX+B;
|
|
W = p->o->w()-B;
|
|
Y = ULY+B;
|
|
H = p->o->h()-B;
|
|
} else if (q != p) { // copy position and size of current widget
|
|
W = q->o->w();
|
|
H = q->o->h();
|
|
X = q->o->x()+W;
|
|
Y = q->o->y();
|
|
if (X+W > ULX+p->o->w()) {
|
|
X = q->o->x();
|
|
Y = q->o->y()+H;
|
|
if (Y+H > ULY+p->o->h()) Y = ULY+B;
|
|
}
|
|
} else { // just make it small and square...
|
|
X = ULX+B;
|
|
Y = ULY+B;
|
|
W = H = B;
|
|
}
|
|
|
|
// Construct the Fl_Type:
|
|
Fl_Widget_Type *t = _make();
|
|
if (!o) o = widget(0,0,100,100); // create template widget
|
|
t->factory = this;
|
|
// Construct the Fl_Widget:
|
|
t->o = widget(X,Y,W,H);
|
|
if (reading_file) t->o->label(0);
|
|
else if (t->o->label()) t->label(t->o->label()); // allow editing
|
|
t->o->user_data((void*)t);
|
|
// Put it in the parent:
|
|
// ((Fl_Group *)(p->o))->add(t->o); (done by Fl_Type::add())
|
|
// add to browser:
|
|
t->add(anchor, strategy);
|
|
t->redraw();
|
|
return t;
|
|
}
|
|
|
|
void Fl_Widget_Type::setimage(Fluid_Image *i) {
|
|
if (i == image || is_a(ID_Window)) return;
|
|
if (image) image->decrement();
|
|
if (i) i->increment();
|
|
image = i;
|
|
if (i) {
|
|
i->image(o);
|
|
if (o->image() && (scale_image_w_ || scale_image_h_)) {
|
|
int iw = scale_image_w_>0 ? scale_image_w_ : o->image()->data_w();
|
|
int ih = scale_image_h_>0 ? scale_image_h_ : o->image()->data_h();
|
|
o->image()->scale(iw, ih, 0, 1);
|
|
}
|
|
} else {
|
|
o->image(0);
|
|
//scale_image_w_ = scale_image_h_ = 0;
|
|
}
|
|
redraw();
|
|
}
|
|
|
|
void Fl_Widget_Type::setinactive(Fluid_Image *i) {
|
|
if (i == inactive || is_a(ID_Window)) return;
|
|
if (inactive) inactive->decrement();
|
|
if (i) i->increment();
|
|
inactive = i;
|
|
if (i) {
|
|
i->deimage(o);
|
|
if (o->deimage()) {
|
|
int iw = scale_deimage_w_>0 ? scale_deimage_w_ : o->deimage()->data_w();
|
|
int ih = scale_deimage_h_>0 ? scale_deimage_h_ : o->deimage()->data_h();
|
|
o->deimage()->scale(iw, ih, 0, 1);
|
|
}
|
|
} else {
|
|
o->deimage(0);
|
|
//scale_deimage_w_ = scale_deimage_h_ = 0;
|
|
}
|
|
redraw();
|
|
}
|
|
|
|
void Fl_Widget_Type::setlabel(const char *n) {
|
|
o->label(n);
|
|
redraw();
|
|
}
|
|
|
|
Fl_Widget_Type::Fl_Widget_Type()
|
|
: override_visible_(0)
|
|
{
|
|
for (int n=0; n<NUM_EXTRA_CODE; n++) {extra_code_[n] = 0; }
|
|
subclass_ = 0;
|
|
hotspot_ = 0;
|
|
tooltip_ = 0;
|
|
image_name_ = 0;
|
|
inactive_name_ = 0;
|
|
image = 0;
|
|
inactive = 0;
|
|
o = 0;
|
|
public_ = 1;
|
|
bind_image_ = 0;
|
|
compress_image_ = 1;
|
|
bind_deimage_ = 0;
|
|
compress_deimage_ = 1;
|
|
scale_image_w_ = 0;
|
|
scale_image_h_ = 0;
|
|
scale_deimage_w_ = 0;
|
|
scale_deimage_h_ = 0;
|
|
}
|
|
|
|
Fl_Widget_Type::~Fl_Widget_Type() {
|
|
if (o) {
|
|
Fl_Window *win = o->window();
|
|
delete o;
|
|
if (win)
|
|
win->redraw();
|
|
}
|
|
if (subclass_) free((void*)subclass_);
|
|
if (tooltip_) free((void*)tooltip_);
|
|
if (image_name_) {
|
|
free((void*)image_name_);
|
|
if (image) image->decrement();
|
|
}
|
|
if (inactive_name_) {
|
|
free((void*)inactive_name_);
|
|
if (inactive) inactive->decrement();
|
|
}
|
|
for (int n=0; n<NUM_EXTRA_CODE; n++) {
|
|
if (extra_code_[n]) free((void*) extra_code_[n]);
|
|
}
|
|
}
|
|
|
|
void Fl_Widget_Type::extra_code(int m,const char *n) {
|
|
storestring(n,extra_code_[m]);
|
|
}
|
|
|
|
extern void redraw_browser();
|
|
void Fl_Widget_Type::subclass(const char *n) {
|
|
if (storestring(n,subclass_) && visible)
|
|
redraw_browser();
|
|
}
|
|
|
|
void Fl_Widget_Type::tooltip(const char *n) {
|
|
storestring(n,tooltip_);
|
|
o->tooltip(n);
|
|
}
|
|
|
|
void Fl_Widget_Type::image_name(const char *n) {
|
|
setimage(Fluid_Image::find(n));
|
|
storestring(n,image_name_);
|
|
}
|
|
|
|
void Fl_Widget_Type::inactive_name(const char *n) {
|
|
setinactive(Fluid_Image::find(n));
|
|
storestring(n,inactive_name_);
|
|
}
|
|
|
|
void Fl_Widget_Type::redraw() {
|
|
Fl_Type *t = this;
|
|
if (is_a(ID_Menu_Item)) {
|
|
// find the menu button that parents this menu:
|
|
do t = t->parent; while (t && t->is_a(ID_Menu_Item));
|
|
// kludge to cause build_menu to be called again:
|
|
if (t)
|
|
t->add_child(0, 0);
|
|
} else {
|
|
while (t->parent && t->parent->is_widget()) t = t->parent;
|
|
((Fl_Widget_Type*)t)->o->redraw();
|
|
}
|
|
}
|
|
|
|
// the recursive part sorts all children, returns pointer to next:
|
|
Fl_Type *sort(Fl_Type *parent) {
|
|
Fl_Type *f,*n=0;
|
|
for (f = parent ? parent->next : Fl_Type::first; ; f = n) {
|
|
if (!f || (parent && f->level <= parent->level)) break;
|
|
n = sort(f);
|
|
if (!f->selected || !f->is_true_widget()) continue;
|
|
Fl_Widget* fw = ((Fl_Widget_Type*)f)->o;
|
|
Fl_Type *g; // we will insert before this
|
|
for (g = parent ? parent->next : Fl_Type::first; g != f; g = g->next) {
|
|
if (!g->selected || g->level > f->level) continue;
|
|
Fl_Widget* gw = ((Fl_Widget_Type*)g)->o;
|
|
if (gw->y() > fw->y()) break;
|
|
if (gw->y() == fw->y() && gw->x() > fw->x()) break;
|
|
}
|
|
if (g != f) f->move_before(g);
|
|
}
|
|
if (parent)
|
|
parent->layout_widget();
|
|
return f;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// The control panels!
|
|
|
|
Fl_Window *the_panel;
|
|
|
|
// All the callbacks use the argument to indicate whether to load or store.
|
|
// This avoids the need for pointers to all the widgets, and keeps the
|
|
// code localized in the callbacks.
|
|
// A value of LOAD means to load. The hope is that this will not collide
|
|
// with any actual useful values for the argument. I also use this to
|
|
// initialized parts of the widget that are nyi by fluid.
|
|
|
|
Fl_Widget_Type *current_widget; // one of the selected ones
|
|
void* const LOAD = (void *)"LOAD"; // "magic" pointer to indicate that we need to load values into the dialog
|
|
static int numselected; // number selected
|
|
static int haderror;
|
|
|
|
void name_cb(Fl_Input* o, void *v) {
|
|
if (v == LOAD) {
|
|
static char buf[1024];
|
|
if (numselected != 1) {
|
|
snprintf(buf, sizeof(buf), "Widget Properties (%d widgets)", numselected);
|
|
o->hide();
|
|
} else {
|
|
o->value(current_widget->name());
|
|
o->show();
|
|
snprintf(buf, sizeof(buf), "%s Properties", current_widget->title());
|
|
}
|
|
|
|
the_panel->label(buf);
|
|
} else {
|
|
if (numselected == 1) {
|
|
current_widget->name(o->value());
|
|
// I don't update window title, as it probably is being closed
|
|
// and wm2 (a window manager) barfs if you retitle and then
|
|
// hide a window:
|
|
// ((Fl_Window*)(o->parent()->parent()->parent()))->label(current_widget->title());
|
|
}
|
|
}
|
|
}
|
|
|
|
void name_public_member_cb(Fl_Choice* i, void* v) {
|
|
if (v == LOAD) {
|
|
i->value(current_widget->public_);
|
|
if (current_widget->is_in_class()) i->show(); else i->hide();
|
|
} else {
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type *w = ((Fl_Widget_Type*)o);
|
|
if (w->is_in_class()) {
|
|
w->public_ = i->value();
|
|
} else {
|
|
// if this is not in a class, it can be only private or public
|
|
w->public_ = (i->value()>0);
|
|
}
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) {
|
|
set_modflag(1);
|
|
redraw_browser();
|
|
}
|
|
}
|
|
}
|
|
|
|
void name_public_cb(Fl_Choice* i, void* v) {
|
|
if (v == LOAD) {
|
|
i->value(current_widget->public_>0);
|
|
if (current_widget->is_in_class()) i->hide(); else i->show();
|
|
} else {
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
((Fl_Widget_Type*)o)->public_ = i->value();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) {
|
|
set_modflag(1);
|
|
redraw_browser();
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Treating UNDO for text widget.
|
|
|
|
Goal: we want to continuously update the UI while the user is typing text
|
|
(changing the label, in this case). Code View does deferred updates, and
|
|
the widget browser and widget panel update on every keystroke. At the same
|
|
time, we want to limit undo actions to few and logical units.
|
|
|
|
Caveats:
|
|
|
|
1: the text widget has its own undo handling for the text field, but we may want to do a global undo
|
|
2: every o->label() call will create an undo entry, but we want only one single event for all selected widgets
|
|
3: we want a single undo for the entire editing phase, but still propagate changes as they happen
|
|
|
|
The edit process has these main states:
|
|
|
|
1: starting to edit [first_change==1 && !unfocus]; we must create a single undo checkpoint before anything changes
|
|
2: continue editing [first_change==0 && !unfocus]; we must suspend any undo checkpoints
|
|
3: done editing, unfocus [first_change==0 && unfocus]; we must make sure that undo checkpoints are enabled again
|
|
4: losing focus without editing [first_change==1 && unfocus]; don't create and checkpoints
|
|
|
|
We must also check:
|
|
1: changing focus without changing text (works)
|
|
2: copy and paste, drag and drop operations (works)
|
|
3: save operation without unfocus event (works)
|
|
*/
|
|
void label_cb(Fl_Input* i, void *v) {
|
|
static int first_change = 1;
|
|
if (v == LOAD) {
|
|
i->value(current_widget->label());
|
|
first_change = 1;
|
|
} else {
|
|
if (i->changed()) {
|
|
undo_suspend();
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
if (!mod) {
|
|
if (first_change) {
|
|
undo_resume();
|
|
undo_checkpoint();
|
|
undo_suspend();
|
|
first_change = 0;
|
|
}
|
|
mod = 1;
|
|
}
|
|
o->label(i->value());
|
|
}
|
|
}
|
|
undo_resume();
|
|
if (mod) set_modflag(1);
|
|
}
|
|
int r = (int)Fl::callback_reason();
|
|
if ( (r == FL_REASON_LOST_FOCUS) || (r == FL_REASON_ENTER_KEY) )
|
|
first_change = 1;
|
|
}
|
|
}
|
|
|
|
static Fl_Input *image_input;
|
|
|
|
void image_cb(Fl_Input* i, void *v) {
|
|
if (v == LOAD) {
|
|
image_input = i;
|
|
if (current_widget->is_widget() && !current_widget->is_a(ID_Window)) {
|
|
i->activate();
|
|
i->value(((Fl_Widget_Type*)current_widget)->image_name());
|
|
} else i->deactivate();
|
|
} else {
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
((Fl_Widget_Type*)o)->image_name(i->value());
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void image_browse_cb(Fl_Button* b, void *v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_widget() && !current_widget->is_a(ID_Window))
|
|
b->activate();
|
|
else
|
|
b->deactivate();
|
|
} else {
|
|
int mod = 0;
|
|
if (ui_find_image(image_input->value())) {
|
|
image_input->value(ui_find_image_name);
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
((Fl_Widget_Type*)o)->image_name(ui_find_image_name);
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void bind_image_cb(Fl_Check_Button* b, void *v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_widget() && !current_widget->is_a(ID_Window)) {
|
|
b->activate();
|
|
b->value(current_widget->bind_image_);
|
|
} else {
|
|
b->deactivate();
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
((Fl_Widget_Type*)o)->bind_image_ = b->value();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void compress_image_cb(Fl_Check_Button* b, void *v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_widget() && !current_widget->is_a(ID_Window)) {
|
|
b->activate();
|
|
b->value(!current_widget->compress_image_);
|
|
} else {
|
|
b->deactivate();
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
((Fl_Widget_Type*)o)->compress_image_ = !b->value();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
static Fl_Input *inactive_input;
|
|
|
|
void inactive_cb(Fl_Input* i, void *v) {
|
|
if (v == LOAD) {
|
|
inactive_input = i;
|
|
if (current_widget->is_widget() && !current_widget->is_a(ID_Window)) {
|
|
i->activate();
|
|
i->value(((Fl_Widget_Type*)current_widget)->inactive_name());
|
|
} else i->deactivate();
|
|
} else {
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
((Fl_Widget_Type*)o)->inactive_name(i->value());
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void inactive_browse_cb(Fl_Button* b, void *v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_widget() && !current_widget->is_a(ID_Window))
|
|
b->activate();
|
|
else
|
|
b->deactivate();
|
|
} else {
|
|
int mod = 0;
|
|
if (ui_find_image(inactive_input->value())) {
|
|
inactive_input->value(ui_find_image_name);
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
((Fl_Widget_Type*)o)->inactive_name(ui_find_image_name);
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void bind_deimage_cb(Fl_Check_Button* b, void *v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_widget() && !current_widget->is_a(ID_Window)) {
|
|
b->activate();
|
|
b->value(current_widget->bind_deimage_);
|
|
} else {
|
|
b->deactivate();
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
((Fl_Widget_Type*)o)->bind_deimage_ = b->value();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void compress_deimage_cb(Fl_Check_Button* b, void *v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_widget() && !current_widget->is_a(ID_Window)) {
|
|
b->activate();
|
|
b->value(!current_widget->compress_deimage_);
|
|
} else {
|
|
b->deactivate();
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
((Fl_Widget_Type*)o)->compress_deimage_ = !b->value();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void tooltip_cb(Fl_Input* i, void *v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_widget()) {
|
|
i->activate();
|
|
i->value(((Fl_Widget_Type*)current_widget)->tooltip());
|
|
} else i->deactivate();
|
|
} else {
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
((Fl_Widget_Type*)o)->tooltip(i->value());
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
Fluid_Coord_Input *x_input, *y_input, *w_input, *h_input;
|
|
|
|
static int widget_i = 0;
|
|
|
|
static int vars_i_cb(const Fluid_Coord_Input*, void *v) {
|
|
return widget_i;
|
|
}
|
|
|
|
static int vars_x_cb(const Fluid_Coord_Input*, void *v) {
|
|
Fl_Type *t = (Fl_Type*)v;
|
|
if (t->is_widget())
|
|
return ((Fl_Widget_Type*)t)->o->x();
|
|
return 0;
|
|
}
|
|
|
|
static int vars_y_cb(const Fluid_Coord_Input*, void *v) {
|
|
Fl_Type *t = (Fl_Type*)v;
|
|
if (t->is_widget())
|
|
return ((Fl_Widget_Type*)t)->o->y();
|
|
return 0;
|
|
}
|
|
|
|
static int vars_w_cb(const Fluid_Coord_Input*, void *v) {
|
|
Fl_Type *t = (Fl_Type*)v;
|
|
if (t->is_widget())
|
|
return ((Fl_Widget_Type*)t)->o->w();
|
|
return 0;
|
|
}
|
|
|
|
static int vars_h_cb(const Fluid_Coord_Input*, void *v) {
|
|
Fl_Type *t = (Fl_Type*)v;
|
|
if (t->is_widget())
|
|
return ((Fl_Widget_Type*)t)->o->h();
|
|
return 0;
|
|
}
|
|
|
|
static int vars_px_cb(const Fluid_Coord_Input*, void *v) {
|
|
Fl_Type *t = ((Fl_Type*)v)->parent;
|
|
if (t && t->is_widget())
|
|
return ((Fl_Widget_Type*)t)->o->x();
|
|
return 0;
|
|
}
|
|
|
|
static int vars_py_cb(const Fluid_Coord_Input*, void *v) {
|
|
Fl_Type *t = ((Fl_Type*)v)->parent;
|
|
if (t && t->is_widget())
|
|
return ((Fl_Widget_Type*)t)->o->y();
|
|
return 0;
|
|
}
|
|
|
|
static int vars_pw_cb(const Fluid_Coord_Input*, void *v) {
|
|
Fl_Type *t = ((Fl_Type*)v)->parent;
|
|
if (t && t->is_widget())
|
|
return ((Fl_Widget_Type*)t)->o->w();
|
|
return 0;
|
|
}
|
|
|
|
static int vars_ph_cb(const Fluid_Coord_Input*, void *v) {
|
|
Fl_Type *t = ((Fl_Type*)v)->parent;
|
|
if (t && t->is_widget())
|
|
return ((Fl_Widget_Type*)t)->o->h();
|
|
return 0;
|
|
}
|
|
|
|
static int vars_sx_cb(const Fluid_Coord_Input*, void *v) {
|
|
Fl_Type *t = ((Fl_Type*)v)->prev_sibling();
|
|
if (t && t->is_widget())
|
|
return ((Fl_Widget_Type*)t)->o->x();
|
|
return 0;
|
|
}
|
|
|
|
static int vars_sy_cb(const Fluid_Coord_Input*, void *v) {
|
|
Fl_Type *t = ((Fl_Type*)v)->prev_sibling();
|
|
if (t && t->is_widget())
|
|
return ((Fl_Widget_Type*)t)->o->y();
|
|
return 0;
|
|
}
|
|
|
|
static int vars_sw_cb(const Fluid_Coord_Input*, void *v) {
|
|
Fl_Type *t = ((Fl_Type*)v)->prev_sibling();
|
|
if (t && t->is_widget())
|
|
return ((Fl_Widget_Type*)t)->o->w();
|
|
return 0;
|
|
}
|
|
|
|
static int vars_sh_cb(const Fluid_Coord_Input*, void *v) {
|
|
Fl_Type *t = ((Fl_Type*)v)->prev_sibling();
|
|
if (t && t->is_widget())
|
|
return ((Fl_Widget_Type*)t)->o->h();
|
|
return 0;
|
|
}
|
|
|
|
static int bbox_x, bbox_y, bbox_r, bbox_b;
|
|
static int bbox_min(int a, int b) { return (a<b) ? a : b; }
|
|
static int bbox_max(int a, int b) { return (a>b) ? a : b; }
|
|
|
|
static void calculate_bbox(Fl_Type *p) {
|
|
char first = 1;
|
|
bbox_x = bbox_y = bbox_r = bbox_b = 0;
|
|
for (p=p->first_child(); p; p=p->next_sibling()) {
|
|
if (p->is_widget()) {
|
|
Fl_Widget *o = ((Fl_Widget_Type*)p)->o;
|
|
if (first) {
|
|
bbox_x = o->x(); bbox_y = o->y();
|
|
bbox_r = o->x() + o->w(); bbox_b = o->y() + o->h();
|
|
first = 0;
|
|
} else {
|
|
bbox_x = bbox_min(bbox_x, o->x());
|
|
bbox_y = bbox_min(bbox_y, o->y());
|
|
bbox_r = bbox_max(bbox_r, o->x() + o->w());
|
|
bbox_b = bbox_max(bbox_b, o->y() + o->h());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static int vars_cx_cb(const Fluid_Coord_Input*, void *v) {
|
|
calculate_bbox((Fl_Type*)v);
|
|
return bbox_x;
|
|
}
|
|
|
|
static int vars_cy_cb(const Fluid_Coord_Input*, void *v) {
|
|
calculate_bbox((Fl_Type*)v);
|
|
return bbox_y;
|
|
}
|
|
|
|
static int vars_cw_cb(const Fluid_Coord_Input*, void *v) {
|
|
calculate_bbox((Fl_Type*)v);
|
|
return bbox_r - bbox_x;
|
|
}
|
|
|
|
static int vars_ch_cb(const Fluid_Coord_Input*, void *v) {
|
|
calculate_bbox((Fl_Type*)v);
|
|
return bbox_b - bbox_y;
|
|
}
|
|
|
|
Fluid_Coord_Input_Vars widget_vars[] = {
|
|
{ "i", vars_i_cb }, // zero based counter of selected widgets
|
|
{ "x", vars_x_cb }, // position and size of current widget
|
|
{ "y", vars_y_cb },
|
|
{ "w", vars_w_cb },
|
|
{ "h", vars_h_cb },
|
|
{ "px", vars_px_cb }, // position and size of parent widget
|
|
{ "py", vars_py_cb },
|
|
{ "pw", vars_pw_cb },
|
|
{ "ph", vars_ph_cb },
|
|
{ "sx", vars_sx_cb }, // position and size of previous sibling
|
|
{ "sy", vars_sy_cb },
|
|
{ "sw", vars_sw_cb },
|
|
{ "sh", vars_sh_cb },
|
|
{ "cx", vars_cx_cb }, // position and size of bounding box of all children
|
|
{ "cy", vars_cy_cb },
|
|
{ "cw", vars_cw_cb },
|
|
{ "ch", vars_ch_cb },
|
|
{ 0 }
|
|
};
|
|
|
|
void x_cb(Fluid_Coord_Input *i, void *v) {
|
|
if (v == LOAD) {
|
|
x_input = i;
|
|
if (current_widget->is_true_widget()) {
|
|
i->value(((Fl_Widget_Type *)current_widget)->o->x());
|
|
x_input->activate();
|
|
} else x_input->deactivate();
|
|
} else {
|
|
undo_checkpoint();
|
|
widget_i = 0;
|
|
int mod = 0;
|
|
int v = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_true_widget()) {
|
|
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
|
|
i->variables(widget_vars, o);
|
|
v = i->value();
|
|
w->resize(v, w->y(), w->w(), w->h());
|
|
if (w->window()) w->window()->redraw();
|
|
widget_i++;
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) {
|
|
set_modflag(1);
|
|
i->value(v); // change the displayed value to the result of the last
|
|
// calculation. Keep the formula if it was not used.
|
|
}
|
|
}
|
|
}
|
|
|
|
void y_cb(Fluid_Coord_Input *i, void *v) {
|
|
if (v == LOAD) {
|
|
y_input = i;
|
|
if (current_widget->is_true_widget()) {
|
|
i->value(((Fl_Widget_Type *)current_widget)->o->y());
|
|
y_input->activate();
|
|
} else y_input->deactivate();
|
|
} else {
|
|
undo_checkpoint();
|
|
widget_i = 0;
|
|
int mod = 0;
|
|
int v = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_true_widget()) {
|
|
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
|
|
i->variables(widget_vars, o);
|
|
v = i->value();
|
|
w->resize(w->x(), v, w->w(), w->h());
|
|
if (w->window()) w->window()->redraw();
|
|
widget_i++;
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) {
|
|
set_modflag(1);
|
|
i->value(v);
|
|
}
|
|
}
|
|
}
|
|
|
|
void w_cb(Fluid_Coord_Input *i, void *v) {
|
|
if (v == LOAD) {
|
|
w_input = i;
|
|
if (current_widget->is_true_widget()) {
|
|
i->value(((Fl_Widget_Type *)current_widget)->o->w());
|
|
w_input->activate();
|
|
} else w_input->deactivate();
|
|
} else {
|
|
undo_checkpoint();
|
|
widget_i = 0;
|
|
int mod = 0;
|
|
int v = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_true_widget()) {
|
|
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
|
|
i->variables(widget_vars, o);
|
|
v = i->value();
|
|
w->resize(w->x(), w->y(), v, w->h());
|
|
if (w->window()) w->window()->redraw();
|
|
widget_i++;
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) {
|
|
set_modflag(1);
|
|
i->value(v);
|
|
}
|
|
}
|
|
}
|
|
|
|
void h_cb(Fluid_Coord_Input *i, void *v) {
|
|
if (v == LOAD) {
|
|
h_input = i;
|
|
if (current_widget->is_true_widget()) {
|
|
i->value(((Fl_Widget_Type *)current_widget)->o->h());
|
|
h_input->activate();
|
|
} else h_input->deactivate();
|
|
} else {
|
|
undo_checkpoint();
|
|
widget_i = 0;
|
|
int mod = 0;
|
|
int v = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_true_widget()) {
|
|
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
|
|
i->variables(widget_vars, o);
|
|
v = i->value();
|
|
w->resize(w->x(), w->y(), w->w(), v);
|
|
if (w->window()) w->window()->redraw();
|
|
widget_i++;
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) {
|
|
set_modflag(1);
|
|
i->value(v);
|
|
}
|
|
}
|
|
}
|
|
|
|
void wc_relative_cb(Fl_Choice *i, void *v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Widget_Class)) {
|
|
i->show();
|
|
i->value(((Fl_Widget_Class_Type *)current_widget)->wc_relative);
|
|
} else {
|
|
i->hide();
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && current_widget->is_a(ID_Widget_Class)) {
|
|
Fl_Widget_Class_Type *t = (Fl_Widget_Class_Type *)o;
|
|
t->wc_relative = i->value();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// turn number to string or string to number for saving to file:
|
|
// does not work for hierarchical menus!
|
|
|
|
const char *item_name(Fl_Menu_Item* m, int i) {
|
|
if (m) {
|
|
while (m->label()) {
|
|
if (m->argument() == i) return m->label();
|
|
m++;
|
|
}
|
|
}
|
|
static char buffer[20];
|
|
sprintf(buffer, "%d", i);
|
|
return buffer;
|
|
}
|
|
int item_number(Fl_Menu_Item* m, const char* i) {
|
|
if (!i)
|
|
return 0;
|
|
if (m && i) {
|
|
if (i[0]=='F' && i[1]=='L' && i[2]=='_') i += 3;
|
|
while (m->label()) {
|
|
if (!strcmp(m->label(), i)) return int(m->argument());
|
|
m++;
|
|
}
|
|
}
|
|
return atoi(i);
|
|
}
|
|
|
|
#define ZERO_ENTRY 1000
|
|
|
|
Fl_Menu_Item boxmenu[] = {
|
|
{"NO_BOX",0,0,(void *)ZERO_ENTRY},
|
|
{"boxes",0,0,0,FL_SUBMENU},
|
|
{"UP_BOX",0,0,(void *)FL_UP_BOX},
|
|
{"DOWN_BOX",0,0,(void *)FL_DOWN_BOX},
|
|
{"FLAT_BOX",0,0,(void *)FL_FLAT_BOX},
|
|
{"BORDER_BOX",0,0,(void *)FL_BORDER_BOX},
|
|
{"THIN_UP_BOX",0,0,(void *)FL_THIN_UP_BOX},
|
|
{"THIN_DOWN_BOX",0,0,(void *)FL_THIN_DOWN_BOX},
|
|
{"ENGRAVED_BOX",0,0,(void *)FL_ENGRAVED_BOX},
|
|
{"EMBOSSED_BOX",0,0,(void *)FL_EMBOSSED_BOX},
|
|
{"ROUND_UP_BOX",0,0,(void *)FL_ROUND_UP_BOX},
|
|
{"ROUND_DOWN_BOX",0,0,(void *)FL_ROUND_DOWN_BOX},
|
|
{"DIAMOND_UP_BOX",0,0,(void *)FL_DIAMOND_UP_BOX},
|
|
{"DIAMOND_DOWN_BOX",0,0,(void *)FL_DIAMOND_DOWN_BOX},
|
|
{"SHADOW_BOX",0,0,(void *)FL_SHADOW_BOX},
|
|
{"ROUNDED_BOX",0,0,(void *)FL_ROUNDED_BOX},
|
|
{"RSHADOW_BOX",0,0,(void *)FL_RSHADOW_BOX},
|
|
{"RFLAT_BOX",0,0,(void *)FL_RFLAT_BOX},
|
|
{"OVAL_BOX",0,0,(void *)FL_OVAL_BOX},
|
|
{"OSHADOW_BOX",0,0,(void *)FL_OSHADOW_BOX},
|
|
{"OFLAT_BOX",0,0,(void *)FL_OFLAT_BOX},
|
|
{"PLASTIC_UP_BOX",0,0,(void *)FL_PLASTIC_UP_BOX},
|
|
{"PLASTIC_DOWN_BOX",0,0,(void *)FL_PLASTIC_DOWN_BOX},
|
|
{"PLASTIC_THIN_UP_BOX",0,0,(void *)FL_PLASTIC_THIN_UP_BOX},
|
|
{"PLASTIC_THIN_DOWN_BOX",0,0,(void *)FL_PLASTIC_THIN_DOWN_BOX},
|
|
{"PLASTIC_ROUND_UP_BOX",0,0,(void *)FL_PLASTIC_ROUND_UP_BOX},
|
|
{"PLASTIC_ROUND_DOWN_BOX",0,0,(void *)FL_PLASTIC_ROUND_DOWN_BOX},
|
|
{"GTK_UP_BOX",0,0,(void *)FL_GTK_UP_BOX},
|
|
{"GTK_DOWN_BOX",0,0,(void *)FL_GTK_DOWN_BOX},
|
|
{"GTK_THIN_UP_BOX",0,0,(void *)FL_GTK_THIN_UP_BOX},
|
|
{"GTK_THIN_DOWN_BOX",0,0,(void *)FL_GTK_THIN_DOWN_BOX},
|
|
{"GTK_ROUND_UP_BOX",0,0,(void *)FL_GTK_ROUND_UP_BOX},
|
|
{"GTK_ROUND_DOWN_BOX",0,0,(void *)FL_GTK_ROUND_DOWN_BOX},
|
|
{"GLEAM_UP_BOX",0,0,(void *)FL_GLEAM_UP_BOX},
|
|
{"GLEAM_DOWN_BOX",0,0,(void *)FL_GLEAM_DOWN_BOX},
|
|
{"GLEAM_THIN_UP_BOX",0,0,(void *)FL_GLEAM_THIN_UP_BOX},
|
|
{"GLEAM_THIN_DOWN_BOX",0,0,(void *)FL_GLEAM_THIN_DOWN_BOX},
|
|
{"GLEAM_ROUND_UP_BOX",0,0,(void *)FL_GLEAM_ROUND_UP_BOX},
|
|
{"GLEAM_ROUND_DOWN_BOX",0,0,(void *)FL_GLEAM_ROUND_DOWN_BOX},
|
|
{"OXY_UP_BOX",0,0,(void *)FL_OXY_UP_BOX},
|
|
{"OXY_DOWN_BOX",0,0,(void *)FL_OXY_DOWN_BOX},
|
|
{"OXY_THIN_UP_BOX",0,0,(void *)FL_OXY_THIN_UP_BOX},
|
|
{"OXY_THIN_DOWN_BOX",0,0,(void *)FL_OXY_THIN_DOWN_BOX},
|
|
{"OXY_ROUND_UP_BOX",0,0,(void *)FL_OXY_ROUND_UP_BOX},
|
|
{"OXY_ROUND_DOWN_BOX",0,0,(void *)FL_OXY_ROUND_DOWN_BOX},
|
|
{"OXY_BUTTON_UP_BOX",0,0,(void *)FL_OXY_BUTTON_UP_BOX},
|
|
{"OXY_BUTTON_DOWN_BOX",0,0,(void *)FL_OXY_BUTTON_DOWN_BOX},
|
|
{0},
|
|
{"frames",0,0,0,FL_SUBMENU},
|
|
{"UP_FRAME",0,0,(void *)FL_UP_FRAME},
|
|
{"DOWN_FRAME",0,0,(void *)FL_DOWN_FRAME},
|
|
{"THIN_UP_FRAME",0,0,(void *)FL_THIN_UP_FRAME},
|
|
{"THIN_DOWN_FRAME",0,0,(void *)FL_THIN_DOWN_FRAME},
|
|
{"ENGRAVED_FRAME",0,0,(void *)FL_ENGRAVED_FRAME},
|
|
{"EMBOSSED_FRAME",0,0,(void *)FL_EMBOSSED_FRAME},
|
|
{"BORDER_FRAME",0,0,(void *)FL_BORDER_FRAME},
|
|
{"SHADOW_FRAME",0,0,(void *)FL_SHADOW_FRAME},
|
|
{"ROUNDED_FRAME",0,0,(void *)FL_ROUNDED_FRAME},
|
|
{"OVAL_FRAME",0,0,(void *)FL_OVAL_FRAME},
|
|
{"PLASTIC_UP_FRAME",0,0,(void *)FL_PLASTIC_UP_FRAME},
|
|
{"PLASTIC_DOWN_FRAME",0,0,(void *)FL_PLASTIC_DOWN_FRAME},
|
|
{"GTK_UP_FRAME",0,0,(void *)FL_GTK_UP_FRAME},
|
|
{"GTK_DOWN_FRAME",0,0,(void *)FL_GTK_DOWN_FRAME},
|
|
{"GTK_THIN_UP_FRAME",0,0,(void *)FL_GTK_THIN_UP_FRAME},
|
|
{"GTK_THIN_DOWN_FRAME",0,0,(void *)FL_GTK_THIN_DOWN_FRAME},
|
|
{"GLEAM_UP_FRAME",0,0,(void *)FL_GLEAM_UP_FRAME},
|
|
{"GLEAM_DOWN_FRAME",0,0,(void *)FL_GLEAM_DOWN_FRAME},
|
|
{"OXY_UP_FRAME",0,0,(void *)FL_OXY_UP_FRAME},
|
|
{"OXY_DOWN_FRAME",0,0,(void *)FL_OXY_DOWN_FRAME},
|
|
{"OXY_THIN_UP_FRAME",0,0,(void *)FL_OXY_THIN_UP_FRAME},
|
|
{"OXY_THIN_DOWN_FRAME",0,0,(void *)FL_OXY_THIN_DOWN_FRAME},
|
|
{0},
|
|
{0}};
|
|
|
|
const char *boxname(int i) {
|
|
if (!i) i = ZERO_ENTRY;
|
|
for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
|
|
if (boxmenu[j].argument() == i) return boxmenu[j].label();
|
|
return 0;
|
|
}
|
|
|
|
int boxnumber(const char *i) {
|
|
if (i[0]=='F' && i[1]=='L' && i[2]=='_') i += 3;
|
|
for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
|
|
if (boxmenu[j].label() && !strcmp(boxmenu[j].label(), i)) {
|
|
return int(boxmenu[j].argument());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void box_cb(Fl_Choice* i, void *v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
|
|
int n = current_widget->o->box(); if (!n) n = ZERO_ENTRY;
|
|
for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
|
|
if (boxmenu[j].argument() == n) {i->value(j); break;}
|
|
} else {
|
|
int mod = 0;
|
|
int m = i->value();
|
|
int n = int(boxmenu[m].argument());
|
|
if (!n) return; // should not happen
|
|
if (n == ZERO_ENTRY) n = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
q->o->box((Fl_Boxtype)n);
|
|
q->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void down_box_cb(Fl_Choice* i, void *v) {
|
|
if (v == LOAD) {
|
|
int n;
|
|
if (current_widget->is_a(ID_Button))
|
|
n = ((Fl_Button*)(current_widget->o))->down_box();
|
|
else if (current_widget->is_a(ID_Input_Choice))
|
|
n = ((Fl_Input_Choice*)(current_widget->o))->down_box();
|
|
else if (current_widget->is_a(ID_Menu_Manager_))
|
|
n = ((Fl_Menu_*)(current_widget->o))->down_box();
|
|
else {
|
|
i->deactivate(); return;
|
|
}
|
|
i->activate();
|
|
if (!n) n = ZERO_ENTRY;
|
|
for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
|
|
if (boxmenu[j].argument() == n) {i->value(j); break;}
|
|
} else {
|
|
int mod = 0;
|
|
int m = i->value();
|
|
int n = int(boxmenu[m].argument());
|
|
if (!n) return; // should not happen
|
|
if (n == ZERO_ENTRY) n = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected) {
|
|
if (o->is_a(ID_Button)) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
((Fl_Button*)(q->o))->down_box((Fl_Boxtype)n);
|
|
if (((Fl_Button*)(q->o))->value()) q->redraw();
|
|
} else if (o->is_a(ID_Input_Choice)) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
((Fl_Input_Choice*)(q->o))->down_box((Fl_Boxtype)n);
|
|
} else if (o->is_a(ID_Menu_Manager_)) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
((Fl_Menu_*)(q->o))->down_box((Fl_Boxtype)n);
|
|
}
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void compact_cb(Fl_Light_Button* i, void* v) {
|
|
if (v == LOAD) {
|
|
uchar n;
|
|
if (current_widget->is_a(ID_Button) && !current_widget->is_a(ID_Menu_Item)) {
|
|
n = ((Fl_Button*)(current_widget->o))->compact();
|
|
i->value(n);
|
|
i->show();
|
|
} else {
|
|
i->hide();
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
uchar n = (uchar)i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_a(ID_Button) && !o->is_a(ID_Menu_Item)) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
uchar v = ((Fl_Button*)(q->o))->compact();
|
|
if (n != v) {
|
|
if (!mod) {
|
|
mod = 1;
|
|
undo_checkpoint();
|
|
}
|
|
((Fl_Button*)(q->o))->compact(n);
|
|
q->redraw();
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
Fl_Menu_Item whenmenu[] = {
|
|
// set individual bits
|
|
{"FL_WHEN_CHANGED",0,0,(void*)FL_WHEN_CHANGED, FL_MENU_TOGGLE},
|
|
{"FL_WHEN_NOT_CHANGED",0,0,(void*)FL_WHEN_NOT_CHANGED, FL_MENU_TOGGLE},
|
|
{"FL_WHEN_RELEASE",0,0,(void*)FL_WHEN_RELEASE, FL_MENU_TOGGLE},
|
|
{"FL_WHEN_ENTER_KEY",0,0,(void*)FL_WHEN_ENTER_KEY, FL_MENU_TOGGLE},
|
|
{"FL_WHEN_CLOSED",0,0,(void*)FL_WHEN_CLOSED, FL_MENU_TOGGLE|FL_MENU_DIVIDER},
|
|
// set bit combinations
|
|
{"FL_WHEN_NEVER",0,0,(void*)FL_WHEN_NEVER},
|
|
{"FL_WHEN_RELEASE_ALWAYS",0,0,(void*)FL_WHEN_RELEASE_ALWAYS},
|
|
{"FL_WHEN_ENTER_KEY_ALWAYS",0,0,(void*)FL_WHEN_ENTER_KEY_ALWAYS},
|
|
{"FL_WHEN_ENTER_KEY_CHANGED",0,0,(void*)FL_WHEN_ENTER_KEY_CHANGED},
|
|
{0}};
|
|
|
|
|
|
static Fl_Menu_Item whensymbolmenu[] = {
|
|
/* 0 */ {"FL_WHEN_NEVER",0,0,(void*)FL_WHEN_NEVER},
|
|
/* 1 */ {"FL_WHEN_CHANGED",0,0,(void*)FL_WHEN_CHANGED},
|
|
/* 2 */ {"FL_WHEN_NOT_CHANGED",0,0,(void*)FL_WHEN_NOT_CHANGED},
|
|
/* 3 */ {"FL_WHEN_CHANGED | FL_WHEN_NOT_CHANGED",0,0,(void*)(FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED)},
|
|
/* 4 */ {"FL_WHEN_RELEASE",0,0,(void*)FL_WHEN_RELEASE},
|
|
/* 5 */ {"FL_WHEN_CHANGED | FL_WHEN_RELEASE",0,0,(void*)(FL_WHEN_CHANGED|FL_WHEN_RELEASE)},
|
|
/* 6 */ {"FL_WHEN_RELEASE_ALWAYS",0,0,(void*)FL_WHEN_RELEASE_ALWAYS},
|
|
/* 7 */ {"FL_WHEN_CHANGED | FL_WHEN_RELEASE_ALWAYS",0,0,(void*)(FL_WHEN_CHANGED|FL_WHEN_RELEASE_ALWAYS)},
|
|
/* 8 */ {"FL_WHEN_ENTER_KEY",0,0,(void*)FL_WHEN_ENTER_KEY},
|
|
/* 9 */ {"FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY",0,0,(void*)(FL_WHEN_CHANGED|FL_WHEN_ENTER_KEY)},
|
|
/* 10 */ {"FL_WHEN_ENTER_KEY_ALWAYS",0,0,(void*)FL_WHEN_ENTER_KEY_ALWAYS},
|
|
/* 11 */ {"FL_WHEN_ENTER_KEY_CHANGED",0,0,(void*)FL_WHEN_ENTER_KEY_CHANGED},
|
|
/* 12 */ {"FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY",0,0,(void*)(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY)},
|
|
/* 13 */ {"FL_WHEN_RELEASE | FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY",0,0,(void*)(FL_WHEN_RELEASE|FL_WHEN_CHANGED|FL_WHEN_ENTER_KEY)},
|
|
/* 14 */ {"FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY_ALWAYS",0,0,(void*)(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY_ALWAYS)},
|
|
/* 15 */ {"FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY_CHANGED",0,0,(void*)(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY_CHANGED)},
|
|
{0}
|
|
};
|
|
|
|
// Return a text string representing the Fl_When value n
|
|
const char* when_symbol_name(int n) {
|
|
static char sym[128];
|
|
if (n == FL_WHEN_CLOSED) {
|
|
strcpy(sym, "FL_WHEN_CLOSED");
|
|
} else {
|
|
strcpy(sym, whensymbolmenu[n&15].label());
|
|
if (n & FL_WHEN_CLOSED)
|
|
strcat(sym, " | FL_WHEN_CLOSED");
|
|
}
|
|
return sym;
|
|
}
|
|
|
|
// Set the check marks in the "when()" menu according to the Fl_When value n
|
|
void set_whenmenu(int n) {
|
|
if (n&FL_WHEN_CHANGED) whenmenu[0].set(); else whenmenu[0].clear();
|
|
if (n&FL_WHEN_NOT_CHANGED) whenmenu[1].set(); else whenmenu[1].clear();
|
|
if (n&FL_WHEN_RELEASE) whenmenu[2].set(); else whenmenu[2].clear();
|
|
if (n&FL_WHEN_ENTER_KEY) whenmenu[3].set(); else whenmenu[3].clear();
|
|
if (n&FL_WHEN_CLOSED) whenmenu[4].set(); else whenmenu[4].clear();
|
|
}
|
|
|
|
void when_cb(Fl_Menu_Button* i, void *v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
|
|
int n = current_widget->o->when();
|
|
set_whenmenu(n);
|
|
w_when_box->copy_label(when_symbol_name(n));
|
|
} else {
|
|
int mod = 0;
|
|
int n = 0;
|
|
if (i->mvalue() && ((i->mvalue()->flags & FL_MENU_TOGGLE) == 0) ) {
|
|
n = (int)i->mvalue()->argument();
|
|
set_whenmenu(n);
|
|
} else {
|
|
if (whenmenu[0].value()) n |= FL_WHEN_CHANGED;
|
|
if (whenmenu[1].value()) n |= FL_WHEN_NOT_CHANGED;
|
|
if (whenmenu[2].value()) n |= FL_WHEN_RELEASE;
|
|
if (whenmenu[3].value()) n |= FL_WHEN_ENTER_KEY;
|
|
if (whenmenu[4].value()) n |= FL_WHEN_CLOSED;
|
|
}
|
|
w_when_box->copy_label(when_symbol_name(n));
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
q->o->when(n);
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
uchar Fl_Widget_Type::resizable() const {
|
|
if (is_a(ID_Window)) return ((Fl_Window*)o)->resizable() != 0;
|
|
Fl_Group* p = (Fl_Group*)o->parent();
|
|
if (p) return p->resizable() == o;
|
|
else return 0;
|
|
}
|
|
|
|
void Fl_Widget_Type::resizable(uchar v) {
|
|
if (v) {
|
|
if (resizable()) return;
|
|
if (is_a(ID_Window)) ((Fl_Window*)o)->resizable(o);
|
|
else {
|
|
Fl_Group* p = (Fl_Group*)o->parent();
|
|
if (p) p->resizable(o);
|
|
}
|
|
} else {
|
|
if (!resizable()) return;
|
|
if (is_a(ID_Window)) {
|
|
((Fl_Window*)o)->resizable(0);
|
|
} else {
|
|
Fl_Group* p = (Fl_Group*)o->parent();
|
|
if (p) p->resizable(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void resizable_cb(Fl_Light_Button* i,void* v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;}
|
|
if (numselected > 1) {i->deactivate(); return;}
|
|
i->activate();
|
|
i->value(current_widget->resizable());
|
|
} else {
|
|
undo_checkpoint();
|
|
current_widget->resizable(i->value());
|
|
set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void hotspot_cb(Fl_Light_Button* i,void* v) {
|
|
if (v == LOAD) {
|
|
if (numselected > 1) {i->deactivate(); return;}
|
|
if (current_widget->is_a(ID_Menu_Item)) i->label("divider");
|
|
else i->label("hotspot");
|
|
i->activate();
|
|
i->value(current_widget->hotspot());
|
|
} else {
|
|
undo_checkpoint();
|
|
current_widget->hotspot(i->value());
|
|
if (current_widget->is_a(ID_Menu_Item)) {
|
|
current_widget->redraw();
|
|
return;
|
|
}
|
|
if (i->value()) {
|
|
Fl_Type *p = current_widget->parent;
|
|
if (!p || !p->is_widget()) return;
|
|
while (!p->is_a(ID_Window)) p = p->parent;
|
|
for (Fl_Type *o = p->next; o && o->level > p->level; o = o->next) {
|
|
if (o->is_widget() && o != current_widget)
|
|
((Fl_Widget_Type*)o)->hotspot(0);
|
|
}
|
|
}
|
|
set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void visible_cb(Fl_Light_Button* i, void* v) {
|
|
if (v == LOAD) {
|
|
i->value(current_widget->o->visible());
|
|
if (current_widget->is_a(ID_Window)) i->deactivate();
|
|
else i->activate();
|
|
} else {
|
|
int mod = 0;
|
|
int n = i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
if (!mod) {
|
|
mod = 1;
|
|
undo_checkpoint();
|
|
}
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
n ? q->o->show() : q->o->hide();
|
|
q->redraw();
|
|
if (n && q->parent && q->parent->type_name()) {
|
|
if (q->parent->is_a(ID_Tabs)) {
|
|
((Fl_Tabs *)q->o->parent())->value(q->o);
|
|
} else if (q->parent->is_a(ID_Wizard)) {
|
|
((Fl_Wizard *)q->o->parent())->value(q->o);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (mod) {
|
|
set_modflag(1);
|
|
redraw_browser();
|
|
}
|
|
}
|
|
}
|
|
|
|
void active_cb(Fl_Light_Button* i, void* v) {
|
|
if (v == LOAD) {
|
|
i->value(current_widget->o->active());
|
|
if (current_widget->is_a(ID_Window)) i->deactivate();
|
|
else i->activate();
|
|
} else {
|
|
int mod = 0;
|
|
int n = i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
if (!mod) {
|
|
mod = 1;
|
|
undo_checkpoint();
|
|
}
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
n ? q->o->activate() : q->o->deactivate();
|
|
q->redraw();
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
Fl_Menu_Item fontmenu[] = {
|
|
{"Helvetica"},
|
|
{"Helvetica bold"},
|
|
{"Helvetica italic"},
|
|
{"Helvetica bold italic"},
|
|
{"Courier"},
|
|
{"Courier bold"},
|
|
{"Courier italic"},
|
|
{"Courier bold italic"},
|
|
{"Times"},
|
|
{"Times bold"},
|
|
{"Times italic"},
|
|
{"Times bold italic"},
|
|
{"Symbol"},
|
|
{"Terminal"},
|
|
{"Terminal Bold"},
|
|
{"Zapf Dingbats"},
|
|
{NULL}
|
|
};
|
|
|
|
Fl_Menu_Item fontmenu_w_default[] = {
|
|
{"<default>", 0, NULL, NULL, FL_MENU_DIVIDER},
|
|
{"Helvetica"},
|
|
{"Helvetica bold"},
|
|
{"Helvetica italic"},
|
|
{"Helvetica bold italic"},
|
|
{"Courier"},
|
|
{"Courier bold"},
|
|
{"Courier italic"},
|
|
{"Courier bold italic"},
|
|
{"Times"},
|
|
{"Times bold"},
|
|
{"Times italic"},
|
|
{"Times bold italic"},
|
|
{"Symbol"},
|
|
{"Terminal"},
|
|
{"Terminal Bold"},
|
|
{"Zapf Dingbats"},
|
|
{NULL}
|
|
};
|
|
|
|
void labelfont_cb(Fl_Choice* i, void *v) {
|
|
if (v == LOAD) {
|
|
int n = current_widget->o->labelfont();
|
|
if (n > 15) n = 0;
|
|
i->value(n);
|
|
} else {
|
|
int mod = 0;
|
|
int n = i->value();
|
|
if (n <= 0) n = layout->labelfont;
|
|
if (n <= 0) n = FL_HELVETICA;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
q->o->labelfont(n);
|
|
q->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void labelsize_cb(Fl_Value_Input* i, void *v) {
|
|
int n;
|
|
if (v == LOAD) {
|
|
n = current_widget->o->labelsize();
|
|
} else {
|
|
int mod = 0;
|
|
n = int(i->value());
|
|
if (n <= 0) n = layout->labelsize;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
q->o->labelsize(n);
|
|
q->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
i->value(n);
|
|
}
|
|
|
|
extern const char *ui_find_image_name;
|
|
|
|
Fl_Menu_Item labeltypemenu[] = {
|
|
{"NORMAL_LABEL",0,0,(void*)0},
|
|
{"SHADOW_LABEL",0,0,(void*)FL_SHADOW_LABEL},
|
|
{"ENGRAVED_LABEL",0,0,(void*)FL_ENGRAVED_LABEL},
|
|
{"EMBOSSED_LABEL",0,0,(void*)FL_EMBOSSED_LABEL},
|
|
{"NO_LABEL",0,0,(void*)(FL_NO_LABEL)},
|
|
{0}};
|
|
|
|
void labeltype_cb(Fl_Choice* i, void *v) {
|
|
if (v == LOAD) {
|
|
int n;
|
|
n = current_widget->o->labeltype();
|
|
i->when(FL_WHEN_RELEASE);
|
|
for (int j = 0; j < int(sizeof(labeltypemenu)/sizeof(*labeltypemenu)); j++)
|
|
if (labeltypemenu[j].argument() == n) {i->value(j); break;}
|
|
} else {
|
|
int mod = 0;
|
|
int m = i->value();
|
|
int n = int(labeltypemenu[m].argument());
|
|
if (n<0) return; // should not happen
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* p = (Fl_Widget_Type*)o;
|
|
p->o->labeltype((Fl_Labeltype)n);
|
|
p->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
Fl_Menu_Item colormenu[] = {
|
|
{ "Foreground Color", 0, 0, (void*)(fl_intptr_t)FL_FOREGROUND_COLOR, 0, 0, FL_HELVETICA, 11},
|
|
{ "Background Color", 0, 0, (void*)(fl_intptr_t)FL_BACKGROUND_COLOR, 0, 0, FL_HELVETICA, 11},
|
|
{ "Background Color 2", 0, 0, (void*)(fl_intptr_t)FL_BACKGROUND2_COLOR, 0, 0, FL_HELVETICA, 11},
|
|
{ "Selection Color", 0, 0, (void*)(fl_intptr_t)FL_SELECTION_COLOR, 0, 0, FL_HELVETICA, 11},
|
|
{ "Inactive Color", 0, 0, (void*)(fl_intptr_t)FL_INACTIVE_COLOR, FL_MENU_DIVIDER, 0, FL_HELVETICA, 11},
|
|
{ "Black", 0, 0, (void*)(fl_intptr_t)FL_BLACK, 0, 0, FL_HELVETICA, 11},
|
|
{ "White", 0, 0, (void*)(fl_intptr_t)FL_WHITE, FL_MENU_DIVIDER, 0, FL_HELVETICA, 11},
|
|
{ "Gray 0", 0, 0, (void*)(fl_intptr_t)FL_GRAY0, 0, 0, FL_HELVETICA, 11},
|
|
{ "Dark 3", 0, 0, (void*)(fl_intptr_t)FL_DARK3, 0, 0, FL_HELVETICA, 11},
|
|
{ "Dark 2", 0, 0, (void*)(fl_intptr_t)FL_DARK2, 0, 0, FL_HELVETICA, 11},
|
|
{ "Dark 1", 0, 0, (void*)(fl_intptr_t)FL_DARK1, 0, 0, FL_HELVETICA, 11},
|
|
{ "Light 1", 0, 0, (void*)(fl_intptr_t)FL_LIGHT1, 0, 0, FL_HELVETICA, 11},
|
|
{ "Light 2", 0, 0, (void*)(fl_intptr_t)FL_LIGHT2, 0, 0, FL_HELVETICA, 11},
|
|
{ "Light 3", 0, 0, (void*)(fl_intptr_t)FL_LIGHT3, 0, 0, FL_HELVETICA, 11},
|
|
{ 0 }
|
|
};
|
|
|
|
void color_common(Fl_Color c) {
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
q->o->color(c); q->o->redraw();
|
|
if (q->parent && q->parent->is_a(ID_Tabs)) {
|
|
if (q->o->parent()) q->o->parent()->redraw();
|
|
}
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
|
|
void color_cb(Fl_Button* i, void *v) {
|
|
Fl_Color c = current_widget->o->color();
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
|
|
} else {
|
|
Fl_Color d = fl_show_colormap(c);
|
|
if (d == c) return;
|
|
c = d;
|
|
color_common(c);
|
|
}
|
|
i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw();
|
|
}
|
|
|
|
void color_menu_cb(Fl_Menu_Button* i, void *v) {
|
|
Fl_Color c = current_widget->o->color();
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
|
|
} else {
|
|
Fl_Color d = (Fl_Color)(i->mvalue()->argument());
|
|
if (d == c) return;
|
|
c = d;
|
|
color_common(c);
|
|
w_color->color(c); w_color->labelcolor(fl_contrast(FL_BLACK,c)); w_color->redraw();
|
|
}
|
|
}
|
|
|
|
void color2_common(Fl_Color c) {
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
q->o->selection_color(c); q->o->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
|
|
void color2_cb(Fl_Button* i, void *v) {
|
|
Fl_Color c = current_widget->o->selection_color();
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
|
|
} else {
|
|
Fl_Color d = fl_show_colormap(c);
|
|
if (d == c) return;
|
|
c = d;
|
|
color2_common(c);
|
|
}
|
|
i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw();
|
|
}
|
|
|
|
void color2_menu_cb(Fl_Menu_Button* i, void *v) {
|
|
Fl_Color c = current_widget->o->selection_color();
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
|
|
} else {
|
|
Fl_Color d = (Fl_Color)(i->mvalue()->argument());
|
|
if (d == c) return;
|
|
c = d;
|
|
color2_common(c);
|
|
w_selectcolor->color(c); w_selectcolor->labelcolor(fl_contrast(FL_BLACK,c)); w_selectcolor->redraw();
|
|
}
|
|
}
|
|
|
|
void labelcolor_common(Fl_Color c) {
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
q->o->labelcolor(c); q->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
|
|
void labelcolor_cb(Fl_Button* i, void *v) {
|
|
Fl_Color c = current_widget->o->labelcolor();
|
|
if (v != LOAD) {
|
|
Fl_Color d = fl_show_colormap(c);
|
|
if (d == c) return;
|
|
c = d;
|
|
labelcolor_common(c);
|
|
}
|
|
i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw();
|
|
}
|
|
|
|
void labelcolor_menu_cb(Fl_Menu_Button* i, void *v) {
|
|
Fl_Color c = current_widget->o->labelcolor();
|
|
if (v != LOAD) {
|
|
Fl_Color d = (Fl_Color)(i->mvalue()->argument());
|
|
if (d == c) return;
|
|
c = d;
|
|
labelcolor_common(c);
|
|
w_labelcolor->color(c); w_labelcolor->labelcolor(fl_contrast(FL_BLACK,c)); w_labelcolor->redraw();
|
|
}
|
|
}
|
|
|
|
static Fl_Button* relative(Fl_Widget* o, int i) {
|
|
Fl_Group* g = (Fl_Group*)(o->parent());
|
|
return (Fl_Button*)(g->child(g->find(*o)+i));
|
|
}
|
|
|
|
static Fl_Menu_Item alignmenu[] = {
|
|
{"FL_ALIGN_CENTER",0,0,(void*)(fl_intptr_t)(FL_ALIGN_CENTER)},
|
|
{"FL_ALIGN_TOP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_TOP)},
|
|
{"FL_ALIGN_BOTTOM",0,0,(void*)(fl_intptr_t)(FL_ALIGN_BOTTOM)},
|
|
{"FL_ALIGN_LEFT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_LEFT)},
|
|
{"FL_ALIGN_RIGHT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_RIGHT)},
|
|
{"FL_ALIGN_INSIDE",0,0,(void*)(fl_intptr_t)(FL_ALIGN_INSIDE)},
|
|
{"FL_ALIGN_CLIP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_CLIP)},
|
|
{"FL_ALIGN_WRAP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_WRAP)},
|
|
{"FL_ALIGN_TEXT_OVER_IMAGE",0,0,(void*)(fl_intptr_t)(FL_ALIGN_TEXT_OVER_IMAGE)},
|
|
{"FL_ALIGN_TOP_LEFT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_TOP_LEFT)},
|
|
{"FL_ALIGN_TOP_RIGHT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_TOP_RIGHT)},
|
|
{"FL_ALIGN_BOTTOM_LEFT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_BOTTOM_LEFT)},
|
|
{"FL_ALIGN_BOTTOM_RIGHT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_BOTTOM_RIGHT)},
|
|
{"FL_ALIGN_LEFT_TOP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_LEFT_TOP)},
|
|
{"FL_ALIGN_RIGHT_TOP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_RIGHT_TOP)},
|
|
{"FL_ALIGN_LEFT_BOTTOM",0,0,(void*)(fl_intptr_t)(FL_ALIGN_LEFT_BOTTOM)},
|
|
{"FL_ALIGN_RIGHT_BOTTOM",0,0,(void*)(fl_intptr_t)(FL_ALIGN_RIGHT_BOTTOM)},
|
|
{0}};
|
|
|
|
void align_cb(Fl_Button* i, void *v) {
|
|
Fl_Align b = Fl_Align(fl_uintptr_t(i->user_data()));
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
|
|
i->value(current_widget->o->align() & b);
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
Fl_Align x = q->o->align();
|
|
Fl_Align y;
|
|
if (i->value()) {
|
|
y = x | b;
|
|
if (b == FL_ALIGN_LEFT || b == FL_ALIGN_TOP) {
|
|
Fl_Button *b1 = relative(i,+1);
|
|
b1->clear();
|
|
y = y & ~(b1->argument());
|
|
}
|
|
if (b == FL_ALIGN_RIGHT || b == FL_ALIGN_BOTTOM) {
|
|
Fl_Button *b1 = relative(i,-1);
|
|
b1->clear();
|
|
y = y & ~(b1->argument());
|
|
}
|
|
} else {
|
|
y = x & ~b;
|
|
}
|
|
if (x != y) {
|
|
q->o->align(y);
|
|
q->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void align_position_cb(Fl_Choice *i, void *v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
|
|
Fl_Menu_Item *mi = (Fl_Menu_Item*)i->menu();
|
|
Fl_Align b = current_widget->o->align() & FL_ALIGN_POSITION_MASK;
|
|
for (;mi->text;mi++) {
|
|
if ((Fl_Align)(mi->argument())==b)
|
|
i->value(mi);
|
|
}
|
|
} else {
|
|
const Fl_Menu_Item *mi = i->menu() + i->value();
|
|
Fl_Align b = Fl_Align(fl_uintptr_t(mi->user_data()));
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
Fl_Align x = q->o->align();
|
|
Fl_Align y = (x & ~FL_ALIGN_POSITION_MASK) | b;
|
|
if (x != y) {
|
|
q->o->align(y);
|
|
q->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void align_text_image_cb(Fl_Choice *i, void *v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
|
|
Fl_Menu_Item *mi = (Fl_Menu_Item*)i->menu();
|
|
Fl_Align b = current_widget->o->align() & FL_ALIGN_IMAGE_MASK;
|
|
for (;mi->text;mi++) {
|
|
if ((Fl_Align)(mi->argument())==b)
|
|
i->value(mi);
|
|
}
|
|
} else {
|
|
const Fl_Menu_Item *mi = i->menu() + i->value();
|
|
Fl_Align b = Fl_Align(fl_uintptr_t(mi->user_data()));
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
Fl_Align x = q->o->align();
|
|
Fl_Align y = (x & ~FL_ALIGN_IMAGE_MASK) | b;
|
|
if (x != y) {
|
|
q->o->align(y);
|
|
q->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
void callback_cb(CodeEditor* i, void *v) {
|
|
if (v == LOAD) {
|
|
const char *cbtext = current_widget->callback();
|
|
i->buffer()->text( cbtext ? cbtext : "" );
|
|
} else {
|
|
int mod = 0;
|
|
char *c = i->buffer()->text();
|
|
const char *d = c_check(c);
|
|
if (d) {
|
|
fl_message("Error in callback: %s",d);
|
|
if (i->window()) i->window()->make_current();
|
|
haderror = 1;
|
|
}
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected) {
|
|
o->callback(c);
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
free(c);
|
|
}
|
|
}
|
|
|
|
void comment_cb(Fl_Text_Editor* i, void *v) {
|
|
if (v == LOAD) {
|
|
const char *cmttext = current_widget->comment();
|
|
i->buffer()->text( cmttext ? cmttext : "" );
|
|
} else {
|
|
int mod = 0;
|
|
char *c = i->buffer()->text();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected) {
|
|
o->comment(c);
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
free(c);
|
|
}
|
|
}
|
|
|
|
void user_data_cb(Fl_Input *i, void *v) {
|
|
if (v == LOAD) {
|
|
i->value(current_widget->user_data());
|
|
} else {
|
|
int mod = 0;
|
|
const char *c = i->value();
|
|
const char *d = c_check(c);
|
|
if (d) {fl_message("Error in user_data: %s",d); haderror = 1; return;}
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected) {
|
|
o->user_data(c);
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void user_data_type_cb(Fl_Input_Choice *i, void *v) {
|
|
static const char *dflt = "void*";
|
|
if (v == LOAD) {
|
|
const char *c = current_widget->user_data_type();
|
|
if (!c) c = dflt;
|
|
i->value(c);
|
|
} else {
|
|
int mod = 0;
|
|
const char *c = i->value();
|
|
const char *d = c_check(c);
|
|
if (!*c) i->value(dflt);
|
|
else if (!strcmp(c,dflt)) c = 0;
|
|
if (!d) {
|
|
if (c && *c && c[strlen(c)-1] != '*' && strcmp(c,"long"))
|
|
d = "must be pointer or long";
|
|
}
|
|
if (d) {fl_message("Error in type: %s",d); haderror = 1; return;}
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected) {
|
|
o->user_data_type(c);
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
// "v_attributes" let user type in random code for attribute settings:
|
|
|
|
void v_input_cb(Fl_Input* i, void* v) {
|
|
int n = fl_int(i->user_data());
|
|
if (v == LOAD) {
|
|
i->value(current_widget->extra_code(n));
|
|
} else {
|
|
int mod = 0;
|
|
const char *c = i->value();
|
|
const char *d = c_check(c&&c[0]=='#' ? c+1 : c);
|
|
if (d) {fl_message("Error in %s: %s",i->label(),d); haderror = 1; return;}
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type *t = (Fl_Widget_Type*)o;
|
|
t->extra_code(n,c);
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void subclass_cb(Fl_Input* i, void* v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
|
|
i->value(current_widget->subclass());
|
|
} else {
|
|
int mod = 0;
|
|
const char *c = i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type *t = (Fl_Widget_Type*)o;
|
|
t->subclass(c);
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// textstuff: set textfont, textsize, textcolor attributes:
|
|
|
|
// default widget returns 0 to indicate not-implemented:
|
|
// The first parameter specifies the operation:
|
|
// 0: get all values
|
|
// 1: set the text font
|
|
// 2: set the text size
|
|
// 3: set the text color
|
|
// 4: get all default values for this type
|
|
int Fl_Widget_Type::textstuff(int, Fl_Font&, int&, Fl_Color&) {
|
|
return 0;
|
|
}
|
|
|
|
void textfont_cb(Fl_Choice* i, void* v) {
|
|
Fl_Font n; int s; Fl_Color c;
|
|
if (v == LOAD) {
|
|
if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;}
|
|
i->activate();
|
|
if (n > 15) n = FL_HELVETICA;
|
|
i->value(n);
|
|
} else {
|
|
int mod = 0;
|
|
n = (Fl_Font)i->value();
|
|
if (n <= 0) n = layout->textfont;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
q->textstuff(1,n,s,c);
|
|
q->o->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void textsize_cb(Fl_Value_Input* i, void* v) {
|
|
Fl_Font n; int s; Fl_Color c;
|
|
if (v == LOAD) {
|
|
if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;}
|
|
i->activate();
|
|
} else {
|
|
int mod = 0;
|
|
s = int(i->value());
|
|
if (s <= 0) s = layout->textsize;
|
|
if (s <= 0) s = layout->labelsize;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
q->textstuff(2,n,s,c);
|
|
q->o->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
i->value(s);
|
|
}
|
|
|
|
void textcolor_common(Fl_Color c) {
|
|
Fl_Font n; int s;
|
|
int mod = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
q->textstuff(3,n,s,c); q->o->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
|
|
void textcolor_cb(Fl_Button* i, void* v) {
|
|
Fl_Font n; int s; Fl_Color c;
|
|
if (v == LOAD) {
|
|
if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;}
|
|
i->activate();
|
|
} else {
|
|
c = i->color();
|
|
Fl_Color d = fl_show_colormap(c);
|
|
if (d == c) return;
|
|
c = d;
|
|
textcolor_common(c);
|
|
}
|
|
i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw();
|
|
}
|
|
|
|
void textcolor_menu_cb(Fl_Menu_Button* i, void* v) {
|
|
Fl_Font n; int s; Fl_Color c;
|
|
if (v == LOAD) {
|
|
if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;}
|
|
i->activate();
|
|
} else {
|
|
c = i->color();
|
|
Fl_Color d = (Fl_Color)(i->mvalue()->argument());
|
|
if (d == c) return;
|
|
c = d;
|
|
textcolor_common(c);
|
|
w_textcolor->color(c); w_textcolor->labelcolor(fl_contrast(FL_BLACK,c)); w_textcolor->redraw();
|
|
}
|
|
}
|
|
|
|
void image_spacing_cb(Fl_Value_Input* i, void* v) {
|
|
int s;
|
|
if (v == LOAD) {
|
|
if (!current_widget->is_true_widget()) {
|
|
i->deactivate();
|
|
i->value(0);
|
|
} else {
|
|
i->activate();
|
|
i->value(((Fl_Widget_Type*)current_widget)->o->label_image_spacing());
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
s = int(i->value());
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_true_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
if (q->o->label_image_spacing() != s) {
|
|
q->o->label_image_spacing(s);
|
|
if (!(q->o->align() & FL_ALIGN_INSIDE) && q->o->window())
|
|
q->o->window()->damage(FL_DAMAGE_EXPOSE); // outside labels
|
|
q->o->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void h_label_margin_cb(Fl_Value_Input* i, void* v) {
|
|
int s;
|
|
if (v == LOAD) {
|
|
if (!current_widget->is_true_widget()) {
|
|
i->deactivate();
|
|
i->value(0);
|
|
} else {
|
|
i->activate();
|
|
i->value(((Fl_Widget_Type*)current_widget)->o->horizontal_label_margin());
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
s = int(i->value());
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_true_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
if (q->o->horizontal_label_margin() != s) {
|
|
q->o->horizontal_label_margin(s);
|
|
if (!(q->o->align() & FL_ALIGN_INSIDE) && q->o->window())
|
|
q->o->window()->damage(FL_DAMAGE_EXPOSE); // outside labels
|
|
q->o->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void v_label_margin_cb(Fl_Value_Input* i, void* v) {
|
|
int s;
|
|
if (v == LOAD) {
|
|
if (!current_widget->is_true_widget()) {
|
|
i->deactivate();
|
|
i->value(0);
|
|
} else {
|
|
i->activate();
|
|
i->value(((Fl_Widget_Type*)current_widget)->o->vertical_label_margin());
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
s = int(i->value());
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_true_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
if (q->o->vertical_label_margin() != s) {
|
|
q->o->vertical_label_margin(s);
|
|
if (!(q->o->align() & FL_ALIGN_INSIDE) && q->o->window())
|
|
q->o->window()->damage(FL_DAMAGE_EXPOSE); // outside labels
|
|
q->o->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Kludges to the panel for subclasses:
|
|
|
|
void min_w_cb(Fl_Value_Input* i, void* v) {
|
|
if (v == LOAD) {
|
|
if (!current_widget->is_a(ID_Window)) return;
|
|
i->value(((Fl_Window_Type*)current_widget)->sr_min_w);
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
int n = (int)i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_a(ID_Window)) {
|
|
((Fl_Window_Type*)current_widget)->sr_min_w = n;
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void min_h_cb(Fl_Value_Input* i, void* v) {
|
|
if (v == LOAD) {
|
|
if (!current_widget->is_a(ID_Window)) return;
|
|
i->value(((Fl_Window_Type*)current_widget)->sr_min_h);
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
int n = (int)i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_a(ID_Window)) {
|
|
((Fl_Window_Type*)current_widget)->sr_min_h = n;
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void max_w_cb(Fl_Value_Input* i, void* v) {
|
|
if (v == LOAD) {
|
|
if (!current_widget->is_a(ID_Window)) return;
|
|
i->value(((Fl_Window_Type*)current_widget)->sr_max_w);
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
int n = (int)i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_a(ID_Window)) {
|
|
((Fl_Window_Type*)current_widget)->sr_max_w = n;
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void max_h_cb(Fl_Value_Input* i, void* v) {
|
|
if (v == LOAD) {
|
|
if (!current_widget->is_a(ID_Window)) return;
|
|
i->value(((Fl_Window_Type*)current_widget)->sr_max_h);
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
int n = (int)i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_a(ID_Window)) {
|
|
((Fl_Window_Type*)current_widget)->sr_max_h = n;
|
|
mod = 1;
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void set_min_size_cb(Fl_Button*, void* v) {
|
|
if (v == LOAD) {
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_a(ID_Window)) {
|
|
Fl_Window_Type *win = (Fl_Window_Type*)current_widget;
|
|
win->sr_min_w = win->o->w();
|
|
win->sr_min_h = win->o->h();
|
|
mod = 1;
|
|
}
|
|
}
|
|
propagate_load(the_panel, LOAD);
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void set_max_size_cb(Fl_Button*, void* v) {
|
|
if (v == LOAD) {
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_a(ID_Window)) {
|
|
Fl_Window_Type *win = (Fl_Window_Type*)current_widget;
|
|
win->sr_max_w = win->o->w();
|
|
win->sr_max_h = win->o->h();
|
|
mod = 1;
|
|
}
|
|
}
|
|
propagate_load(the_panel, LOAD);
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void slider_size_cb(Fl_Value_Input* i, void* v) {
|
|
if (v == LOAD) {
|
|
if (!current_widget->is_a(ID_Slider)) {i->deactivate(); return;}
|
|
i->activate();
|
|
i->value(((Fl_Slider*)(current_widget->o))->slider_size());
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
double n = i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
if (q->is_a(ID_Slider)) {
|
|
((Fl_Slider*)(q->o))->slider_size(n);
|
|
q->o->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void min_cb(Fl_Value_Input* i, void* v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Valuator_)) {
|
|
i->activate();
|
|
i->value(((Fl_Valuator*)(current_widget->o))->minimum());
|
|
} else if (current_widget->is_a(ID_Spinner)) {
|
|
i->activate();
|
|
i->value(((Fl_Spinner*)(current_widget->o))->minimum());
|
|
} else {
|
|
i->deactivate();
|
|
return;
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
double n = i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
if (q->is_a(ID_Valuator_)) {
|
|
((Fl_Valuator*)(q->o))->minimum(n);
|
|
q->o->redraw();
|
|
mod = 1;
|
|
} else if (q->is_a(ID_Spinner)) {
|
|
((Fl_Spinner*)(q->o))->minimum(n);
|
|
q->o->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void max_cb(Fl_Value_Input* i, void* v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Valuator_)) {
|
|
i->activate();
|
|
i->value(((Fl_Valuator*)(current_widget->o))->maximum());
|
|
} else if (current_widget->is_a(ID_Spinner)) {
|
|
i->activate();
|
|
i->value(((Fl_Spinner*)(current_widget->o))->maximum());
|
|
} else {
|
|
i->deactivate();
|
|
return;
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
double n = i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
if (q->is_a(ID_Valuator_)) {
|
|
((Fl_Valuator*)(q->o))->maximum(n);
|
|
q->o->redraw();
|
|
mod = 1;
|
|
} else if (q->is_a(ID_Spinner)) {
|
|
((Fl_Spinner*)(q->o))->maximum(n);
|
|
q->o->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void step_cb(Fl_Value_Input* i, void* v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Valuator_)) {
|
|
i->activate();
|
|
i->value(((Fl_Valuator*)(current_widget->o))->step());
|
|
} else if (current_widget->is_a(ID_Spinner)) {
|
|
i->activate();
|
|
i->value(((Fl_Spinner*)(current_widget->o))->step());
|
|
} else {
|
|
i->deactivate();
|
|
return;
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
double n = i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
if (q->is_a(ID_Valuator_)) {
|
|
((Fl_Valuator*)(q->o))->step(n);
|
|
q->o->redraw();
|
|
mod = 1;
|
|
} else if (q->is_a(ID_Spinner)) {
|
|
((Fl_Spinner*)(q->o))->step(n);
|
|
q->o->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void value_cb(Fl_Value_Input* i, void* v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Valuator_)) {
|
|
i->activate();
|
|
i->value(((Fl_Valuator*)(current_widget->o))->value());
|
|
} else if (current_widget->is_button()) {
|
|
i->activate();
|
|
i->value(((Fl_Button*)(current_widget->o))->value());
|
|
} else if (current_widget->is_a(ID_Spinner)) {
|
|
i->activate();
|
|
i->value(((Fl_Spinner*)(current_widget->o))->value());
|
|
} else
|
|
i->deactivate();
|
|
} else {
|
|
int mod = 0;
|
|
undo_checkpoint();
|
|
double n = i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
if (q->is_a(ID_Valuator_)) {
|
|
((Fl_Valuator*)(q->o))->value(n);
|
|
mod = 1;
|
|
} else if (q->is_button()) {
|
|
((Fl_Button*)(q->o))->value(n != 0);
|
|
if (q->is_a(ID_Menu_Item)) q->redraw();
|
|
mod = 1;
|
|
} else if (q->is_a(ID_Spinner)) {
|
|
((Fl_Spinner*)(q->o))->value(n);
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
// The following three callbacks cooperate, showing only one of the groups of
|
|
// widgets that use the same space in the dialog.
|
|
|
|
void values_group_cb(Fl_Group* g, void* v) {
|
|
if (v == LOAD) {
|
|
if ( current_widget->is_a(ID_Flex)
|
|
|| current_widget->is_a(ID_Grid)
|
|
|| current_widget->is_a(ID_Window))
|
|
{
|
|
g->hide();
|
|
} else {
|
|
g->show();
|
|
}
|
|
propagate_load(g, v);
|
|
}
|
|
}
|
|
|
|
void flex_margin_group_cb(Fl_Group* g, void* v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Flex)) {
|
|
g->show();
|
|
} else {
|
|
g->hide();
|
|
}
|
|
propagate_load(g, v);
|
|
}
|
|
}
|
|
|
|
void size_range_group_cb(Fl_Group* g, void* v) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Window)) {
|
|
g->show();
|
|
} else {
|
|
g->hide();
|
|
}
|
|
propagate_load(g, v);
|
|
}
|
|
}
|
|
|
|
|
|
static void flex_margin_cb(Fl_Value_Input* i, void* v,
|
|
void (*load_margin)(Fl_Flex*,Fl_Value_Input*),
|
|
int (*update_margin)(Fl_Flex*,int)) {
|
|
if (v == LOAD) {
|
|
if (current_widget->is_a(ID_Flex)) {
|
|
load_margin((Fl_Flex*)current_widget->o, i);
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
int new_value = (int)i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_a(ID_Flex)) {
|
|
Fl_Flex_Type* q = (Fl_Flex_Type*)o;
|
|
Fl_Flex* w = (Fl_Flex*)q->o;
|
|
if (update_margin(w, new_value)) {
|
|
w->layout();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
static void load_left_margin(Fl_Flex *w, Fl_Value_Input* i)
|
|
{
|
|
int v;
|
|
w->margin(&v, NULL, NULL, NULL);
|
|
i->value((double)v);
|
|
}
|
|
|
|
static int update_left_margin(Fl_Flex *w, int new_value)
|
|
{
|
|
int l, t, r, b;
|
|
w->margin(&l, &t, &r, &b);
|
|
if (new_value!=l) {
|
|
w->margin(new_value, t, r, b);
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void flex_margin_left_cb(Fl_Value_Input* i, void* v) {
|
|
flex_margin_cb(i, v, load_left_margin, update_left_margin);
|
|
}
|
|
|
|
static void load_top_margin(Fl_Flex *w, Fl_Value_Input* i)
|
|
{
|
|
int v;
|
|
w->margin(NULL, &v, NULL, NULL);
|
|
i->value((double)v);
|
|
}
|
|
|
|
static int update_top_margin(Fl_Flex *w, int new_value)
|
|
{
|
|
int l, t, r, b;
|
|
w->margin(&l, &t, &r, &b);
|
|
if (new_value!=t) {
|
|
w->margin(l, new_value, r, b);
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void flex_margin_top_cb(Fl_Value_Input* i, void* v) {
|
|
flex_margin_cb(i, v, load_top_margin, update_top_margin);
|
|
}
|
|
|
|
static void load_right_margin(Fl_Flex *w, Fl_Value_Input* i)
|
|
{
|
|
int v;
|
|
w->margin(NULL, NULL, &v, NULL);
|
|
i->value((double)v);
|
|
}
|
|
|
|
static int update_right_margin(Fl_Flex *w, int new_value)
|
|
{
|
|
int l, t, r, b;
|
|
w->margin(&l, &t, &r, &b);
|
|
if (new_value!=r) {
|
|
w->margin(l, t, new_value, b);
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void flex_margin_right_cb(Fl_Value_Input* i, void* v) {
|
|
flex_margin_cb(i, v, load_right_margin, update_right_margin);
|
|
}
|
|
|
|
static void load_bottom_margin(Fl_Flex *w, Fl_Value_Input* i)
|
|
{
|
|
int v;
|
|
w->margin(NULL, NULL, NULL, &v);
|
|
i->value((double)v);
|
|
}
|
|
|
|
static int update_bottom_margin(Fl_Flex *w, int new_value)
|
|
{
|
|
int l, t, r, b;
|
|
w->margin(&l, &t, &r, &b);
|
|
if (new_value!=b) {
|
|
w->margin(l, t, r, new_value);
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void flex_margin_bottom_cb(Fl_Value_Input* i, void* v) {
|
|
flex_margin_cb(i, v, load_bottom_margin, update_bottom_margin);
|
|
}
|
|
|
|
static void load_gap(Fl_Flex *w, Fl_Value_Input* i)
|
|
{
|
|
int v = w->gap();
|
|
i->value((double)v);
|
|
}
|
|
|
|
static int update_gap(Fl_Flex *w, int new_value)
|
|
{
|
|
int g = w->gap();
|
|
if (new_value!=g) {
|
|
w->gap(new_value);
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void flex_margin_gap_cb(Fl_Value_Input* i, void* v) {
|
|
flex_margin_cb(i, v, load_gap, update_gap);
|
|
}
|
|
|
|
void position_group_cb(Fl_Group* g, void* v) {
|
|
if (v == LOAD) {
|
|
if (Fl_Flex_Type::parent_is_flex(current_widget)) {
|
|
g->hide();
|
|
} else {
|
|
g->show();
|
|
}
|
|
}
|
|
propagate_load(g, v);
|
|
}
|
|
|
|
void flex_size_group_cb(Fl_Group* g, void* v) {
|
|
if (v == LOAD) {
|
|
if (Fl_Flex_Type::parent_is_flex(current_widget)) {
|
|
g->show();
|
|
} else {
|
|
g->hide();
|
|
}
|
|
}
|
|
propagate_load(g, v);
|
|
}
|
|
|
|
void flex_size_cb(Fl_Value_Input* i, void* v) {
|
|
if (v == LOAD) {
|
|
if (Fl_Flex_Type::parent_is_flex(current_widget)) {
|
|
i->value(Fl_Flex_Type::size(current_widget));
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
int new_size = (int)i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget() && Fl_Flex_Type::parent_is_flex(o)) {
|
|
Fl_Widget* w = (Fl_Widget*)((Fl_Widget_Type*)o)->o;
|
|
Fl_Flex* f = (Fl_Flex*)((Fl_Flex_Type*)o->parent)->o;
|
|
int was_fixed = f->fixed(w);
|
|
if (new_size==0) {
|
|
if (was_fixed) {
|
|
f->fixed(w, 0);
|
|
f->layout();
|
|
widget_flex_fixed->value(0);
|
|
mod = 1;
|
|
}
|
|
} else {
|
|
int old_size = Fl_Flex_Type::size(o);
|
|
if (old_size!=new_size || !was_fixed) {
|
|
f->fixed(w, new_size);
|
|
f->layout();
|
|
widget_flex_fixed->value(1);
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
void flex_fixed_cb(Fl_Check_Button* i, void* v) {
|
|
if (v == LOAD) {
|
|
if (Fl_Flex_Type::parent_is_flex(current_widget)) {
|
|
i->value(Fl_Flex_Type::is_fixed(current_widget));
|
|
}
|
|
} else {
|
|
int mod = 0;
|
|
int new_fixed = (int)i->value();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget() && Fl_Flex_Type::parent_is_flex(o)) {
|
|
Fl_Widget* w = (Fl_Widget*)((Fl_Widget_Type*)o)->o;
|
|
Fl_Flex* f = (Fl_Flex*)((Fl_Flex_Type*)o->parent)->o;
|
|
int was_fixed = f->fixed(w);
|
|
if (new_fixed==0) {
|
|
if (was_fixed) {
|
|
f->fixed(w, 0);
|
|
f->layout();
|
|
mod = 1;
|
|
}
|
|
} else {
|
|
if (!was_fixed) {
|
|
f->fixed(w, Fl_Flex_Type::size(o));
|
|
f->layout();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// subtypes:
|
|
|
|
Fl_Menu_Item *Fl_Widget_Type::subtypes() {return 0;}
|
|
|
|
void subtype_cb(Fl_Choice* i, void* v) {
|
|
static Fl_Menu_Item empty_type_menu[] = {
|
|
{"Normal",0,0,(void*)0},
|
|
{0}};
|
|
|
|
if (v == LOAD) {
|
|
Fl_Menu_Item* m = current_widget->subtypes();
|
|
if (!m) {
|
|
i->menu(empty_type_menu);
|
|
i->value(0);
|
|
i->deactivate();
|
|
} else {
|
|
i->menu(m);
|
|
int j;
|
|
for (j = 0;; j++) {
|
|
if (!m[j].text) {j = 0; break;}
|
|
if (current_widget->is_a(ID_Spinner)) {
|
|
if (m[j].argument() == ((Fl_Spinner*)current_widget->o)->type()) break;
|
|
} else {
|
|
if (m[j].argument() == current_widget->o->type()) break;
|
|
}
|
|
}
|
|
i->value(j);
|
|
i->activate();
|
|
}
|
|
i->redraw();
|
|
} else {
|
|
int mod = 0;
|
|
int n = int(i->mvalue()->argument());
|
|
Fl_Menu_Item* m = current_widget->subtypes();
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->selected && o->is_widget()) {
|
|
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
|
|
if (q->subtypes()==m) {
|
|
if (q->is_a(ID_Spinner))
|
|
((Fl_Spinner*)q->o)->type(n);
|
|
else if (q->is_a(ID_Flex))
|
|
((Fl_Flex_Type*)q)->change_subtype_to(n);
|
|
else
|
|
q->o->type(n);
|
|
q->redraw();
|
|
mod = 1;
|
|
}
|
|
}
|
|
}
|
|
if (mod) set_modflag(1);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
void propagate_load(Fl_Group* g, void* v) {
|
|
if (v == LOAD) {
|
|
Fl_Widget*const* a = g->array();
|
|
for (int i=g->children(); i--;) {
|
|
Fl_Widget* o = *a++;
|
|
o->do_callback(o, LOAD, FL_REASON_USER);
|
|
}
|
|
}
|
|
}
|
|
|
|
void set_cb(Fl_Button*, void*) {
|
|
haderror = 0;
|
|
Fl_Widget*const* a = the_panel->array();
|
|
for (int i=the_panel->children(); i--;) {
|
|
Fl_Widget* o = *a++;
|
|
if (o->changed()) {
|
|
o->do_callback();
|
|
if (haderror) return;
|
|
o->clear_changed();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ok_cb(Fl_Return_Button* o, void* v) {
|
|
set_cb(o,v);
|
|
if (!haderror) the_panel->hide();
|
|
}
|
|
|
|
void toggle_overlays(Fl_Widget *,void *); // in Fl_Window_Type.cxx
|
|
void overlay_cb(Fl_Button*o,void *v) {
|
|
toggle_overlays(o,v);
|
|
}
|
|
|
|
void leave_live_mode_cb(Fl_Widget*, void*);
|
|
|
|
void live_mode_cb(Fl_Button*o,void *) {
|
|
/// \todo live mode should end gracefully when the application quits
|
|
/// or when the user closes the live widget
|
|
static Fl_Type *live_type = 0L;
|
|
static Fl_Widget *live_widget = 0L;
|
|
static Fl_Window *live_window = 0L;
|
|
// if 'o' is 0, we must quit live mode
|
|
if (!o) {
|
|
o = wLiveMode;
|
|
o->value(0);
|
|
}
|
|
if (o->value()) {
|
|
if (numselected == 1) {
|
|
Fl_Group::current(0L);
|
|
live_widget = current_widget->enter_live_mode(1);
|
|
if (live_widget) {
|
|
live_type = current_widget;
|
|
Fl_Group::current(0);
|
|
int w = live_widget->w();
|
|
int h = live_widget->h();
|
|
live_window = new Fl_Double_Window(w+20, h+55, "Fluid Live Resize");
|
|
live_window->box(FL_FLAT_BOX);
|
|
live_window->color(FL_GREEN);
|
|
Fl_Group *rsz = new Fl_Group(0, h+20, 130, 35);
|
|
rsz->box(FL_NO_BOX);
|
|
Fl_Box *rsz_dummy = new Fl_Box(110, h+20, 1, 25);
|
|
rsz_dummy->box(FL_NO_BOX);
|
|
rsz->resizable(rsz_dummy);
|
|
Fl_Button *btn = new Fl_Button(10, h+20, 100, 25, "Exit Live Resize");
|
|
btn->labelsize(12);
|
|
btn->callback(leave_live_mode_cb);
|
|
rsz->end();
|
|
live_window->add(live_widget);
|
|
live_widget->position(10, 10);
|
|
live_window->resizable(live_widget);
|
|
live_window->set_modal(); // block all other UI
|
|
live_window->callback(leave_live_mode_cb);
|
|
if (current_widget->is_a(ID_Window)) {
|
|
Fl_Window_Type *w = (Fl_Window_Type*)current_widget;
|
|
int mw = w->sr_min_w; if (mw>0) mw += 20;
|
|
int mh = w->sr_min_h; if (mh>0) mh += 55;
|
|
int MW = w->sr_max_w; if (MW>0) MW += 20;
|
|
int MH = w->sr_max_h; if (MH>2) MH += 55;
|
|
if (mw || mh || MW || MH)
|
|
live_window->size_range(mw, mh, MW, MH);
|
|
}
|
|
live_window->show();
|
|
live_widget->show();
|
|
} else o->value(0);
|
|
} else o->value(0);
|
|
} else {
|
|
if (live_type)
|
|
live_type->leave_live_mode();
|
|
if (live_window) {
|
|
live_window->hide();
|
|
Fl::delete_widget(live_window);
|
|
}
|
|
live_type = 0L;
|
|
live_widget = 0L;
|
|
live_window = 0L;
|
|
}
|
|
}
|
|
|
|
// update the panel according to current widget set:
|
|
void load_panel() {
|
|
if (!the_panel) return;
|
|
|
|
// find all the Fl_Widget subclasses currently selected:
|
|
numselected = 0;
|
|
current_widget = 0;
|
|
if (Fl_Type::current) {
|
|
if (Fl_Type::current->is_widget())
|
|
current_widget=(Fl_Widget_Type*)Fl_Type::current;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
if (o->is_widget() && o->selected) {
|
|
numselected++;
|
|
if (!current_widget) current_widget = (Fl_Widget_Type*)o;
|
|
}
|
|
}
|
|
}
|
|
if (current_widget && current_widget->is_a(ID_Grid)) {
|
|
if (widget_tab_grid->parent()!=widget_tabs)
|
|
widget_tabs->add(widget_tab_grid);
|
|
} else {
|
|
if (widget_tab_grid->parent()==widget_tabs) {
|
|
widget_tabs_repo->add(widget_tab_grid);
|
|
}
|
|
}
|
|
if (current_widget && current_widget->parent && current_widget->parent->is_a(ID_Grid)) {
|
|
if (widget_tab_grid_child->parent()!=widget_tabs)
|
|
widget_tabs->add(widget_tab_grid_child);
|
|
} else {
|
|
if (widget_tab_grid_child->parent()==widget_tabs) {
|
|
widget_tabs_repo->add(widget_tab_grid_child);
|
|
}
|
|
}
|
|
if (numselected)
|
|
propagate_load(the_panel, LOAD);
|
|
else
|
|
the_panel->hide();
|
|
}
|
|
|
|
extern Fl_Window *widgetbin_panel;
|
|
|
|
// This is called when user double-clicks an item, open or update the panel:
|
|
void Fl_Widget_Type::open() {
|
|
bool adjust_position = false;
|
|
if (!the_panel) {
|
|
the_panel = make_widget_panel();
|
|
adjust_position = true;
|
|
}
|
|
load_panel();
|
|
if (numselected) {
|
|
the_panel->show();
|
|
if (adjust_position) {
|
|
if (widgetbin_panel && widgetbin_panel->visible()) {
|
|
if ( (the_panel->x()+the_panel->w() > widgetbin_panel->x())
|
|
&& (the_panel->x() < widgetbin_panel->x()+widgetbin_panel->w())
|
|
&& (the_panel->y()+the_panel->h() > widgetbin_panel->y())
|
|
&& (the_panel->y() < widgetbin_panel->y()+widgetbin_panel->h()) )
|
|
{
|
|
if (widgetbin_panel->y()+widgetbin_panel->h()+the_panel->h() > Fl::h())
|
|
the_panel->position(the_panel->x(), widgetbin_panel->y()-the_panel->h()-30);
|
|
else
|
|
the_panel->position(the_panel->x(), widgetbin_panel->y()+widgetbin_panel->h()+30);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extern void redraw_overlays();
|
|
extern void check_redraw_corresponding_parent(Fl_Type*);
|
|
extern void redraw_browser();
|
|
extern void update_codeview_position();
|
|
|
|
// Called when ui changes what objects are selected:
|
|
// p is selected object, null for all deletions (we must throw away
|
|
// old panel in that case, as the object may no longer exist)
|
|
void selection_changed(Fl_Type *p) {
|
|
// store all changes to the current selected objects:
|
|
if (p && the_panel && the_panel->visible()) {
|
|
set_cb(0,0);
|
|
// if there was an error, we try to leave the selected set unchanged:
|
|
if (haderror) {
|
|
Fl_Type *q = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
o->new_selected = o->selected;
|
|
if (!q && o->selected) q = o;
|
|
}
|
|
if (!p || !p->selected) p = q;
|
|
Fl_Type::current = p;
|
|
redraw_browser();
|
|
return;
|
|
}
|
|
}
|
|
// update the selected flags to new set:
|
|
Fl_Type *q = 0;
|
|
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
|
|
o->selected = o->new_selected;
|
|
if (!q && o->selected) q = o;
|
|
}
|
|
if (!p || !p->selected) p = q;
|
|
Fl_Type::current = p;
|
|
check_redraw_corresponding_parent(p);
|
|
redraw_overlays();
|
|
// load the panel with the new settings:
|
|
load_panel();
|
|
// update the code viewer to show the code for the selected object
|
|
update_codeview_position();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Writing the C code:
|
|
|
|
// test to see if user named a function, or typed in code:
|
|
int is_name(const char *c) {
|
|
for (; *c; c++)
|
|
if ((ispunct(*c)||*c=='\n') && *c!='_' && *c!=':') return 0;
|
|
return 1;
|
|
}
|
|
|
|
// Test to see if name() is an array entry. If so, and this is the
|
|
// highest number, return name[num+1]. Return null if not the highest
|
|
// number or a field or function. Return name() if not an array entry.
|
|
const char *array_name(Fl_Widget_Type *o) {
|
|
const char *c = o->name();
|
|
if (!c) return 0;
|
|
const char *d;
|
|
for (d = c; *d != '['; d++) {
|
|
if (!*d) return c;
|
|
if (ispunct(*d) && *d!='_') return 0;
|
|
}
|
|
int num = atoi(d+1);
|
|
int sawthis = 0;
|
|
Fl_Type *t = o->prev;
|
|
Fl_Type *tp = o;
|
|
const char *cn = o->class_name(1);
|
|
for (; t && t->class_name(1) == cn; tp = t, t = t->prev) {/*empty*/}
|
|
for (t = tp; t && t->class_name(1) == cn; t = t->next) {
|
|
if (t == o) {sawthis=1; continue;}
|
|
const char *e = t->name();
|
|
if (!e) continue;
|
|
if (strncmp(c,e,d-c)) continue;
|
|
int n1 = atoi(e+(d-c)+1);
|
|
if (n1 > num || (n1==num && sawthis)) return 0;
|
|
}
|
|
static char buffer[128];
|
|
// MRS: we want strncpy() here...
|
|
strncpy(buffer,c,d-c+1);
|
|
snprintf(buffer+(d-c+1),sizeof(buffer) - (d-c+1), "%d]",num+1);
|
|
return buffer;
|
|
}
|
|
|
|
// Test to see if extra code is a declaration:
|
|
int isdeclare(const char *c) {
|
|
while (isspace(*c)) c++;
|
|
if (*c == '#') return 1;
|
|
if (!strncmp(c,"extern",6)) return 1;
|
|
if (!strncmp(c,"typedef",7)) return 1;
|
|
if (!strncmp(c,"using",5)) return 1;
|
|
return 0;
|
|
}
|
|
|
|
void Fl_Widget_Type::write_static(Fd_Code_Writer& f) {
|
|
const char* t = subclassname(this);
|
|
if (!subclass() || (is_class() && !strncmp(t, "Fl_", 3))) {
|
|
f.write_h_once("#include <FL/Fl.H>");
|
|
f.write_h_once("#include <FL/%s.H>", t);
|
|
}
|
|
for (int n=0; n < NUM_EXTRA_CODE; n++) {
|
|
if (extra_code(n) && isdeclare(extra_code(n)))
|
|
f.write_h_once("%s", extra_code(n));
|
|
}
|
|
if (callback() && is_name(callback())) {
|
|
int write_extern_declaration = 1;
|
|
char buf[1024]; snprintf(buf, 1023, "%s(*)", callback());
|
|
if (is_in_class()) {
|
|
if (has_function("static void", buf))
|
|
write_extern_declaration = 0;
|
|
} else {
|
|
if (has_toplevel_function(0L, buf))
|
|
write_extern_declaration = 0;
|
|
}
|
|
if (write_extern_declaration)
|
|
f.write_h_once("extern void %s(%s*, %s);", callback(), t,
|
|
user_data_type() ? user_data_type() : "void*");
|
|
}
|
|
const char* k = class_name(1);
|
|
const char* c = array_name(this);
|
|
if (c && !k && !is_class()) {
|
|
f.write_c("\n");
|
|
if (!public_) f.write_c("static ");
|
|
else f.write_h("extern %s *%s;\n", t, c);
|
|
if (strchr(c, '[') == NULL) f.write_c("%s *%s=(%s *)0;\n", t, c, t);
|
|
else f.write_c("%s *%s={(%s *)0};\n", t, c, t);
|
|
}
|
|
if (callback() && !is_name(callback())) {
|
|
// see if 'o' or 'v' used, to prevent unused argument warnings:
|
|
int use_o = 0;
|
|
int use_v = 0;
|
|
const char *d;
|
|
for (d = callback(); *d;) {
|
|
if (*d == 'o' && !is_id(d[1])) use_o = 1;
|
|
if (*d == 'v' && !is_id(d[1])) use_v = 1;
|
|
do d++; while (is_id(*d));
|
|
while (*d && !is_id(*d)) d++;
|
|
}
|
|
const char* cn = callback_name(f);
|
|
if (k) {
|
|
f.write_c("\nvoid %s::%s_i(%s*", k, cn, t);
|
|
} else {
|
|
f.write_c("\nstatic void %s(%s*", cn, t);
|
|
}
|
|
if (use_o) f.write_c(" o");
|
|
const char* ut = user_data_type() ? user_data_type() : "void*";
|
|
f.write_c(", %s", ut);
|
|
if (use_v) f.write_c(" v");
|
|
f.write_c(") {\n");
|
|
// Matt: disabled f.tag(FD_TAG_GENERIC, 0);
|
|
f.write_c_indented(callback(), 1, 0);
|
|
if (*(d-1) != ';' && *(d-1) != '}') {
|
|
const char *p = strrchr(callback(), '\n');
|
|
if (p) p ++;
|
|
else p = callback();
|
|
// Only add trailing semicolon if the last line is not a preprocessor
|
|
// statement...
|
|
if (*p != '#' && *p) f.write_c(";");
|
|
}
|
|
f.write_c("\n");
|
|
// Matt: disabled f.tag(FD_TAG_WIDGET_CALLBACK, get_uid());
|
|
f.write_c("}\n");
|
|
if (k) {
|
|
f.write_c("void %s::%s(%s* o, %s v) {\n", k, cn, t, ut);
|
|
f.write_c("%s((%s*)(o", f.indent(1), k);
|
|
Fl_Type *q = 0;
|
|
for (Fl_Type* p = parent; p && p->is_widget(); q = p, p = p->parent)
|
|
f.write_c("->parent()");
|
|
if (!q || !q->is_a(ID_Widget_Class))
|
|
f.write_c("->user_data()");
|
|
f.write_c("))->%s_i(o,v);\n}\n", cn);
|
|
}
|
|
}
|
|
if (image) {
|
|
if (!f.c_contains(image))
|
|
image->write_static(f, compress_image_);
|
|
}
|
|
if (inactive) {
|
|
if (!f.c_contains(inactive))
|
|
inactive->write_static(f, compress_deimage_);
|
|
}
|
|
}
|
|
|
|
void Fl_Widget_Type::write_code1(Fd_Code_Writer& f) {
|
|
const char* t = subclassname(this);
|
|
const char *c = array_name(this);
|
|
if (c) {
|
|
if (class_name(1)) {
|
|
f.write_public(public_);
|
|
f.write_h("%s%s *%s;\n", f.indent(1), t, c);
|
|
}
|
|
}
|
|
if (class_name(1) && callback() && !is_name(callback())) {
|
|
const char* cn = callback_name(f);
|
|
const char* ut = user_data_type() ? user_data_type() : "void*";
|
|
f.write_public(0);
|
|
f.write_h("%sinline void %s_i(%s*, %s);\n", f.indent(1), cn, t, ut);
|
|
f.write_h("%sstatic void %s(%s*, %s);\n", f.indent(1), cn, t, ut);
|
|
}
|
|
// figure out if local variable will be used (prevent compiler warnings):
|
|
int wused = !name() && is_a(ID_Window);
|
|
const char *ptr;
|
|
|
|
f.varused = wused;
|
|
|
|
if (!name() && !f.varused) {
|
|
f.varused |= can_have_children();
|
|
|
|
if (!f.varused) {
|
|
f.varused_test = 1;
|
|
write_widget_code(f);
|
|
f.varused_test = 0;
|
|
}
|
|
}
|
|
|
|
if (!f.varused) {
|
|
for (int n=0; n < NUM_EXTRA_CODE; n++)
|
|
if (extra_code(n) && !isdeclare(extra_code(n)))
|
|
{
|
|
int instring = 0;
|
|
int inname = 0;
|
|
int incomment = 0;
|
|
int incppcomment = 0;
|
|
for (ptr = extra_code(n); *ptr; ptr ++) {
|
|
if (instring) {
|
|
if (*ptr == '\\') ptr++;
|
|
else if (*ptr == '\"') instring = 0;
|
|
} else if (inname && !isalnum(*ptr & 255)) {
|
|
inname = 0;
|
|
} else if (*ptr == '/' && ptr[1]=='*') {
|
|
incomment = 1; ptr++;
|
|
} else if (incomment) {
|
|
if (*ptr == '*' && ptr[1]=='/') {
|
|
incomment = 0; ptr++;
|
|
}
|
|
} else if (*ptr == '/' && ptr[1]=='/') {
|
|
incppcomment = 1; ptr++;
|
|
} else if (incppcomment) {
|
|
if (*ptr == '\n')
|
|
incppcomment = 0;
|
|
} else if (*ptr == '\"') {
|
|
instring = 1;
|
|
} else if (isalnum(*ptr & 255) || *ptr == '_') {
|
|
size_t len = strspn(ptr, "0123456789_"
|
|
"abcdefghijklmnopqrstuvwxyz"
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
|
if (!strncmp(ptr, "o", len)) {
|
|
f.varused = 1;
|
|
break;
|
|
} else {
|
|
ptr += len - 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
f.write_c("%s{ ", f.indent());
|
|
write_comment_inline_c(f);
|
|
if (f.varused) f.write_c("%s* o = ", t);
|
|
if (name()) f.write_c("%s = ", name());
|
|
if (is_a(ID_Window)) {
|
|
// Handle special case where user is faking a Fl_Group type as a window,
|
|
// there is no 2-argument constructor in that case:
|
|
if (!strstr(t, "Window"))
|
|
f.write_c("new %s(0, 0, %d, %d", t, o->w(), o->h());
|
|
else
|
|
f.write_c("new %s(%d, %d", t, o->w(), o->h());
|
|
} else if (is_a(ID_Menu_Bar)
|
|
&& ((Fl_Menu_Bar_Type*)this)->is_sys_menu_bar()
|
|
&& is_in_class()) {
|
|
f.write_c("(%s*)new %s(%d, %d, %d, %d",
|
|
t, ((Fl_Menu_Bar_Type*)this)->sys_menubar_proxy_name(),
|
|
o->x(), o->y(), o->w(), o->h());
|
|
} else {
|
|
f.write_c("new %s(%d, %d, %d, %d", t, o->x(), o->y(), o->w(), o->h());
|
|
}
|
|
if (label() && *label()) {
|
|
f.write_c(", ");
|
|
switch (g_project.i18n_type) {
|
|
case FD_I18N_NONE : /* None */
|
|
f.write_cstring(label());
|
|
break;
|
|
case FD_I18N_GNU : /* GNU gettext */
|
|
f.write_c("%s(", g_project.i18n_gnu_function.c_str());
|
|
f.write_cstring(label());
|
|
f.write_c(")");
|
|
break;
|
|
case FD_I18N_POSIX : /* POSIX catgets */
|
|
f.write_c("catgets(%s,%s,%d,",
|
|
g_project.i18n_pos_file.empty() ? "_catalog" : g_project.i18n_pos_file.c_str(),
|
|
g_project.i18n_pos_set.c_str(), msgnum());
|
|
f.write_cstring(label());
|
|
f.write_c(")");
|
|
break;
|
|
}
|
|
}
|
|
f.write_c(");\n");
|
|
|
|
f.indentation++;
|
|
|
|
// Avoid compiler warning for unused variable.
|
|
// Also avoid quality control warnings about incorrect allocation error handling.
|
|
if (wused) f.write_c("%sw = o; (void)w;\n", f.indent());
|
|
|
|
write_widget_code(f);
|
|
}
|
|
|
|
void Fl_Widget_Type::write_color(Fd_Code_Writer& f, const char* field, Fl_Color color) {
|
|
const char* color_name = 0;
|
|
switch (color) {
|
|
case FL_FOREGROUND_COLOR: color_name = "FL_FOREGROUND_COLOR"; break;
|
|
case FL_BACKGROUND2_COLOR: color_name = "FL_BACKGROUND2_COLOR"; break;
|
|
case FL_INACTIVE_COLOR: color_name = "FL_INACTIVE_COLOR"; break;
|
|
case FL_SELECTION_COLOR: color_name = "FL_SELECTION_COLOR"; break;
|
|
case FL_GRAY0: color_name = "FL_GRAY0"; break;
|
|
case FL_DARK3: color_name = "FL_DARK3"; break;
|
|
case FL_DARK2: color_name = "FL_DARK2"; break;
|
|
case FL_DARK1: color_name = "FL_DARK1"; break;
|
|
case FL_BACKGROUND_COLOR: color_name = "FL_BACKGROUND_COLOR"; break;
|
|
case FL_LIGHT1: color_name = "FL_LIGHT1"; break;
|
|
case FL_LIGHT2: color_name = "FL_LIGHT2"; break;
|
|
case FL_LIGHT3: color_name = "FL_LIGHT3"; break;
|
|
case FL_BLACK: color_name = "FL_BLACK"; break;
|
|
case FL_RED: color_name = "FL_RED"; break;
|
|
case FL_GREEN: color_name = "FL_GREEN"; break;
|
|
case FL_YELLOW: color_name = "FL_YELLOW"; break;
|
|
case FL_BLUE: color_name = "FL_BLUE"; break;
|
|
case FL_MAGENTA: color_name = "FL_MAGENTA"; break;
|
|
case FL_CYAN: color_name = "FL_CYAN"; break;
|
|
case FL_DARK_RED: color_name = "FL_DARK_RED"; break;
|
|
case FL_DARK_GREEN: color_name = "FL_DARK_GREEN"; break;
|
|
case FL_DARK_YELLOW: color_name = "FL_DARK_YELLOW"; break;
|
|
case FL_DARK_BLUE: color_name = "FL_DARK_BLUE"; break;
|
|
case FL_DARK_MAGENTA: color_name = "FL_DARK_MAGENTA"; break;
|
|
case FL_DARK_CYAN: color_name = "FL_DARK_CYAN"; break;
|
|
case FL_WHITE: color_name = "FL_WHITE"; break;
|
|
}
|
|
const char *var = is_class() ? "this" : name() ? name() : "o";
|
|
if (color_name) {
|
|
f.write_c("%s%s->%s(%s);\n", f.indent(), var, field, color_name);
|
|
} else {
|
|
f.write_c("%s%s->%s((Fl_Color)%d);\n", f.indent(), var, field, color);
|
|
}
|
|
}
|
|
|
|
// this is split from write_code1(Fd_Code_Writer& f) for Fl_Window_Type:
|
|
void Fl_Widget_Type::write_widget_code(Fd_Code_Writer& f) {
|
|
Fl_Widget* tplate = ((Fl_Widget_Type*)factory)->o;
|
|
const char *var = is_class() ? "this" : name() ? name() : "o";
|
|
|
|
if (tooltip() && *tooltip()) {
|
|
f.write_c("%s%s->tooltip(",f.indent(), var);
|
|
switch (g_project.i18n_type) {
|
|
case FD_I18N_NONE : /* None */
|
|
f.write_cstring(tooltip());
|
|
break;
|
|
case FD_I18N_GNU : /* GNU gettext */
|
|
f.write_c("%s(", g_project.i18n_gnu_function.c_str());
|
|
f.write_cstring(tooltip());
|
|
f.write_c(")");
|
|
break;
|
|
case FD_I18N_POSIX : /* POSIX catgets */
|
|
f.write_c("catgets(%s,%s,%d,",
|
|
g_project.i18n_pos_file.empty() ? "_catalog" : g_project.i18n_pos_file.c_str(),
|
|
g_project.i18n_pos_set.c_str(),
|
|
msgnum() + 1);
|
|
f.write_cstring(tooltip());
|
|
f.write_c(")");
|
|
break;
|
|
}
|
|
f.write_c(");\n");
|
|
}
|
|
|
|
if (is_a(ID_Spinner) && ((Fl_Spinner*)o)->type() != ((Fl_Spinner*)tplate)->type())
|
|
f.write_c("%s%s->type(%d);\n", f.indent(), var, ((Fl_Spinner*)o)->type());
|
|
else if (o->type() != tplate->type() && !is_a(ID_Window))
|
|
f.write_c("%s%s->type(%d);\n", f.indent(), var, o->type());
|
|
if (o->box() != tplate->box() || subclass())
|
|
f.write_c("%s%s->box(FL_%s);\n", f.indent(), var, boxname(o->box()));
|
|
|
|
// write shortcut command if needed
|
|
int shortcut = 0;
|
|
if (is_button()) shortcut = ((Fl_Button*)o)->shortcut();
|
|
else if (is_a(ID_Input)) shortcut = ((Fl_Input_*)o)->shortcut();
|
|
else if (is_a(ID_Value_Input)) shortcut = ((Fl_Value_Input*)o)->shortcut();
|
|
else if (is_a(ID_Text_Display)) shortcut = ((Fl_Text_Display*)o)->shortcut();
|
|
if (shortcut) {
|
|
int s = shortcut;
|
|
f.write_c("%s%s->shortcut(", f.indent(), var);
|
|
if (g_project.use_FL_COMMAND) {
|
|
if (s & FL_CTRL) { f.write_c("FL_CONTROL|"); s &= ~FL_CTRL; }
|
|
if (s & FL_META) { f.write_c("FL_COMMAND|"); s &= ~FL_META; }
|
|
} else {
|
|
if (s & FL_CTRL) { f.write_c("FL_CTRL|"); s &= ~FL_CTRL; }
|
|
if (s & FL_META) { f.write_c("FL_META|"); s &= ~FL_META; }
|
|
}
|
|
if (s & FL_SHIFT) { f.write_c("FL_SHIFT|"); s &= ~FL_SHIFT; }
|
|
if (s & FL_ALT) { f.write_c("FL_ALT|"); s &= ~FL_ALT; }
|
|
if ((s < 127) && isprint(s))
|
|
f.write_c("'%c');\n", s);
|
|
else
|
|
f.write_c("0x%x);\n", s);
|
|
}
|
|
|
|
if (is_a(ID_Button)) {
|
|
Fl_Button* b = (Fl_Button*)o;
|
|
if (b->down_box()) f.write_c("%s%s->down_box(FL_%s);\n", f.indent(), var,
|
|
boxname(b->down_box()));
|
|
if (b->value()) f.write_c("%s%s->value(1);\n", f.indent(), var);
|
|
if (b->compact()) f.write_c("%s%s->compact(%d);\n", f.indent(), var, b->compact());
|
|
} else if (is_a(ID_Input_Choice)) {
|
|
Fl_Input_Choice* b = (Fl_Input_Choice*)o;
|
|
if (b->down_box()) f.write_c("%s%s->down_box(FL_%s);\n", f.indent(), var,
|
|
boxname(b->down_box()));
|
|
} else if (is_a(ID_Menu_Manager_)) {
|
|
Fl_Menu_* b = (Fl_Menu_*)o;
|
|
if (b->down_box()) f.write_c("%s%s->down_box(FL_%s);\n", f.indent(), var,
|
|
boxname(b->down_box()));
|
|
}
|
|
if (o->color() != tplate->color() || subclass())
|
|
write_color(f, "color", o->color());
|
|
if (o->selection_color() != tplate->selection_color() || subclass())
|
|
write_color(f, "selection_color", o->selection_color());
|
|
if (image) {
|
|
image->write_code(f, bind_image_, var);
|
|
if (scale_image_w_ || scale_image_h_) {
|
|
f.write_c("%s%s->image()->scale(", f.indent(), var);
|
|
if (scale_image_w_>0)
|
|
f.write_c("%d, ", scale_image_w_);
|
|
else
|
|
f.write_c("%s->image()->data_w(), ", var);
|
|
if (scale_image_h_>0)
|
|
f.write_c("%d, 0, 1);\n", scale_image_h_);
|
|
else
|
|
f.write_c("%s->image()->data_h(), 0, 1);\n", var);
|
|
}
|
|
}
|
|
if (inactive) {
|
|
inactive->write_code(f, bind_deimage_, var, 1);
|
|
if (scale_deimage_w_ || scale_deimage_h_) {
|
|
f.write_c("%s%s->deimage()->scale(", f.indent(), var);
|
|
if (scale_deimage_w_>0)
|
|
f.write_c("%d, ", scale_deimage_w_);
|
|
else
|
|
f.write_c("%s->deimage()->data_w(), ", var);
|
|
if (scale_deimage_h_>0)
|
|
f.write_c("%d, 0, 1);\n", scale_deimage_h_);
|
|
else
|
|
f.write_c("%s->deimage()->data_h(), 0, 1);\n", var);
|
|
}
|
|
}
|
|
if (o->labeltype() != tplate->labeltype() || subclass())
|
|
f.write_c("%s%s->labeltype(FL_%s);\n", f.indent(), var,
|
|
item_name(labeltypemenu, o->labeltype()));
|
|
if (o->labelfont() != tplate->labelfont() || subclass())
|
|
f.write_c("%s%s->labelfont(%d);\n", f.indent(), var, o->labelfont());
|
|
if (o->labelsize() != tplate->labelsize() || subclass())
|
|
f.write_c("%s%s->labelsize(%d);\n", f.indent(), var, o->labelsize());
|
|
if (o->labelcolor() != tplate->labelcolor() || subclass())
|
|
write_color(f, "labelcolor", o->labelcolor());
|
|
if (o->horizontal_label_margin() != tplate->horizontal_label_margin())
|
|
f.write_c("%s%s->horizontal_label_margin(%d);\n", f.indent(), var, o->horizontal_label_margin());
|
|
if (o->vertical_label_margin() != tplate->vertical_label_margin())
|
|
f.write_c("%s%s->vertical_label_margin(%d);\n", f.indent(), var, o->vertical_label_margin());
|
|
if (o->label_image_spacing() != tplate->label_image_spacing())
|
|
f.write_c("%s%s->label_image_spacing(%d);\n", f.indent(), var, o->label_image_spacing());
|
|
if (is_a(ID_Valuator_)) {
|
|
Fl_Valuator* v = (Fl_Valuator*)o;
|
|
Fl_Valuator* t = (Fl_Valuator*)(tplate);
|
|
if (v->minimum()!=t->minimum())
|
|
f.write_c("%s%s->minimum(%g);\n", f.indent(), var, v->minimum());
|
|
if (v->maximum()!=t->maximum())
|
|
f.write_c("%s%s->maximum(%g);\n", f.indent(), var, v->maximum());
|
|
if (v->step()!=t->step())
|
|
f.write_c("%s%s->step(%g);\n", f.indent(), var, v->step());
|
|
if (v->value()) {
|
|
if (is_a(ID_Scrollbar)) { // Fl_Scrollbar::value(double) is not available
|
|
f.write_c("%s%s->Fl_Slider::value(%g);\n", f.indent(), var, v->value());
|
|
} else {
|
|
f.write_c("%s%s->value(%g);\n", f.indent(), var, v->value());
|
|
}
|
|
}
|
|
if (is_a(ID_Slider)) {
|
|
double x = ((Fl_Slider*)v)->slider_size();
|
|
double y = ((Fl_Slider*)t)->slider_size();
|
|
if (x != y) f.write_c("%s%s->slider_size(%g);\n", f.indent(), var, x);
|
|
}
|
|
}
|
|
if (is_a(ID_Spinner)) {
|
|
Fl_Spinner* v = (Fl_Spinner*)o;
|
|
Fl_Spinner* t = (Fl_Spinner*)(tplate);
|
|
if (v->minimum()!=t->minimum())
|
|
f.write_c("%s%s->minimum(%g);\n", f.indent(), var, v->minimum());
|
|
if (v->maximum()!=t->maximum())
|
|
f.write_c("%s%s->maximum(%g);\n", f.indent(), var, v->maximum());
|
|
if (v->step()!=t->step())
|
|
f.write_c("%s%s->step(%g);\n", f.indent(), var, v->step());
|
|
if (v->value()!=1.0f)
|
|
f.write_c("%s%s->value(%g);\n", f.indent(), var, v->value());
|
|
}
|
|
|
|
{Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) {
|
|
Fl_Font g; int s; Fl_Color c; textstuff(0,g,s,c);
|
|
if (g != ff) f.write_c("%s%s->textfont(%d);\n", f.indent(), var, g);
|
|
if (s != fs) f.write_c("%s%s->textsize(%d);\n", f.indent(), var, s);
|
|
if (c != fc) write_color(f, "textcolor", c);
|
|
}}
|
|
const char* ud = user_data();
|
|
if (class_name(1) && !parent->is_widget()) ud = "this";
|
|
if (callback()) {
|
|
f.write_c("%s%s->callback((Fl_Callback*)%s", f.indent(), var, callback_name(f));
|
|
if (ud)
|
|
f.write_c(", (void*)(%s));\n", ud);
|
|
else
|
|
f.write_c(");\n");
|
|
} else if (ud) {
|
|
f.write_c("%s%s->user_data((void*)(%s));\n", f.indent(), var, ud);
|
|
}
|
|
if (o->align() != tplate->align() || subclass()) {
|
|
int i = o->align();
|
|
f.write_c("%s%s->align(Fl_Align(%s", f.indent(), var,
|
|
item_name(alignmenu, i & ~FL_ALIGN_INSIDE));
|
|
if (i & FL_ALIGN_INSIDE) f.write_c("|FL_ALIGN_INSIDE");
|
|
f.write_c("));\n");
|
|
}
|
|
Fl_When ww = o->when();
|
|
if (ww != tplate->when() || subclass())
|
|
f.write_c("%s%s->when(%s);\n", f.indent(), var, when_symbol_name(ww));
|
|
if (!o->visible() && o->parent())
|
|
f.write_c("%s%s->hide();\n", f.indent(), var);
|
|
if (!o->active())
|
|
f.write_c("%s%s->deactivate();\n", f.indent(), var);
|
|
if (!is_a(ID_Group) && resizable())
|
|
f.write_c("%sFl_Group::current()->resizable(%s);\n", f.indent(), var);
|
|
if (hotspot()) {
|
|
if (is_class())
|
|
f.write_c("%shotspot(%s);\n", f.indent(), var);
|
|
else if (is_a(ID_Window))
|
|
f.write_c("%s%s->hotspot(%s);\n", f.indent(), var, var);
|
|
else
|
|
f.write_c("%s%s->window()->hotspot(%s);\n", f.indent(), var, var);
|
|
}
|
|
}
|
|
|
|
void Fl_Widget_Type::write_extra_code(Fd_Code_Writer& f) {
|
|
for (int n=0; n < NUM_EXTRA_CODE; n++)
|
|
if (extra_code(n) && !isdeclare(extra_code(n)))
|
|
f.write_c("%s%s\n", f.indent(), extra_code(n));
|
|
}
|
|
|
|
void Fl_Widget_Type::write_block_close(Fd_Code_Writer& f) {
|
|
f.indentation--;
|
|
f.write_c("%s} // %s* %s\n", f.indent(), subclassname(this),
|
|
name() ? name() : "o");
|
|
}
|
|
|
|
void Fl_Widget_Type::write_code2(Fd_Code_Writer& f) {
|
|
write_extra_code(f);
|
|
write_block_close(f);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
void Fl_Widget_Type::write_properties(Fd_Project_Writer &f) {
|
|
Fl_Type::write_properties(f);
|
|
f.write_indent(level+1);
|
|
switch (public_) {
|
|
case 0: f.write_string("private"); break;
|
|
case 1: break;
|
|
case 2: f.write_string("protected"); break;
|
|
}
|
|
if (tooltip() && *tooltip()) {
|
|
f.write_string("tooltip");
|
|
f.write_word(tooltip());
|
|
}
|
|
if (image_name() && *image_name()) {
|
|
if (scale_image_w_ || scale_image_h_)
|
|
f.write_string("scale_image {%d %d}", scale_image_w_, scale_image_h_);
|
|
f.write_string("image");
|
|
f.write_word(image_name());
|
|
f.write_string("compress_image %d", compress_image_);
|
|
}
|
|
if (bind_image_) f.write_string("bind_image 1");
|
|
if (inactive_name() && *inactive_name()) {
|
|
if (scale_deimage_w_ || scale_deimage_h_)
|
|
f.write_string("scale_deimage {%d %d}", scale_deimage_w_, scale_deimage_h_);
|
|
f.write_string("deimage");
|
|
f.write_word(inactive_name());
|
|
f.write_string("compress_deimage %d", compress_deimage_);
|
|
}
|
|
if (bind_deimage_) f.write_string("bind_deimage 1");
|
|
f.write_string("xywh {%d %d %d %d}", o->x(), o->y(), o->w(), o->h());
|
|
Fl_Widget* tplate = ((Fl_Widget_Type*)factory)->o;
|
|
if (is_a(ID_Spinner) && ((Fl_Spinner*)o)->type() != ((Fl_Spinner*)tplate)->type()) {
|
|
f.write_string("type");
|
|
f.write_word(item_name(subtypes(), ((Fl_Spinner*)o)->type()));
|
|
} else if (subtypes() && (o->type() != tplate->type() || is_a(ID_Window))) {
|
|
f.write_string("type");
|
|
f.write_word(item_name(subtypes(), o->type()));
|
|
}
|
|
if (o->box() != tplate->box()) {
|
|
f.write_string("box"); f.write_word(boxname(o->box()));}
|
|
if (is_a(ID_Input)) {
|
|
Fl_Input_* b = (Fl_Input_*)o;
|
|
if (b->shortcut()) f.write_string("shortcut 0x%x", b->shortcut());
|
|
}
|
|
if (is_a(ID_Value_Input)) {
|
|
Fl_Value_Input* b = (Fl_Value_Input*)o;
|
|
if (b->shortcut()) f.write_string("shortcut 0x%x", b->shortcut());
|
|
}
|
|
if (is_a(ID_Text_Display)) {
|
|
Fl_Text_Display* b = (Fl_Text_Display*)o;
|
|
if (b->shortcut()) f.write_string("shortcut 0x%x", b->shortcut());
|
|
}
|
|
if (is_a(ID_Button)) {
|
|
Fl_Button* b = (Fl_Button*)o;
|
|
if (b->down_box()) {
|
|
f.write_string("down_box"); f.write_word(boxname(b->down_box()));}
|
|
if (b->shortcut()) f.write_string("shortcut 0x%x", b->shortcut());
|
|
if (b->value()) f.write_string("value 1");
|
|
} else if (is_a(ID_Input_Choice)) {
|
|
Fl_Input_Choice* b = (Fl_Input_Choice*)o;
|
|
if (b->down_box()) {
|
|
f.write_string("down_box"); f.write_word(boxname(b->down_box()));}
|
|
} else if (is_a(ID_Menu_)) {
|
|
Fl_Menu_* b = (Fl_Menu_*)o;
|
|
if (b->down_box()) {
|
|
f.write_string("down_box"); f.write_word(boxname(b->down_box()));}
|
|
}
|
|
if (o->color()!=tplate->color())
|
|
f.write_string("color %d", o->color());
|
|
if (o->selection_color()!=tplate->selection_color())
|
|
f.write_string("selection_color %d", o->selection_color());
|
|
if (o->labeltype()!=tplate->labeltype()) {
|
|
f.write_string("labeltype");
|
|
f.write_word(item_name(labeltypemenu, o->labeltype()));
|
|
}
|
|
if (o->labelfont()!=tplate->labelfont())
|
|
f.write_string("labelfont %d", o->labelfont());
|
|
if (o->labelsize()!=tplate->labelsize())
|
|
f.write_string("labelsize %d", o->labelsize());
|
|
if (o->labelcolor()!=tplate->labelcolor())
|
|
f.write_string("labelcolor %d", o->labelcolor());
|
|
if (o->align()!=tplate->align())
|
|
f.write_string("align %d", o->align());
|
|
if (o->horizontal_label_margin()!=tplate->horizontal_label_margin())
|
|
f.write_string("h_label_margin %d", o->horizontal_label_margin());
|
|
if (o->vertical_label_margin()!=tplate->vertical_label_margin())
|
|
f.write_string("v_label_margin %d", o->vertical_label_margin());
|
|
if (o->label_image_spacing()!=tplate->label_image_spacing())
|
|
f.write_string("image_spacing %d", o->label_image_spacing());
|
|
if (o->when() != tplate->when())
|
|
f.write_string("when %d", o->when());
|
|
if (is_a(ID_Valuator_)) {
|
|
Fl_Valuator* v = (Fl_Valuator*)o;
|
|
Fl_Valuator* t = (Fl_Valuator*)(tplate);
|
|
if (v->minimum()!=t->minimum()) f.write_string("minimum %g",v->minimum());
|
|
if (v->maximum()!=t->maximum()) f.write_string("maximum %g",v->maximum());
|
|
if (v->step()!=t->step()) f.write_string("step %g",v->step());
|
|
if (v->value()!=0.0) f.write_string("value %g",v->value());
|
|
if (is_a(ID_Slider)) {
|
|
double x = ((Fl_Slider*)v)->slider_size();
|
|
double y = ((Fl_Slider*)t)->slider_size();
|
|
if (x != y) f.write_string("slider_size %g", x);
|
|
}
|
|
}
|
|
if (is_a(ID_Spinner)) {
|
|
Fl_Spinner* v = (Fl_Spinner*)o;
|
|
Fl_Spinner* t = (Fl_Spinner*)(tplate);
|
|
if (v->minimum()!=t->minimum()) f.write_string("minimum %g",v->minimum());
|
|
if (v->maximum()!=t->maximum()) f.write_string("maximum %g",v->maximum());
|
|
if (v->step()!=t->step()) f.write_string("step %g",v->step());
|
|
if (v->value()!=1.0) f.write_string("value %g",v->value());
|
|
}
|
|
{Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) {
|
|
Fl_Font ft; int s; Fl_Color c; textstuff(0,ft,s,c);
|
|
if (ft != ff) f.write_string("textfont %d", ft);
|
|
if (s != fs) f.write_string("textsize %d", s);
|
|
if (c != fc) f.write_string("textcolor %d", c);
|
|
}}
|
|
if (!o->visible() && !override_visible_) f.write_string("hide");
|
|
if (!o->active()) f.write_string("deactivate");
|
|
if (resizable()) f.write_string("resizable");
|
|
if (hotspot()) f.write_string(is_a(ID_Menu_Item) ? "divider" : "hotspot");
|
|
for (int n=0; n < NUM_EXTRA_CODE; n++) if (extra_code(n)) {
|
|
f.write_indent(level+1);
|
|
f.write_string("code%d",n);
|
|
f.write_word(extra_code(n));
|
|
}
|
|
if (subclass()) {
|
|
f.write_indent(level+1);
|
|
f.write_string("class");
|
|
f.write_word(subclass());
|
|
}
|
|
}
|
|
|
|
void Fl_Widget_Type::read_property(Fd_Project_Reader &f, const char *c) {
|
|
int x,y,w,h; Fl_Font ft; int s; Fl_Color cc;
|
|
if (!strcmp(c,"private")) {
|
|
public_ = 0;
|
|
} else if (!strcmp(c,"protected")) {
|
|
public_ = 2;
|
|
} else if (!strcmp(c,"xywh")) {
|
|
if (sscanf(f.read_word(),"%d %d %d %d",&x,&y,&w,&h) == 4) {
|
|
x += pasteoffset;
|
|
y += pasteoffset;
|
|
// FIXME temporary change!
|
|
if (f.read_version>=2.0 && o->parent() && o->parent()!=o->window()) {
|
|
x += o->parent()->x();
|
|
y += o->parent()->y();
|
|
}
|
|
o->resize(x,y,w,h);
|
|
}
|
|
} else if (!strcmp(c,"tooltip")) {
|
|
tooltip(f.read_word());
|
|
} else if (!strcmp(c,"scale_image")) {
|
|
if (sscanf(f.read_word(),"%d %d",&w,&h) == 2) {
|
|
scale_image_w_ = w;
|
|
scale_image_h_ = h;
|
|
}
|
|
} else if (!strcmp(c,"image")) {
|
|
image_name(f.read_word());
|
|
// starting in 2023, `image` is always followed by `compress_image`
|
|
// the code below is for compatibility with older .fl files
|
|
const char *ext = fl_filename_ext(image_name_);
|
|
if ( strcmp(ext, ".jpg")
|
|
&& strcmp(ext, ".png")
|
|
&& strcmp(ext, ".svg")
|
|
&& strcmp(ext, ".svgz"))
|
|
compress_image_ = 0; // if it is neither of those, default to uncompressed
|
|
} else if (!strcmp(c,"bind_image")) {
|
|
bind_image_ = (int)atol(f.read_word());
|
|
} else if (!strcmp(c,"compress_image")) {
|
|
compress_image_ = (int)atol(f.read_word());
|
|
} else if (!strcmp(c,"scale_deimage")) {
|
|
if (sscanf(f.read_word(),"%d %d",&w,&h) == 2) {
|
|
scale_deimage_w_ = w;
|
|
scale_deimage_h_ = h;
|
|
}
|
|
} else if (!strcmp(c,"deimage")) {
|
|
inactive_name(f.read_word());
|
|
// starting in 2023, `deimage` is always followed by `compress_deimage`
|
|
// the code below is for compatibility with older .fl files
|
|
const char *ext = fl_filename_ext(inactive_name_);
|
|
if ( strcmp(ext, ".jpg")
|
|
&& strcmp(ext, ".png")
|
|
&& strcmp(ext, ".svg")
|
|
&& strcmp(ext, ".svgz"))
|
|
compress_deimage_ = 0; // if it is neither of those, default to uncompressed
|
|
} else if (!strcmp(c,"bind_deimage")) {
|
|
bind_deimage_ = (int)atol(f.read_word());
|
|
} else if (!strcmp(c,"compress_deimage")) {
|
|
compress_deimage_ = (int)atol(f.read_word());
|
|
} else if (!strcmp(c,"type")) {
|
|
if (is_a(ID_Spinner))
|
|
((Fl_Spinner*)o)->type(item_number(subtypes(), f.read_word()));
|
|
else
|
|
o->type(item_number(subtypes(), f.read_word()));
|
|
} else if (!strcmp(c,"box")) {
|
|
const char* value = f.read_word();
|
|
if ((x = boxnumber(value))) {
|
|
if (x == ZERO_ENTRY) x = 0;
|
|
o->box((Fl_Boxtype)x);
|
|
} else if (sscanf(value,"%d",&x) == 1) o->box((Fl_Boxtype)x);
|
|
} else if (is_a(ID_Button) && !strcmp(c,"down_box")) {
|
|
const char* value = f.read_word();
|
|
if ((x = boxnumber(value))) {
|
|
if (x == ZERO_ENTRY) x = 0;
|
|
((Fl_Button*)o)->down_box((Fl_Boxtype)x);
|
|
}
|
|
} else if (is_a(ID_Input_Choice) && !strcmp(c,"down_box")) {
|
|
const char* value = f.read_word();
|
|
if ((x = boxnumber(value))) {
|
|
if (x == ZERO_ENTRY) x = 0;
|
|
((Fl_Input_Choice*)o)->down_box((Fl_Boxtype)x);
|
|
}
|
|
} else if (is_a(ID_Menu_) && !strcmp(c,"down_box")) {
|
|
const char* value = f.read_word();
|
|
if ((x = boxnumber(value))) {
|
|
if (x == ZERO_ENTRY) x = 0;
|
|
((Fl_Menu_*)o)->down_box((Fl_Boxtype)x);
|
|
}
|
|
} else if (is_button() && !strcmp(c,"value")) {
|
|
const char* value = f.read_word();
|
|
((Fl_Button*)o)->value(atoi(value));
|
|
} else if (!strcmp(c,"color")) {
|
|
const char *cw = f.read_word();
|
|
if (cw[0]=='0' && cw[1]=='x') {
|
|
sscanf(cw,"0x%x",&x);
|
|
o->color(x);
|
|
} else {
|
|
int n = sscanf(cw,"%d %d",&x,&y);
|
|
if (n == 2) { // back compatibility...
|
|
if (x != 47) o->color(x);
|
|
o->selection_color(y);
|
|
} else {
|
|
o->color(x);
|
|
}
|
|
}
|
|
} else if (!strcmp(c,"selection_color")) {
|
|
if (sscanf(f.read_word(),"%d",&x)) o->selection_color(x);
|
|
} else if (!strcmp(c,"labeltype")) {
|
|
c = f.read_word();
|
|
if (!strcmp(c,"image")) {
|
|
Fluid_Image *i = Fluid_Image::find(label());
|
|
if (!i) f.read_error("Image file '%s' not found", label());
|
|
else setimage(i);
|
|
image_name(label());
|
|
label("");
|
|
} else {
|
|
o->labeltype((Fl_Labeltype)item_number(labeltypemenu,c));
|
|
}
|
|
} else if (!strcmp(c,"labelfont")) {
|
|
if (sscanf(f.read_word(),"%d",&x) == 1) o->labelfont(x);
|
|
} else if (!strcmp(c,"labelsize")) {
|
|
if (sscanf(f.read_word(),"%d",&x) == 1) o->labelsize(x);
|
|
} else if (!strcmp(c,"labelcolor")) {
|
|
if (sscanf(f.read_word(),"%d",&x) == 1) o->labelcolor(x);
|
|
} else if (!strcmp(c,"align")) {
|
|
if (sscanf(f.read_word(),"%d",&x) == 1) o->align(x);
|
|
} else if (!strcmp(c,"h_label_margin")) {
|
|
if (sscanf(f.read_word(),"%d",&x) == 1) o->horizontal_label_margin(x);
|
|
} else if (!strcmp(c,"v_label_margin")) {
|
|
if (sscanf(f.read_word(),"%d",&x) == 1) o->vertical_label_margin(x);
|
|
} else if (!strcmp(c,"image_spacing")) {
|
|
if (sscanf(f.read_word(),"%d",&x) == 1) o->label_image_spacing(x);
|
|
} else if (!strcmp(c,"when")) {
|
|
if (sscanf(f.read_word(),"%d",&x) == 1) o->when(x);
|
|
} else if (!strcmp(c,"minimum")) {
|
|
if (is_a(ID_Valuator_)) ((Fl_Valuator*)o)->minimum(strtod(f.read_word(),0));
|
|
if (is_a(ID_Spinner)) ((Fl_Spinner*)o)->minimum(strtod(f.read_word(),0));
|
|
} else if (!strcmp(c,"maximum")) {
|
|
if (is_a(ID_Valuator_)) ((Fl_Valuator*)o)->maximum(strtod(f.read_word(),0));
|
|
if (is_a(ID_Spinner)) ((Fl_Spinner*)o)->maximum(strtod(f.read_word(),0));
|
|
} else if (!strcmp(c,"step")) {
|
|
if (is_a(ID_Valuator_)) ((Fl_Valuator*)o)->step(strtod(f.read_word(),0));
|
|
if (is_a(ID_Spinner)) ((Fl_Spinner*)o)->step(strtod(f.read_word(),0));
|
|
} else if (!strcmp(c,"value")) {
|
|
if (is_a(ID_Valuator_)) ((Fl_Valuator*)o)->value(strtod(f.read_word(),0));
|
|
if (is_a(ID_Spinner)) ((Fl_Spinner*)o)->value(strtod(f.read_word(),0));
|
|
} else if ( (!strcmp(c,"slider_size") || !strcmp(c,"size")) && is_a(ID_Slider)) {
|
|
((Fl_Slider*)o)->slider_size(strtod(f.read_word(),0));
|
|
} else if (!strcmp(c,"textfont")) {
|
|
if (sscanf(f.read_word(),"%d",&x) == 1) {ft=(Fl_Font)x; textstuff(1,ft,s,cc);}
|
|
} else if (!strcmp(c,"textsize")) {
|
|
if (sscanf(f.read_word(),"%d",&x) == 1) {s=x; textstuff(2,ft,s,cc);}
|
|
} else if (!strcmp(c,"textcolor")) {
|
|
if (sscanf(f.read_word(),"%d",&x) == 1) {cc=(Fl_Color)x;textstuff(3,ft,s,cc);}
|
|
} else if (!strcmp(c,"hide")) {
|
|
o->hide();
|
|
} else if (!strcmp(c,"deactivate")) {
|
|
o->deactivate();
|
|
} else if (!strcmp(c,"resizable")) {
|
|
resizable(1);
|
|
} else if (!strcmp(c,"hotspot") || !strcmp(c, "divider")) {
|
|
hotspot(1);
|
|
} else if (!strcmp(c,"class")) {
|
|
subclass(f.read_word());
|
|
} else if (!strcmp(c,"shortcut")) {
|
|
int shortcut = (int)strtol(f.read_word(),0,0);
|
|
if (is_button()) ((Fl_Button*)o)->shortcut(shortcut);
|
|
else if (is_a(ID_Input)) ((Fl_Input_*)o)->shortcut(shortcut);
|
|
else if (is_a(ID_Value_Input)) ((Fl_Value_Input*)o)->shortcut(shortcut);
|
|
else if (is_a(ID_Text_Display)) ((Fl_Text_Display*)o)->shortcut(shortcut);
|
|
} else {
|
|
if (!strncmp(c,"code",4)) {
|
|
int n = atoi(c+4);
|
|
if (n >= 0 && n <= NUM_EXTRA_CODE) {
|
|
extra_code(n,f.read_word());
|
|
return;
|
|
}
|
|
} else if (!strcmp(c,"extra_code")) {
|
|
extra_code(0,f.read_word());
|
|
return;
|
|
}
|
|
Fl_Type::read_property(f, c);
|
|
}
|
|
}
|
|
|
|
Fl_Menu_Item boxmenu1[] = {
|
|
// these extra ones are for looking up fdesign saved strings:
|
|
{"NO_FRAME", 0,0,(void *)FL_NO_BOX},
|
|
{"ROUNDED3D_UPBOX", 0,0,(void *)_FL_ROUND_UP_BOX},
|
|
{"ROUNDED3D_DOWNBOX", 0,0,(void *)_FL_ROUND_DOWN_BOX},
|
|
{"OVAL3D_UPBOX", 0,0,(void *)_FL_ROUND_UP_BOX},
|
|
{"OVAL3D_DOWNBOX", 0,0,(void *)_FL_ROUND_DOWN_BOX},
|
|
{"0", 0,0,(void *)ZERO_ENTRY},
|
|
{"1", 0,0,(void *)FL_UP_BOX},
|
|
{"2", 0,0,(void *)FL_DOWN_BOX},
|
|
{"3", 0,0,(void *)FL_FLAT_BOX},
|
|
{"4", 0,0,(void *)FL_BORDER_BOX},
|
|
{"5", 0,0,(void *)FL_SHADOW_BOX},
|
|
{"6", 0,0,(void *)FL_FRAME_BOX},
|
|
{"7", 0,0,(void *)FL_ROUNDED_BOX},
|
|
{"8", 0,0,(void *)FL_RFLAT_BOX},
|
|
{"9", 0,0,(void *)FL_RSHADOW_BOX},
|
|
{"10", 0,0,(void *)FL_UP_FRAME},
|
|
{"11", 0,0,(void *)FL_DOWN_FRAME},
|
|
{0}};
|
|
|
|
int lookup_symbol(const char *, int &, int numberok = 0);
|
|
|
|
int Fl_Widget_Type::read_fdesign(const char* propname, const char* value) {
|
|
int v;
|
|
if (!strcmp(propname,"box")) {
|
|
float x,y,w,h;
|
|
if (sscanf(value,"%f %f %f %f",&x,&y,&w,&h) == 4) {
|
|
if (fdesign_flip) {
|
|
Fl_Type *p;
|
|
for (p = parent; p && !p->is_a(ID_Window); p = p->parent) {/*empty*/}
|
|
if (p && p->is_widget()) y = ((Fl_Widget_Type*)p)->o->h()-(y+h);
|
|
}
|
|
x += pasteoffset;
|
|
y += pasteoffset;
|
|
o->resize(int(x),int(y),int(w),int(h));
|
|
}
|
|
} else if (!strcmp(propname,"label")) {
|
|
label(value);
|
|
} else if (!strcmp(propname,"name")) {
|
|
this->name(value);
|
|
} else if (!strcmp(propname,"callback")) {
|
|
callback(value); user_data_type("long");
|
|
} else if (!strcmp(propname,"argument")) {
|
|
user_data(value);
|
|
} else if (!strcmp(propname,"shortcut")) {
|
|
if (value[0]) {
|
|
char buf[128]; sprintf(buf,"o->shortcut(\"%s\");",value);
|
|
extra_code(0,buf);
|
|
}
|
|
} else if (!strcmp(propname,"style")) {
|
|
if (!strncmp(value,"FL_NORMAL",9)) return 1;
|
|
if (!lookup_symbol(value,v,1)) return 0;
|
|
o->labelfont(v); o->labeltype((Fl_Labeltype)(v>>8));
|
|
} else if (!strcmp(propname,"size")) {
|
|
if (!lookup_symbol(value,v,1)) return 0;
|
|
o->labelsize(v);
|
|
} else if (!strcmp(propname,"type")) {
|
|
if (!strncmp(value,"NORMAL",6)) return 1;
|
|
if (lookup_symbol(value,v,1)) {o->type(v); return 1;}
|
|
if (!strcmp(value+strlen(value)-5,"FRAME")) goto TRY_BOXTYPE;
|
|
if (!strcmp(value+strlen(value)-3,"BOX")) goto TRY_BOXTYPE;
|
|
return 0;
|
|
} else if (!strcmp(propname,"lcol")) {
|
|
if (!lookup_symbol(value,v,1)) return 0;
|
|
o->labelcolor(v);
|
|
} else if (!strcmp(propname,"return")) {
|
|
if (!lookup_symbol(value,v,0)) return 0;
|
|
o->when(v|FL_WHEN_RELEASE);
|
|
} else if (!strcmp(propname,"alignment")) {
|
|
if (!lookup_symbol(value,v)) {
|
|
// convert old numeric values:
|
|
int v1 = atoi(value); if (v1 <= 0 && strcmp(value,"0")) return 0;
|
|
v = 0;
|
|
if (v1 >= 5) {v = FL_ALIGN_INSIDE; v1 -= 5;}
|
|
switch (v1) {
|
|
case 0: v += FL_ALIGN_TOP; break;
|
|
case 1: v += FL_ALIGN_BOTTOM; break;
|
|
case 2: v += FL_ALIGN_LEFT; break;
|
|
case 3: v += FL_ALIGN_RIGHT; break;
|
|
case 4: v += FL_ALIGN_CENTER; break;
|
|
default: return 0;
|
|
}
|
|
}
|
|
o->align(v);
|
|
} else if (!strcmp(propname,"resizebox")) {
|
|
resizable(1);
|
|
} else if (!strcmp(propname,"colors")) {
|
|
char* p = (char*)value;
|
|
while (*p != ' ') {if (!*p) return 0; p++;}
|
|
*p = 0;
|
|
int v1;
|
|
if (!lookup_symbol(value,v,1) || !lookup_symbol(p+1,v1,1)) {
|
|
*p=' '; return 0;}
|
|
o->color(v,v1);
|
|
} else if (!strcmp(propname,"resize")) {
|
|
return !strcmp(value,"FL_RESIZE_ALL");
|
|
} else if (!strcmp(propname,"gravity")) {
|
|
return !strcmp(value,"FL_NoGravity FL_NoGravity");
|
|
} else if (!strcmp(propname,"boxtype")) {
|
|
TRY_BOXTYPE:
|
|
int x = boxnumber(value);
|
|
if (!x) {x = item_number(boxmenu1, value); if (x < 0) return 0;}
|
|
if (x == ZERO_ENTRY) {
|
|
x = 0;
|
|
if (o->box() != ((Fl_Widget_Type*)factory)->o->box()) return 1; // kludge for frame
|
|
}
|
|
o->box((Fl_Boxtype)x);
|
|
} else {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void leave_live_mode_cb(Fl_Widget*, void*) {
|
|
live_mode_cb(0, 0);
|
|
}
|
|
|
|
Fl_Widget *Fl_Widget_Type::enter_live_mode(int) {
|
|
live_widget = widget(o->x(), o->y(), o->w(), o->h());
|
|
if (live_widget)
|
|
copy_properties();
|
|
return live_widget;
|
|
}
|
|
|
|
Fl_Widget* Fl_Widget_Type::propagate_live_mode(Fl_Group* grp) {
|
|
live_widget = grp;
|
|
copy_properties();
|
|
Fl_Type *n;
|
|
for (n = next; n && n->level > level; n = n->next) {
|
|
if (n->level == level+1) {
|
|
Fl_Widget* proxy_child = n->enter_live_mode();
|
|
if (proxy_child && n->is_widget() && ((Fl_Widget_Type*)n)->resizable()) {
|
|
grp->resizable(proxy_child);
|
|
}
|
|
}
|
|
}
|
|
grp->end();
|
|
return live_widget;
|
|
}
|
|
|
|
|
|
void Fl_Widget_Type::leave_live_mode() {
|
|
}
|
|
|
|
/**
|
|
copy all properties from the edit widget to the live widget
|
|
*/
|
|
void Fl_Widget_Type::copy_properties() {
|
|
if (!live_widget)
|
|
return;
|
|
|
|
Fl_Font ff = 0;
|
|
int fs = 0;
|
|
Fl_Color fc = 0;
|
|
textstuff(0, ff, fs, fc);
|
|
|
|
// copy all attributes common to all widget types
|
|
Fl_Widget *w = live_widget;
|
|
w->label(o->label());
|
|
w->tooltip(tooltip());
|
|
w->type(o->type());
|
|
w->box(o->box());
|
|
w->color(o->color());
|
|
w->selection_color(o->selection_color());
|
|
w->labeltype(o->labeltype());
|
|
w->labelfont(o->labelfont());
|
|
w->labelsize(o->labelsize());
|
|
w->labelcolor(o->labelcolor());
|
|
w->align(o->align());
|
|
w->when(o->when());
|
|
|
|
// copy all attributes specific to widgets derived from Fl_Button
|
|
if (is_button()) {
|
|
Fl_Button* d = (Fl_Button*)live_widget, *s = (Fl_Button*)o;
|
|
d->down_box(s->down_box());
|
|
d->shortcut(s->shortcut());
|
|
d->value(s->value());
|
|
}
|
|
|
|
// copy all attributes specific to widgets derived from Fl_Input_
|
|
if (is_a(ID_Input)) {
|
|
Fl_Input_* d = (Fl_Input_*)live_widget, *s = (Fl_Input_*)o;
|
|
d->shortcut(s->shortcut());
|
|
d->textfont(ff);
|
|
d->textsize(fs);
|
|
d->textcolor(fc);
|
|
}
|
|
|
|
// copy all attributes specific to widgets derived from Fl_Value_Input
|
|
if (is_a(ID_Value_Input)) {
|
|
Fl_Value_Input* d = (Fl_Value_Input*)live_widget, *s = (Fl_Value_Input*)o;
|
|
d->shortcut(s->shortcut());
|
|
d->textfont(ff);
|
|
d->textsize(fs);
|
|
d->textcolor(fc);
|
|
}
|
|
|
|
// copy all attributes specific to widgets derived from Fl_Text_Display
|
|
if (is_a(ID_Text_Display)) {
|
|
Fl_Text_Display* d = (Fl_Text_Display*)live_widget, *s = (Fl_Text_Display*)o;
|
|
d->shortcut(s->shortcut());
|
|
d->textfont(ff);
|
|
d->textsize(fs);
|
|
d->textcolor(fc);
|
|
}
|
|
|
|
// copy all attributes specific to Fl_Valuator and derived classes
|
|
if (is_a(ID_Valuator_)) {
|
|
Fl_Valuator* d = (Fl_Valuator*)live_widget, *s = (Fl_Valuator*)o;
|
|
d->minimum(s->minimum());
|
|
d->maximum(s->maximum());
|
|
d->step(s->step());
|
|
d->value(s->value());
|
|
if (is_a(ID_Slider)) {
|
|
Fl_Slider *d = (Fl_Slider*)live_widget, *s = (Fl_Slider*)o;
|
|
d->slider_size(s->slider_size());
|
|
}
|
|
}
|
|
|
|
// copy all attributes specific to Fl_Spinner and derived classes
|
|
if (is_a(ID_Spinner)) {
|
|
Fl_Spinner* d = (Fl_Spinner*)live_widget, *s = (Fl_Spinner*)o;
|
|
d->minimum(s->minimum());
|
|
d->maximum(s->maximum());
|
|
d->step(s->step());
|
|
d->value(s->value());
|
|
}
|
|
|
|
if (!o->visible())
|
|
w->hide();
|
|
if (!o->active())
|
|
w->deactivate();
|
|
}
|
|
|