Added visual gudelines for widget distances and sizes to fluid. It is disabled by default, but can be enabled in the "Grid" dialog box. I am not sure if this is actually a good change, but thanks to SVN I'll risk a commit to get some feedback fro the early adopters.

Fluid now indicates a "good" (according to some Apple guidelines, but that's not permanent y any means) distance of widgets to the window border, indicates vertical and horizontal alignment with other widgets, shows "good" sizes for buttons, and indicates a good distance between two buttons at the same y-position.

Achtung, Baby: I wrote this on a WIndows machine, hoping that SVN will replce CR/LF with LF's, as promised by the documentation. Unix users: please check and blame me!

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@4057 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Matthias Melcher 2005-02-26 20:27:19 +00:00
parent 3145a0d010
commit 5b49a9ae51
5 changed files with 204 additions and 56 deletions

View File

@ -38,9 +38,12 @@
#include "alignment_panel.h"
#include <stdio.h>
#define DRAW_GUIDES
extern int gridx;
extern int gridy;
extern int snap;
extern int show_guides;
int include_H_from_C = 1;
extern int i18n_type;
@ -64,6 +67,18 @@ static void update_xywh() {
}
}
void guides_cb(Fl_Check_Button *i, long) {
show_guides = i->value();
fluid_prefs.set("show_guides", show_guides);
for (Fl_Type *p = Fl_Type::first; p; p = p->next) {
if (p->is_window()) {
Fl_Window_Type *w = (Fl_Window_Type *)p;
((Fl_Overlay_Window *)(w->o))->redraw_overlay();
}
}
}
void grid_cb(Fl_Input *i, long v) {
int n = atoi(i->value());
if (n < 0) n = 0;
@ -187,6 +202,7 @@ void show_grid_cb(Fl_Widget *, void *) {
sprintf(buf,"%d",gridx); horizontal_input->value(buf);
sprintf(buf,"%d",gridy); vertical_input->value(buf);
sprintf(buf,"%d",snap); snap_input->value(buf);
guides_toggle->value(show_guides);
grid_window->hotspot(grid_window);
grid_window->show();
}
@ -463,6 +479,81 @@ void Fl_Window_Type::newposition(Fl_Widget_Type *myo,int &X,int &Y,int &R,int &T
if (T<Y) {int n = Y; Y = T; T = n;}
}
// draw a vertical arrow pointing toward y2
static void draw_v_arrow(int x, int y1, int y2) {
int dy = (y1>y2) ? -1 : 1 ;
fl_yxline(x, y1, y2);
fl_xyline(x-4, y2, x+4);
fl_line(x-2, y2-dy*5, x, y2-dy);
fl_line(x+2, y2-dy*5, x, y2-dy);
char buf[16];
sprintf(buf, "%d", dy*(y2-y1));
fl_font(FL_HELVETICA, 9);
fl_draw(buf, x+3, y1+0.5*(y2-y1)+3);
}
static void draw_h_arrow(int x1, int y, int x2) {
int dx = (x1>x2) ? -1 : 1 ;
fl_xyline(x1, y, x2);
fl_yxline(x2, y-4, y+4);
fl_line(x2-dx*5, y-2, x2-dx, y);
fl_line(x2-dx*5, y+2, x2-dx, y);
char buf[16];
sprintf(buf, "%d", dx*(x2-x1));
fl_font(FL_HELVETICA, 9);
fl_draw(buf, x1+0.5*(x2-x1)-6, y+9);
}
static void draw_top_brace(const Fl_Widget *w) {
fl_yxline(w->x(), w->y()-2, w->y()+6);
fl_yxline(w->x()+w->w()-1, w->y()-2, w->y()+6);
fl_xyline(w->x()-2, w->y(), w->x()+w->w()+1);
}
static void draw_left_brace(const Fl_Widget *w) {
fl_xyline(w->x()-2, w->y(), w->x()+6);
fl_xyline(w->x()-2, w->y()+w->h()-1, w->x()+6);
fl_yxline(w->x(), w->y()-2, w->y()+w->h()+1);
}
static void draw_right_brace(const Fl_Widget *w) {
int xx = w->x() + w->w() - 1;
fl_xyline(xx-6, w->y(), xx+2);
fl_xyline(xx-6, w->y()+w->h()-1, xx+2);
fl_yxline(xx, w->y()-2, w->y()+w->h()+1);
}
static void draw_bottom_brace(const Fl_Widget *w) {
int yy = w->y() + w->h() - 1;
fl_yxline(w->x(), yy-6, yy+2);
fl_yxline(w->x()+w->w()-1, yy-6, yy+2);
fl_xyline(w->x()-2, yy, w->x()+w->w()+1);
}
static void draw_height(int x, int y, int b) {
b--;
fl_yxline(x, y, y+8);
fl_yxline(x, b-8, b);
fl_line(x-2, y+5, x, y+1, x+2, y+5);
fl_line(x-2, b-5, x, b-1, x+2, b-5);
char buf[16];
sprintf(buf, "%d", b-y+1);
fl_font(FL_HELVETICA, 9);
fl_draw(buf, x+3, b-3);
}
static void draw_width(int x, int y, int r) {
r--;
fl_xyline(x, y, x+8);
fl_xyline(r-8, y, r);
fl_line(x+5, y-2, x+1, y, x+5, y+2);
fl_line(r-5, y-2, r-1, y, r-5, y+2);
char buf[16];
sprintf(buf, "%d", r-x+1);
fl_font(FL_HELVETICA, 9);
fl_draw(buf, r-5-fl_width(buf), y-1);
}
void Fl_Window_Type::draw_overlay() {
if (recalc) {
bx = o->w(); by = o->h(); br = 0; bt = 0;
@ -489,8 +580,10 @@ void Fl_Window_Type::draw_overlay() {
if (!numselected) return;
int mybx,myby,mybr,mybt;
mybx = o->w(); myby = o->h(); mybr = 0; mybt = 0;
Fl_Type *selection = 0L; // used to store the one selcted widget (if n==1)
for (Fl_Type *q=next; q && q->level>level; q = q->next)
if (q->selected && q->is_widget() && !q->is_menu_item()) {
selection = q;
Fl_Widget_Type* myo = (Fl_Widget_Type*)q;
int x,y,r,t;
newposition(myo,x,y,r,t);
@ -506,6 +599,50 @@ void Fl_Window_Type::draw_overlay() {
fl_rectf(mybr-5,myby,5,5);
fl_rectf(mybr-5,mybt-5,5,5);
fl_rectf(mybx,mybt-5,5,5);
if (show_guides) {
// draw overlays for UI Guideline distances
// - check for distance to the window edge
// * Apple suggest 14 pixels from the top
if (myby==14) draw_v_arrow(mybx+5, myby, 0);
// * Apple suggest 20 pixels from the top
if (o->h()-mybt-1==20) draw_v_arrow(mybx+5, mybt, o->h()-1);
// * Apple suggest 20 pixels from the left
if (mybx==20) draw_h_arrow(mybx, myby+5, 0);
// * Apple suggest 20 pixels from the right
if (o->w()-mybr-1==20) draw_h_arrow(mybr, myby+5, o->w()-1);
// - the following measuremetnt only apply to single selections
if (numselected==1 && selection) {
// check for Apple prefered button sizes
if (selection->is_button()) {
int h = mybt-myby;
if (h==20 || h==17 || h==15) draw_height(mybx+10, myby, mybt);
int w = mybr-mybx;
if (w==68) draw_width(mybx, myby+10, mybr);
}
// - check distances between individual widgets
for (Fl_Type *q=next; q && q->level>level; q = q->next)
if (q != selection) {
Fl_Widget_Type *qw = (Fl_Widget_Type*)q;
// - check horizontal and vertical alignment with other widgets
if (myby == qw->o->y()) draw_top_brace(qw->o);
if (mybx == qw->o->x()) draw_left_brace(qw->o);
if (mybr == qw->o->x()+qw->o->w()) draw_right_brace(qw->o);
if (mybt == qw->o->y()+qw->o->h()) draw_bottom_brace(qw->o);
if (selection->is_button()) {
// - check distances between buttons
if (q->is_button() && qw->o->y()==myby) {
// * horizontal button to button is 12 or 24 pixels
int dx = mybx - (qw->o->x()+qw->o->w());
if (dx==12 || dx==24) draw_h_arrow(mybx-1, myby+10, mybx-dx-1);
dx = qw->o->x() - mybr;
if (dx==12 || dx==24) draw_h_arrow(mybr, myby+10, mybr+dx);
}
}
}
}
// \todo add more cases, maybe an interpreter?
}
}
// Calculate new bounding box of selected widgets:

View File

@ -1,8 +1,8 @@
// generated by Fast Light User Interface Designer (fluid) version 1.0104
// generated by Fast Light User Interface Designer (fluid) version 1.0107
#include "alignment_panel.h"
Fl_Window *project_window=(Fl_Window *)0;
Fl_Double_Window *project_window=(Fl_Double_Window *)0;
static void cb_Close(Fl_Button*, void*) {
project_window->hide();
@ -17,10 +17,10 @@ Fl_Light_Button *include_H_from_C_button=(Fl_Light_Button *)0;
Fl_Choice *i18n_type_chooser=(Fl_Choice *)0;
Fl_Menu_Item menu_i18n_type_chooser[] = {
{"None", 0, 0, 0, 0, 0, 0, 14, 56},
{"GNU gettext", 0, 0, 0, 0, 0, 0, 14, 56},
{"POSIX catgets", 0, 0, 0, 0, 0, 0, 14, 56},
{0}
{"None", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 56},
{"GNU gettext", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 56},
{"POSIX catgets", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 56},
{0,0,0,0,0,0,0,0,0}
};
Fl_Input *i18n_include_input=(Fl_Input *)0;
@ -31,9 +31,9 @@ Fl_Input *i18n_set_input=(Fl_Input *)0;
Fl_Input *i18n_function_input=(Fl_Input *)0;
Fl_Window* make_project_window() {
Fl_Window* w;
{ Fl_Window* o = project_window = new Fl_Window(365, 210, "Project Settings");
Fl_Double_Window* make_project_window() {
Fl_Double_Window* w;
{ Fl_Double_Window* o = project_window = new Fl_Double_Window(365, 210, "Project Settings");
w = o;
{ Fl_Button* o = new Fl_Button(295, 175, 60, 25, "Close");
o->tooltip("Close this dialog.");
@ -112,7 +112,7 @@ Fl_Window* make_project_window() {
}
Fl_Text_Buffer *shell_run_buffer;
Fl_Window *settings_window=(Fl_Window *)0;
Fl_Double_Window *settings_window=(Fl_Double_Window *)0;
static void cb_Close1(Fl_Button*, void*) {
settings_window->hide();
@ -143,9 +143,9 @@ static void cb_prevpos_button(Fl_Check_Button*, void*) {
fluid_prefs.set("prev_window_pos", prevpos_button->value());
}
Fl_Window* make_settings_window() {
Fl_Window* w;
{ Fl_Window* o = settings_window = new Fl_Window(255, 210, "GUI Settings");
Fl_Double_Window* make_settings_window() {
Fl_Double_Window* w;
{ Fl_Double_Window* o = settings_window = new Fl_Double_Window(255, 210, "GUI Settings");
w = o;
{ Fl_Button* o = new Fl_Button(185, 179, 60, 25, "Close");
o->tooltip("Close this dialog.");
@ -192,7 +192,7 @@ Fl_Window* make_settings_window() {
return w;
}
Fl_Window *shell_window=(Fl_Window *)0;
Fl_Double_Window *shell_window=(Fl_Double_Window *)0;
Fl_Input *shell_command_input=(Fl_Input *)0;
@ -222,7 +222,7 @@ static void cb_Cancel(Fl_Button*, void*) {
shell_window->hide();
}
Fl_Window *shell_run_window=(Fl_Window *)0;
Fl_Double_Window *shell_run_window=(Fl_Double_Window *)0;
Fl_Return_Button *shell_run_button=(Fl_Return_Button *)0;
@ -232,9 +232,9 @@ static void cb_shell_run_button(Fl_Return_Button*, void*) {
Fl_Text_Display *shell_run_display=(Fl_Text_Display *)0;
Fl_Window* make_shell_window() {
Fl_Window* w;
{ Fl_Window* o = shell_window = new Fl_Window(450, 145, "Shell Command");
Fl_Double_Window* make_shell_window() {
Fl_Double_Window* w;
{ Fl_Double_Window* o = shell_window = new Fl_Double_Window(450, 145, "Shell Command");
w = o;
{ Fl_Tabs* o = new Fl_Tabs(10, 10, 430, 90);
{ Fl_Group* o = new Fl_Group(10, 30, 430, 70, "Shell Command");
@ -278,7 +278,7 @@ Fl_Window* make_shell_window() {
}
o->end();
}
{ Fl_Window* o = shell_run_window = new Fl_Window(555, 435, "Shell Command Output");
{ Fl_Double_Window* o = shell_run_window = new Fl_Double_Window(555, 435, "Shell Command Output");
w = o;
{ Fl_Return_Button* o = shell_run_button = new Fl_Return_Button(465, 400, 80, 25, "Close");
o->callback((Fl_Callback*)cb_shell_run_button);
@ -295,7 +295,7 @@ Fl_Window* make_shell_window() {
return w;
}
Fl_Window *grid_window=(Fl_Window *)0;
Fl_Double_Window *grid_window=(Fl_Double_Window *)0;
Fl_Input *horizontal_input=(Fl_Input *)0;
@ -303,17 +303,19 @@ Fl_Input *vertical_input=(Fl_Input *)0;
Fl_Input *snap_input=(Fl_Input *)0;
Fl_Check_Button *guides_toggle=(Fl_Check_Button *)0;
static void cb_Close2(Fl_Button*, void*) {
grid_window->hide();
}
Fl_Window* make_grid_window() {
Fl_Window* w;
{ Fl_Window* o = grid_window = new Fl_Window(155, 175, "Grid");
Fl_Double_Window* make_grid_window() {
Fl_Double_Window* w;
{ Fl_Double_Window* o = grid_window = new Fl_Double_Window(155, 208, "Grid");
w = o;
{ Fl_Tabs* o = new Fl_Tabs(10, 10, 135, 120);
{ Fl_Tabs* o = new Fl_Tabs(10, 10, 135, 150);
o->align(FL_ALIGN_TOP_LEFT);
{ Fl_Group* o = new Fl_Group(10, 30, 135, 100, "Grid");
{ Fl_Group* o = new Fl_Group(10, 30, 135, 130, "Grid");
o->align(FL_ALIGN_TOP_LEFT);
{ Fl_Input* o = horizontal_input = new Fl_Input(95, 40, 40, 20, "Horizontal:");
o->tooltip("Horizontal grid spacing.");
@ -336,11 +338,16 @@ Fl_Window* make_grid_window() {
o->callback((Fl_Callback*)grid_cb, (void*)(3));
o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);
}
{ Fl_Check_Button* o = guides_toggle = new Fl_Check_Button(30, 125, 105, 25, "Show Guides");
o->tooltip("Show distance and alignment guides in overlay");
o->down_box(FL_DOWN_BOX);
o->callback((Fl_Callback*)guides_cb, (void*)(4));
}
o->end();
}
o->end();
}
{ Fl_Button* o = new Fl_Button(85, 140, 60, 25, "Close");
{ Fl_Button* o = new Fl_Button(85, 170, 60, 25, "Close");
o->tooltip("Close this dialog.");
o->callback((Fl_Callback*)cb_Close2);
}

View File

@ -1,5 +1,5 @@
# data file for the Fltk User Interface Designer (fluid)
version 1.0103
version 1.0107
header_name {.h}
code_name {.cxx}
decl {\#include <FL/Fl_Text_Buffer.H>} {public
@ -12,7 +12,7 @@ Function {make_project_window()} {open
} {
Fl_Window project_window {
label {Project Settings} open
xywh {469 112 365 210}
xywh {217 589 365 210} type Double
code0 {\#include <FL/Fl_Preferences.H>}
code1 {\#include <FL/Fl_Tooltip.H>} modal visible
} {
@ -103,14 +103,14 @@ decl {extern void i18n_cb(Fl_Choice *,void *);} {public
decl {extern Fl_Preferences fluid_prefs;} {public
}
decl {Fl_Text_Buffer *shell_run_buffer;} {selected public
decl {Fl_Text_Buffer *shell_run_buffer;} {public
}
Function {make_settings_window()} {open
} {
Fl_Window settings_window {
label {GUI Settings} open
xywh {340 243 255 210} visible
xywh {321 150 255 210} type Double visible
} {
Fl_Button {} {
label Close
@ -167,7 +167,7 @@ Function {make_shell_window()} {open
} {
Fl_Window shell_window {
label {Shell Command} open
xywh {630 219 450 145} visible
xywh {588 153 450 145} type Double visible
} {
Fl_Tabs {} {open
xywh {10 10 430 90}
@ -222,7 +222,7 @@ Function {make_shell_window()} {open
}
Fl_Window shell_run_window {
label {Shell Command Output} open
xywh {693 386 555 435} resizable visible
xywh {592 332 555 435} type Double resizable visible
} {
Fl_Return_Button shell_run_button {
label Close
@ -241,14 +241,14 @@ Function {make_grid_window()} {open
} {
Fl_Window grid_window {
label Grid open
xywh {1120 236 155 175} visible
xywh {51 589 155 208} type Double visible
} {
Fl_Tabs {} {
xywh {10 10 135 120} align 5
xywh {10 10 135 150} align 5
} {
Fl_Group {} {
label Grid
xywh {10 30 135 100} align 5
xywh {10 30 135 130} align 5
} {
Fl_Input horizontal_input {
label {Horizontal:}
@ -271,12 +271,18 @@ Function {make_grid_window()} {open
tooltip {Snap to grid within this many pixels.} xywh {95 100 40 20} type Int box THIN_DOWN_BOX
code0 {o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);}
}
Fl_Check_Button guides_toggle {
label {Show Guides}
user_data 4 user_data_type long
callback guides_cb selected
tooltip {Show distance and alignment guides in overlay} xywh {30 125 105 25} down_box DOWN_BOX
}
}
}
Fl_Button {} {
label Close
callback {grid_window->hide();}
tooltip {Close this dialog.} xywh {85 140 60 25}
tooltip {Close this dialog.} xywh {85 170 60 25}
}
}
}

View File

@ -1,14 +1,14 @@
// generated by Fast Light User Interface Designer (fluid) version 1.0104
// generated by Fast Light User Interface Designer (fluid) version 1.0107
#ifndef alignment_panel_h
#define alignment_panel_h
#include <FL/Fl.H>
#include <FL/Fl_Text_Buffer.H>
#include <FL/Fl_Text_Display.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Preferences.H>
#include <FL/Fl_Tooltip.H>
extern Fl_Window *project_window;
extern Fl_Double_Window *project_window;
#include <FL/Fl_Button.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Group.H>
@ -29,34 +29,36 @@ extern Fl_Input *i18n_include_input;
extern Fl_Input *i18n_file_input;
extern Fl_Input *i18n_set_input;
extern Fl_Input *i18n_function_input;
Fl_Window* make_project_window();
Fl_Double_Window* make_project_window();
extern Fl_Menu_Item menu_i18n_type_chooser[];
extern void i18n_cb(Fl_Choice *,void *);
extern Fl_Preferences fluid_prefs;
extern Fl_Text_Buffer *shell_run_buffer;
extern Fl_Window *settings_window;
extern Fl_Double_Window *settings_window;
#include <FL/Fl_Check_Button.H>
extern Fl_Check_Button *tooltips_button;
extern Fl_Check_Button *completion_button;
extern Fl_Check_Button *openlast_button;
extern Fl_Check_Button *prevpos_button;
Fl_Window* make_settings_window();
extern Fl_Window *shell_window;
Fl_Double_Window* make_settings_window();
extern Fl_Double_Window *shell_window;
extern Fl_Input *shell_command_input;
extern Fl_Check_Button *shell_savefl_button;
extern Fl_Check_Button *shell_writecode_button;
extern Fl_Check_Button *shell_writemsgs_button;
#include <FL/Fl_Return_Button.H>
extern void do_shell_command(Fl_Return_Button*, void*);
extern Fl_Window *shell_run_window;
extern Fl_Double_Window *shell_run_window;
extern Fl_Return_Button *shell_run_button;
#include <FL/Fl_Text_Display.H>
extern Fl_Text_Display *shell_run_display;
Fl_Window* make_shell_window();
extern Fl_Window *grid_window;
Fl_Double_Window* make_shell_window();
extern Fl_Double_Window *grid_window;
extern void grid_cb(Fl_Input*, long);
extern Fl_Input *horizontal_input;
extern Fl_Input *vertical_input;
extern Fl_Input *snap_input;
Fl_Window* make_grid_window();
extern void guides_cb(Fl_Check_Button*, long);
extern Fl_Check_Button *guides_toggle;
Fl_Double_Window* make_grid_window();
#endif

View File

@ -65,6 +65,7 @@ Fl_Preferences fluid_prefs(Fl_Preferences::USER, "fltk.org", "fluid");
int gridx = 5;
int gridy = 5;
int snap = 1;
int show_guides = 1;
// File history info...
char absolute_history[10][1024];
@ -558,16 +559,11 @@ Fl_Menu_Item Main_Menu[] = {
extern void fill_in_New_Menu();
void make_main_window() {
int i;
fluid_prefs.get("snap", i, 1);
snap = i;
fluid_prefs.get("gridx", i, 5);
gridx = i;
fluid_prefs.get("gridy", i, 5);
gridy = i;
fluid_prefs.get("snap", snap, 1);
fluid_prefs.get("gridx", gridx, 5);
fluid_prefs.get("gridy", gridy, 5);
fluid_prefs.get("show_guides", show_guides, 0);
load_history();