Browse Source

Added some FLTK draw primitives.

mingodad 13 years ago
parent
commit
138e823ab4
5 changed files with 661 additions and 78 deletions
  1. 1 1
      editor/editor.cxx
  2. 289 70
      ext/sq_fltk.cpp
  3. 364 0
      ourbiz/fl-bar-chart.nut
  4. 6 6
      ourbiz/ourbiz-fltk.nut
  5. 1 1
      ourbiz/utils-fltk.nut

+ 1 - 1
editor/editor.cxx

@@ -930,7 +930,7 @@ static void sq_debug_hook(HSQUIRRELVM v, SQInteger ev_type, const SQChar *source
             printf("LINE line [%d] func [%s] r\n", line, fname);
         break;
     }
-    while(_debug_wait){
+    while(_debug_wait && !_stop_debug){
         Fl::wait(0.01);
     }
     _debug_wait = true;

+ 289 - 70
ext/sq_fltk.cpp

@@ -45,7 +45,8 @@
 #include <FLU/Flu_Combo_Tree.H>
 #include <FLU/Flu_Tree_Browser.H>
 
-#include <squirrel.h>
+#include <squirrel.h>
+SQ_OPT_STRING_STRLEN();
 
 #include "sqfltk.h"
 
@@ -2692,16 +2693,79 @@ static SQInteger _fl_get_font_name(HSQUIRRELVM v)
     return 1;
 }
 
-static SQInteger _fl_fl_font(HSQUIRRELVM v)
+#define _DECL_FUNC(name,nparams,pmask,isStatic) {_SC(#name),_fl_##name,nparams,pmask,isStatic}
+static SQRegFunction fl_obj_funcs[]={
+	_DECL_FUNC(check,1,_SC("y"),SQTrue),
+	_DECL_FUNC(run,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_alt,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_button,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_button1,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_button2,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_button3,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_buttons,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_command,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_ctrl,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_dx,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_dy,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_length,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_shift,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_x,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_x_root,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_y,1,_SC("y"),SQTrue),
+	_DECL_FUNC(event_y_root,1,_SC("y"),SQTrue),
+	_DECL_FUNC(x,1,_SC("y"),SQTrue),
+	_DECL_FUNC(y,1,_SC("y"),SQTrue),
+	_DECL_FUNC(h,1,_SC("y"),SQTrue),
+	_DECL_FUNC(w,1,_SC("y"),SQTrue),
+	_DECL_FUNC(ready,1,_SC("y"),SQTrue),
+	_DECL_FUNC(screen_count,1,_SC("y"),SQTrue),
+
+	_DECL_FUNC(set_fonts,-1,_SC("ys"),SQTrue),
+	_DECL_FUNC(set_font,3,_SC("yi s|i"),SQTrue),
+	_DECL_FUNC(get_font,2,_SC("yi"),SQTrue),
+	_DECL_FUNC(get_font_name, 2,_SC("yi"),SQTrue),
+	_DECL_FUNC(scheme,-1,_SC("ys"),SQTrue),
+	_DECL_FUNC(visual,2,_SC("yi"),SQTrue),
+	_DECL_FUNC(option,-2,_SC("yib"),SQTrue),
+
+	_DECL_FUNC(event_key,-1,_SC("yi"),SQTrue),
+	_DECL_FUNC(event_state,-1,_SC("yi"),SQTrue),
+	_DECL_FUNC(event_is_click,-1,_SC("yi"),SQTrue),
+	_DECL_FUNC(event_clicks,-1,_SC("yi"),SQTrue),
+	_DECL_FUNC(scrollbar_size,-1,_SC("yi"),SQTrue),
+	_DECL_FUNC(visible_focus,-1,_SC("yi"),SQTrue),
+
+	_DECL_FUNC(do_widget_deletion,1,_SC("y"),SQTrue),
+	_DECL_FUNC(delete_widget,2,_SC("yx"),SQTrue),
+	_DECL_FUNC(add_timeout,-3,_SC("ync."),SQTrue),
+	_DECL_FUNC(add_idle,-2,_SC("yc."),SQTrue),
+	_DECL_FUNC(add_focus_changing_handler,2,_SC("yc"),SQTrue),
+	{0,0}
+};
+#undef _DECL_FUNC
+
+
+static SQInteger _fl_globals_fl_font(HSQUIRRELVM v)
 {
-    SQ_FUNC_VARS_NO_TOP(v);
-    SQ_GET_INTEGER(v, 2, font);
-    SQ_GET_INTEGER(v, 3, font_size);
-    fl_font(font, font_size);
-    return 0;
+    SQ_FUNC_VARS(v);
+    if(_top_ > 1){
+        SQ_GET_INTEGER(v, 2, font);
+        SQ_GET_INTEGER(v, 3, font_size);
+        fl_font(font, font_size);
+        return 0;
+    }
+    sq_pushinteger(v, fl_font());
+    return 1;
+}
+
+static SQInteger _fl_globals_fl_size(HSQUIRRELVM v)
+{
+    sq_pushinteger(v, fl_size());
+    return 1;
 }
 
-static SQInteger _fl_fl_height(HSQUIRRELVM v)
+static SQInteger _fl_globals_fl_height(HSQUIRRELVM v)
 {
     SQ_FUNC_VARS(v);
     if(_top_ > 1){
@@ -2713,7 +2777,7 @@ static SQInteger _fl_fl_height(HSQUIRRELVM v)
     return 1;
 }
 
-static SQInteger _fl_fl_width(HSQUIRRELVM v)
+static SQInteger _fl_globals_fl_width(HSQUIRRELVM v)
 {
     SQ_FUNC_VARS(v);
     SQ_GET_STRING(v, 2, str);
@@ -2722,14 +2786,14 @@ static SQInteger _fl_fl_width(HSQUIRRELVM v)
     return 1;
 }
 
-static SQInteger _fl_fl_descent(HSQUIRRELVM v)
+static SQInteger _fl_globals_fl_descent(HSQUIRRELVM v)
 {
     sq_pushinteger(v, fl_descent());
     return 1;
 }
 
 //void fl_cursor(Fl_Cursor, Fl_Color fg=FL_BLACK, Fl_Color bg=FL_WHITE);
-static SQInteger _fl_fl_cursor(HSQUIRRELVM v)
+static SQInteger _fl_globals_fl_cursor(HSQUIRRELVM v)
 {
     SQ_FUNC_VARS(v);
     SQ_GET_INTEGER(v, 2, cursor);
@@ -2737,9 +2801,186 @@ static SQInteger _fl_fl_cursor(HSQUIRRELVM v)
     SQ_OPT_INTEGER(v, 4, bg, FL_WHITE);
     fl_cursor((Fl_Cursor)cursor, fg, bg);
     return 0;
+}
+
+//void	fl_color(Fl_Color c)
+static SQInteger _fl_globals_fl_color(HSQUIRRELVM v)
+{
+    SQ_FUNC_VARS(v);
+    if(_top_ > 1){
+        SQ_GET_INTEGER(v, 2, color);
+        fl_color(color);
+        return 0;
+    }
+    sq_pushinteger(v, fl_color());
+    return 1;
+}
+
+//void fl_draw(int angle,const char* str, int n, int x, int y)
+static SQInteger _fl_globals_fl_draw(HSQUIRRELVM v)
+{
+    SQ_FUNC_VARS(v);
+    if(sq_gettype(v, 2) == OT_INTEGER){
+        //with angle rotation
+        SQ_GET_INTEGER(v, 2, angle);
+        SQ_GET_STRING(v, 3, str);
+        if(_top_ > 5){
+            SQ_GET_INTEGER(v, 4, n);
+            SQ_GET_INTEGER(v, 5, x);
+            SQ_GET_INTEGER(v, 6, y);
+            fl_draw(angle, str, n, x, y);
+        }
+        else
+        {
+            SQ_GET_INTEGER(v, 4, x);
+            SQ_GET_INTEGER(v, 5, y);
+            fl_draw(angle, str, str_size, x, y);
+        }
+    }
+    else
+    {
+        //string
+        SQ_GET_STRING(v, 2, str);
+        if(_top_ > 4){
+            SQ_GET_INTEGER(v, 3, n);
+            SQ_GET_INTEGER(v, 4, x);
+            SQ_GET_INTEGER(v, 5, y);
+            fl_draw(str, n, x, y);
+        }
+        else
+        {
+            SQ_GET_INTEGER(v, 3, x);
+            SQ_GET_INTEGER(v, 4, y);
+            fl_draw(str, str_size, x, y);
+        }
+    }
+    return 0;
+}
+
+//inline void fl_rect(int x, int y, int w, int h, Fl_Color c)
+static SQInteger _fl_globals_fl_rect(HSQUIRRELVM v)
+{
+    SQ_FUNC_VARS(v);
+    SQ_GET_INTEGER(v, 2, ix);
+    SQ_GET_INTEGER(v, 3, iy);
+    SQ_GET_INTEGER(v, 4, iw);
+    SQ_GET_INTEGER(v, 5, ih);
+    if(_top_ > 5){
+        SQ_GET_INTEGER(v, 5, icolor);
+        fl_rect(ix, iy, iw, ih, icolor);
+    }
+    else fl_rect(ix, iy, iw, ih);
+    return 0;
 }
 
-static SQInteger _fl_fl_preferences(HSQUIRRELVM v)
+//inline void fl_rectf(int x, int y, int w, int h, Fl_Color c)
+static SQInteger _fl_globals_fl_rectf(HSQUIRRELVM v)
+{
+    SQ_FUNC_VARS(v);
+    SQ_GET_INTEGER(v, 2, ix);
+    SQ_GET_INTEGER(v, 3, iy);
+    SQ_GET_INTEGER(v, 4, iw);
+    SQ_GET_INTEGER(v, 5, ih);
+    if(_top_ > 5){
+        SQ_GET_INTEGER(v, 5, icolor);
+        fl_rectf(ix, iy, iw, ih, icolor);
+    }
+    else fl_rectf(ix, iy, iw, ih);
+    return 0;
+}
+
+//void fl_line(int x, int y, int x1, int y1, int x2, int y2)
+static SQInteger _fl_globals_fl_line(HSQUIRRELVM v)
+{
+    SQ_FUNC_VARS(v);
+    SQ_GET_INTEGER(v, 2, x);
+    SQ_GET_INTEGER(v, 3, y);
+    SQ_GET_INTEGER(v, 4, x1);
+    SQ_GET_INTEGER(v, 5, y1);
+    if(_top_ > 5){
+        SQ_GET_INTEGER(v, 6, x2);
+        SQ_GET_INTEGER(v, 7, y2);
+        fl_line(x, y, x1, y1, x2, y2);
+    }
+    else fl_line(x, y, x1, y1);
+    return 0;
+}
+
+//void fl_line_style(int style, int width=0, char* dashes=0)
+static SQInteger _fl_globals_fl_line_style(HSQUIRRELVM v)
+{
+    SQ_FUNC_VARS(v);
+    SQ_GET_INTEGER(v, 2, style);
+    SQ_OPT_INTEGER(v, 3, width, 0);
+    if(sq_gettype(v, 4) == OT_STRING){
+        SQ_GET_STRING(v, 4, dashes);
+        fl_line_style(style, width, (char*)dashes);
+    }
+    else fl_line_style(style, width);
+    return 0;
+}
+
+//void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3)
+static SQInteger _fl_globals_fl_loop(HSQUIRRELVM v)
+{
+    SQ_FUNC_VARS(v);
+    SQ_GET_INTEGER(v, 2, x);
+    SQ_GET_INTEGER(v, 3, y);
+    SQ_GET_INTEGER(v, 4, x1);
+    SQ_GET_INTEGER(v, 5, y1);
+    SQ_GET_INTEGER(v, 6, x2);
+    SQ_GET_INTEGER(v, 7, y2);
+    if(_top_ > 7){
+        SQ_GET_INTEGER(v, 8, x3);
+        SQ_GET_INTEGER(v, 9, y3);
+        fl_loop(x, y, x1, y1, x2, y2, x3, y3);
+    }
+    else fl_loop(x, y, x1, y1, x2, y2);
+    return 0;
+}
+
+#define SQ_CHECK_TYPE(v, idx, tp) if(sq_gettype(v, idx) != OT_##tp) return sq_throwerror(v, _SC( #tp " expected for parameter (%d)"), idx-1);
+#define SQ_CHECK_ARRAY(v, idx) SQ_CHECK_TYPE(v, idx, ARRAY)
+#define SQ_CHECK_TABLE(v, idx) SQ_CHECK_TYPE(v, idx, TABLE)
+
+//void fl_measure(const char* str, int& x, int& y, int draw_symbols = 1);
+static SQInteger _fl_globals_fl_measure(HSQUIRRELVM v)
+{
+    SQ_FUNC_VARS(v);
+    SQ_GET_STRING(v, 2, str);
+    SQ_CHECK_TABLE(v, 3);
+    SQ_OPT_BOOL(v, 4, draw_symbols, true);
+    int iw, ih;
+    fl_measure(str, iw, ih, draw_symbols);
+    sq_pushstring(v, _SC("width"), -1);
+    sq_pushinteger(v, iw);
+    sq_rawset(v, 3);
+    sq_pushstring(v, _SC("height"), -1);
+    sq_pushinteger(v, ih);
+    sq_rawset(v, 3);
+    return 0;
+}
+
+//void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3)
+static SQInteger _fl_globals_fl_polygon(HSQUIRRELVM v)
+{
+    SQ_FUNC_VARS(v);
+    SQ_GET_INTEGER(v, 2, x);
+    SQ_GET_INTEGER(v, 3, y);
+    SQ_GET_INTEGER(v, 4, x1);
+    SQ_GET_INTEGER(v, 5, y1);
+    SQ_GET_INTEGER(v, 6, x2);
+    SQ_GET_INTEGER(v, 7, y2);
+    if(_top_ > 7){
+        SQ_GET_INTEGER(v, 8, x3);
+        SQ_GET_INTEGER(v, 9, y3);
+        fl_polygon(x, y, x1, y1, x2, y2, x3, y3);
+    }
+    else fl_polygon(x, y, x1, y1, x2, y2);
+    return 0;
+}
+
+static SQInteger _fl_globals_fl_preferences(HSQUIRRELVM v)
 {
     SQ_FUNC_VARS(v);
     SQ_GET_INTEGER(v, 2, ptype);
@@ -2749,63 +2990,25 @@ static SQInteger _fl_fl_preferences(HSQUIRRELVM v)
     _appPreferences = new Fl_Preferences( (Fl_Preferences::Root)ptype, vendor, application);
     return 0;
 }
-
-#define _DECL_FUNC(name,nparams,pmask,isStatic) {_SC(#name),_fl_##name,nparams,pmask,isStatic}
-static SQRegFunction fl_obj_funcs[]={
-	_DECL_FUNC(check,1,_SC("y"),SQFalse),
-	_DECL_FUNC(run,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_alt,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_button,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_button1,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_button2,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_button3,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_buttons,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_command,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_ctrl,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_dx,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_dy,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_length,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_shift,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_x,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_x_root,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_y,1,_SC("y"),SQFalse),
-	_DECL_FUNC(event_y_root,1,_SC("y"),SQFalse),
-	_DECL_FUNC(x,1,_SC("y"),SQFalse),
-	_DECL_FUNC(y,1,_SC("y"),SQFalse),
-	_DECL_FUNC(h,1,_SC("y"),SQFalse),
-	_DECL_FUNC(w,1,_SC("y"),SQFalse),
-	_DECL_FUNC(ready,1,_SC("y"),SQFalse),
-	_DECL_FUNC(screen_count,1,_SC("y"),SQFalse),
-
-	_DECL_FUNC(set_fonts,-1,_SC("ys"),SQFalse),
-	_DECL_FUNC(set_font,3,_SC("yi s|i"),SQFalse),
-	_DECL_FUNC(get_font,2,_SC("yi"),SQFalse),
-	_DECL_FUNC(get_font_name, 2,_SC("yi"),SQFalse),
-	_DECL_FUNC(scheme,-1,_SC("ys"),SQFalse),
-	_DECL_FUNC(visual,2,_SC("yi"),SQFalse),
-	_DECL_FUNC(option,-2,_SC("yib"),SQFalse),
-
-	_DECL_FUNC(event_key,-1,_SC("yi"),SQFalse),
-	_DECL_FUNC(event_state,-1,_SC("yi"),SQFalse),
-	_DECL_FUNC(event_is_click,-1,_SC("yi"),SQFalse),
-	_DECL_FUNC(event_clicks,-1,_SC("yi"),SQFalse),
-	_DECL_FUNC(scrollbar_size,-1,_SC("yi"),SQFalse),
-	_DECL_FUNC(visible_focus,-1,_SC("yi"),SQFalse),
-
-	_DECL_FUNC(do_widget_deletion,1,_SC("y"),SQFalse),
-	_DECL_FUNC(delete_widget,2,_SC("yx"),SQFalse),
-	_DECL_FUNC(add_timeout,-3,_SC("ync."),SQFalse),
-	_DECL_FUNC(add_idle,-2,_SC("yc."),SQFalse),
-	_DECL_FUNC(add_focus_changing_handler,2,_SC("yc"),SQFalse),
-
-	//globals made static on Fl
-	_DECL_FUNC(fl_cursor, -2,_SC("yiii"),SQFalse),
-	_DECL_FUNC(fl_font,3,_SC("yii"),SQFalse),
-	_DECL_FUNC(fl_width,-2,_SC("ysi"),SQFalse),
-	_DECL_FUNC(fl_height,-1,_SC("yii"),SQFalse),
-	_DECL_FUNC(fl_descent,1,_SC("y"),SQFalse),
-	_DECL_FUNC(fl_preferences,4,_SC("yiss"),SQFalse),
+
+#define _DECL_FUNC(name,nparams,pmask,isStatic) {_SC(#name),_fl_globals_##name,nparams,pmask,isStatic}
+static SQRegFunction fl_globals_funcs[]={
+	_DECL_FUNC(fl_cursor, -2,_SC(".iii"),SQTrue),
+	_DECL_FUNC(fl_color,-1,_SC(".i"),SQTrue),
+	_DECL_FUNC(fl_draw,-4,_SC(". n|s n|s nnn"),SQTrue),
+	_DECL_FUNC(fl_font,-1,_SC(".ii"),SQTrue),
+	_DECL_FUNC(fl_size,1,_SC("."),SQTrue),
+	_DECL_FUNC(fl_height,-1,_SC(".ii"),SQTrue),
+	_DECL_FUNC(fl_width,-2,_SC(".si"),SQTrue),
+	_DECL_FUNC(fl_descent,1,_SC("."),SQTrue),
+	_DECL_FUNC(fl_line,-5,_SC(".nnnnnn"),SQTrue),
+	_DECL_FUNC(fl_line_style,-2,_SC(".ii s|o"),SQTrue),
+	_DECL_FUNC(fl_loop,-7,_SC(".nnnnnnnn"),SQTrue),
+	_DECL_FUNC(fl_measure,-3,_SC(".stb"),SQTrue),
+	_DECL_FUNC(fl_polygon,-7,_SC(".nnnnnnnn"),SQTrue),
+	_DECL_FUNC(fl_rect,-5,_SC(".nnnn"),SQTrue),
+	_DECL_FUNC(fl_rectf,-5,_SC(".nnnn"),SQTrue),
+	_DECL_FUNC(fl_preferences,4,_SC(".iss"),SQTrue),
 
 	{0,0}
 };
@@ -2969,6 +3172,19 @@ static const struct {
 	INT_CONST(FL_WHITE)
 	INT_CONST(FL_YELLOW)
 
+	/*line style*/
+    INT_CONST(FL_SOLID)
+    INT_CONST(FL_DASH)
+    INT_CONST(FL_DOT)
+    INT_CONST(FL_DASHDOT)
+    INT_CONST(FL_DASHDOTDOT)
+    INT_CONST(FL_CAP_FLAT)
+    INT_CONST(FL_CAP_ROUND)
+    INT_CONST(FL_CAP_SQUARE)
+    INT_CONST(FL_JOIN_MITER)
+    INT_CONST(FL_JOIN_ROUND)
+    INT_CONST(FL_JOIN_BEVEL)
+
     /*keyboard*/
     INT_CONST(FL_Key_Space)
     INT_CONST(FL_Key_Plus)
@@ -3093,7 +3309,10 @@ SQRESULT sqext_register_fltklib(HSQUIRRELVM v)
 {
     Fl::user_data = v;
 	//sq_pushstring(v,_SC("fltk"),-1);
-	//sq_newtable(v);
+	//sq_newtable(v);
+
+    //global fl_* functions
+	sq_insert_reg_funcs(v, fl_globals_funcs);
 
 #define INT_CONST_PREFIX_VALUE(prefix, key, value) \
     sq_pushstring(v, _SC(#key), -1);\

+ 364 - 0
ourbiz/fl-bar-chart.nut

@@ -0,0 +1,364 @@
+class Fl_Bar_Chart extends Fl_Box {
+	_bars = null; //{label, value, color}
+	_bar_depth = null;
+	_bar_update_count = null;
+	_bar_num_format_decimals = null;
+	_bar_color = null;
+	
+	constructor(X, Y, W, H, L = null) {
+		base.constructor(X,Y,W,H,L);
+		color(FL_WHITE);
+		align(FL_ALIGN_RIGHT);
+		labeltype(FL_NO_LABEL);
+		_bars = [];
+		_bar_color = FL_BLUE;
+		_bar_depth = 8;
+		_bar_update_count = 0;
+		_bar_num_format_decimals = 0;
+	}
+
+	function bar_count(){return _bars.size();}
+
+	function bar_add(bheader, bvalue, bcolor=FL_BLUE) {
+		_bars.push( [bheader, bvalue, bcolor]);
+	}
+
+	function bar_get(idx) { return _bars[idx];}
+
+	function bar_depth(depth=null){
+		if(depth==null) return _depth;
+		if(_bar_depth == depth) return;
+		_bar_depth = depth;
+		update_bar_chart();
+	}
+
+	function bar_num_format_decimals(decimals=null) {
+		if(decimals==null) return _bar_num_format_decimals;
+		if(_bar_num_format_decimals == decimals) return;
+		_bar_num_format_decimals = decimals;
+		update_bar_chart();
+	}
+
+	function bar_begin_update() {return ++_bar_update_count;}
+
+	function bar_end_update() {
+		if(_bar_update_count == 0) throw("update count underflow");
+		if(--_bar_update_count == 0) update_bar_chart();
+	}
+
+	function update_bar_chart() {
+		if(_bar_update_count == 0) redraw();
+	}
+
+	function bar_clear(){
+		_bars.clear();
+		update_bar_chart();
+	}
+
+
+	function normalize_scale_units(oldScale) {
+		local result = oldScale;
+		if(result < 2) result = 2;
+		else if(result <= 5) result = 5;
+		else if(result <= 10) result = 10;
+		else
+		{
+			local str = result.tostring();
+			local t = str[0] - '0';
+			do
+			{
+				result = result / 10;
+				t *= 10;
+			}
+			while(result >= 10);
+			return t;
+		}
+		return result;
+	}
+
+	function draw_mypolygon(x1, y1, x2, y2, x3, y3, x4, y4, line_color, fill_color) {
+		fl_color(fill_color);
+		fl_polygon(x1, y1, x2, y2, x3, y3, x4, y4);
+
+		fl_color(line_color);
+		fl_line_style(FL_SOLID, 1, NULL);
+		fl_loop(x1, y1, x2, y2, x3, y3, x4, y4);
+	}
+
+	function  draw_mybar(pbx,  pby, pw, ph, pdepth, line_color, fill_color) {
+		local lbx2 = pbx+pw;
+		local lbx3 = lbx2+pdepth;
+		local lby2 = pby+ph;
+		local lby3 = pby-pdepth;
+		// face rect
+		draw_mypolygon(
+			pbx, pby,
+			lbx2, pby,
+			lbx2, lby2,
+			pbx, lby2,
+			line_color,
+			fill_color);
+		// top polygon
+		draw_mypolygon(
+			pbx, pby,
+			lbx2, pby,
+			lbx3, lby3,
+			pbx+pdepth, lby3,
+			line_color,
+			fill_color);
+		// side polygon
+		draw_mypolygon(
+			lbx2, pby,
+			lbx3, lby3,
+			lbx3, lby2-pdepth,
+			lbx2, lby2,
+			line_color,
+			fill_color);
+	}
+
+	function draw() {
+		//set font size, color and clear
+		fl_font(labelfont(), labelsize());
+		fl_color(color());
+		fl_rectf(x(), y(), w(), h());
+
+		local  measure = {};
+		fl_measure("W", measure, false);
+		local  char_width = measure.width, char_height = measure.height;
+		
+
+		local inner_padding = char_height;
+		local box_x = x();
+		local box_y = y() + char_height;
+
+		local str;
+		local nf_buf;
+
+		local bars_box_x, bars_box_y, bars_box_width, bars_box_height;
+
+		local box_label_width = inner_padding;
+		local value_max = 0.0;
+
+		foreach(bar in _bars)
+		{
+			local max_value_str_width = fl_width(bar[0] /*label*/, bar[0].size());
+			if(max_value_str_width > box_label_width) box_label_width = max_value_str_width;
+			if(bar[1] /*value*/  > value_max) value_max = bar[1];
+		}
+
+		box_label_width += inner_padding *2;
+		bars_box_x = box_x + box_label_width;
+		bars_box_y = box_y + inner_padding;
+		bars_box_height = h() - inner_padding - 3 * char_height;
+		bars_box_width = w() - box_label_width - 3 * _bar_depth - inner_padding;
+
+		draw_mypolygon(
+		    bars_box_x, bars_box_y+_bar_depth,
+		    bars_box_x, bars_box_y+_bar_depth+bars_box_height,
+		    bars_box_x+_bar_depth, bars_box_y+bars_box_height,
+		    bars_box_x+_bar_depth, bars_box_y,
+		    FL_BLACK,
+		    FL_YELLOW
+		);
+		draw_mypolygon(
+		    bars_box_x, bars_box_y+_bar_depth+bars_box_height,
+		    bars_box_x+bars_box_width+_bar_depth, bars_box_y+_bar_depth+bars_box_height,
+		    bars_box_x+bars_box_width+_bar_depth*2, bars_box_y+bars_box_height,
+		    bars_box_x+_bar_depth, bars_box_y+bars_box_height,
+		    FL_BLACK,
+		    FL_WHITE
+		);
+
+		fl_color(FL_BLACK);
+		fl_line_style(FL_SOLID, 1, NULL);
+		fl_rect(bars_box_x+_bar_depth, bars_box_y, bars_box_width+_bar_depth, bars_box_height+1);
+
+		fl_line_style(FL_SOLID, 3, NULL);
+		fl_line(bars_box_x, bars_box_y+_bar_depth, bars_box_x, bars_box_y+_bar_depth+bars_box_height, bars_box_x+bars_box_width+_bar_depth, bars_box_y+_bar_depth+bars_box_height);
+		local my_label = label();
+		if(my_label) fl_draw(my_label, my_label.len(), x() + (w() - fl_width(my_label))/2, box_y);
+
+		str = value_max.tostring();
+		fl_measure(str, measure, false);
+		local max_value_str_width = measure.width, max_value_str_height = measure.height;
+
+		local pixelPerUnit, nScaleLines, scaleUnits, itmp;
+		if(value_max == 0) {
+		    pixelPerUnit = 1;
+		    nScaleLines = 1;
+		}
+		else
+		{
+		    itmp = bars_box_width-max_value_str_width-_bar_depth;
+		    pixelPerUnit = itmp / value_max;
+		    nScaleLines = math.ceil(itmp / (2*max_value_str_width));
+		}
+
+		if(nScaleLines == 0) scaleUnits = value_max +1;
+		else
+		{
+		    scaleUnits = math.floor(value_max / nScaleLines) +1;
+		}
+		scaleUnits = normalize_scale_units(scaleUnits);
+		if(scaleUnits == 0)	nScaleLines = 1;
+		else nScaleLines = (value_max / scaleUnits)+1;
+
+		fl_color(FL_DARK3);
+		fl_line_style(FL_DASH, 1, "\0x05\0x05");
+
+		local half_max_value_str_width = math.floor(max_value_str_width / 2);
+		local bars_box_bottom = bars_box_y+_bar_depth+bars_box_height+2;
+		local str_zero = "0";
+
+		local function draw_scaleLine(dk,s) {
+			local lx, ly, lx2, ly2;
+			lx = bars_box_x + dk + _bar_depth;
+			ly = bars_box_y + bars_box_height;
+			lx2 = bars_box_x + dk;
+			ly2 = bars_box_y + _bar_depth+bars_box_height;
+			fl_line(lx, bars_box_y, lx, ly, lx2, ly2);
+			fl_line(lx2, ly2, lx2, ly2 + 2);
+			local oldcolor = fl_color();
+			fl_color(FL_BLACK);
+			fl_draw(s, s.len(), bars_box_x + dk - half_max_value_str_width, bars_box_bottom+char_height);
+			fl_color(oldcolor);
+		}
+
+		if(value_max == 0)
+		{
+		    local ik = math.floor(bars_box_width / 2);
+		    draw_scaleLine(ik,str_zero);
+		}
+		else
+		{
+		    fl_color(FL_BLACK);
+		    fl_draw(str_zero, str_zero.len(), bars_box_x, bars_box_bottom+char_height);
+		    fl_color(FL_DARK3);
+		}
+
+		local _num_buf;
+
+		for(local ik=0; ik < nScaleLines; ik++)
+		{
+		    local xs = math.floor(scaleUnits*pixelPerUnit*ik);
+		    _num_buf = math.number_format(ik*scaleUnits, _bar_num_format_decimals);
+		    draw_scaleLine(xs, _num_buf);
+		}
+
+		local bar_height, bar_y;
+		if(_bars.size() == 0) bar_height = 0;
+		else bar_height = ((bars_box_height- _bar_depth) / ((2.0*_bars.size()+1)));
+
+		bars_box_bottom -= 2*bar_height + _bar_depth;
+		local ikl = 0;
+		foreach(bar in _bars) {
+			bar_y = bars_box_bottom - (2*ikl*bar_height) ;
+			local value = bar[1]; //bar value
+			local bar_width = math.floor(value*pixelPerUnit);
+
+			draw_mybar(bars_box_x, bar_y, bar_width, bar_height, _bar_depth, FL_DARK3, bar[2] /*color*/);
+
+			_num_buf = math.number_format(value, _bar_num_format_decimals);
+
+			local rcenter = math.floor(bar_y+(bar_height-_bar_depth) / 2);
+
+			fl_color(FL_DARK3);
+			fl_line(bars_box_x+bar_width+_bar_depth/2,rcenter, bars_box_x+bar_width+_bar_depth*2, rcenter);
+
+			fl_measure(_num_buf, measure, false);
+			local str_width = measure.width, str_height = measure.height;
+
+			local rc_x = bars_box_x+bar_width+_bar_depth*2;
+			local rc_w = str_width+_bar_depth;
+			local rc_y = rcenter - str_height/2;
+			local rc_h = str_height * 1.1;
+
+			fl_color(FL_YELLOW);
+			fl_line_style(FL_SOLID, 2);
+			fl_rectf(rc_x, rc_y, rc_w, rc_h);
+			fl_color(FL_BLACK);
+			fl_draw(_num_buf, _num_buf.len(), rc_x+_bar_depth/2, rcenter + str_height/3);
+
+			str = bar[0]; //bar header
+			fl_measure(str, measure, false);
+			str_width = measure.width;
+			str_height = measure.height;
+
+			local str_x, str_y;
+			fl_color(FL_BLACK);
+			switch(align()){
+			    case FL_ALIGN_CENTER:
+			    {
+				str_x = box_x+(box_label_width/2) - (str_width / 2);
+				str_y = rcenter + str_height/3;
+			    }
+			    break;
+			    case FL_ALIGN_RIGHT:
+			    {
+				str_x = bars_box_x-str_width-inner_padding;
+				str_y = rcenter + str_height/3;
+			    }
+			    break;
+			    default:
+			    {
+				str_x = box_x + inner_padding;
+				str_y = rcenter + str_height/3;
+			    }
+			}
+
+			fl_draw(str, str.len(), str_x, str_y);
+			++ikl;
+		}
+		fl_line_style(0);
+	}
+};
+
+
+math.number_format_set_thousand_sep(".");
+math.number_format_set_dec_point(",");
+
+math.mynumber_format <- function (value, decp=2){
+	value = value.tofloat();
+	local fvalue, neg, intp;
+	fvalue = format("%.0" + decp + "f", value);
+	if (decp > 0){
+		if (value < 0) intp = fvalue.slice(1, -(decp+1));
+		else intp = fvalue.slice(0, -(decp+1));
+	}
+	else intp = fvalue;
+
+	local thousands_rep = "%1" + math.thousand_separator();
+	local thousandsp = intp.reverse().gsub("(%d%d%d)",thousands_rep);
+	if ((intp.len() % 3) == 0) thousandsp = thousandsp.slice(0,-1);
+	if (decp > 0) fvalue = thousandsp.reverse() + math.decimal_separator() + fvalue.slice(-decp);
+	else fvalue = thousandsp.reverse();
+	if (value < 0) return "-" + fvalue;
+	else return fvalue;
+}
+
+function blank_when_zero(snum) {return snum.tofloat();}
+
+local win = Fl_Double_Window(10,50, 800, 560, "My Barchart");
+local mychart = Fl_Bar_Chart(20,20, 760, 520, "My Barchart");
+win->end();
+
+mychart->labelsize(18);
+
+local function rand_value(){return math.rand() % 300;}
+
+mychart.bar_add("January", rand_value());
+mychart->bar_add("Febrary", rand_value());
+mychart->bar_add("March", rand_value());
+mychart->bar_add("April", rand_value());
+mychart->bar_add("May", rand_value());
+mychart->bar_add("June", rand_value(), FL_RED);
+mychart->bar_add("July", rand_value(), FL_GREEN);
+mychart->bar_add("August", rand_value());
+mychart->bar_add("September", rand_value());
+mychart->bar_add("November", rand_value());
+mychart->bar_add("Dicember", rand_value());
+
+win->resizable(mychart);
+win->show_main();
+Fl.run();
+

+ 6 - 6
ourbiz/ourbiz-fltk.nut

@@ -460,10 +460,10 @@ class Fl_Data_Table extends Flv_Data_Table {
 		//char_width = self:labelsize() --fltk.fl_width('w')
 		//it seems that if not set the text font on fluid
 		//we get segfault here
-		Fl.fl_font(textfont(), textsize());
+		fl_font(textfont(), textsize());
 		local gs = global_style();
-		gs.height(Fl.fl_height()+Fl.fl_descent());
-		char_width = Fl.fl_width("w");
+		gs.height(fl_height()+fl_descent());
+		char_width = fl_width("w");
 		draw_offset(char_width/3);
 		//print(grid_width, char_width)
 
@@ -540,11 +540,11 @@ class MyListSearchWindow extends ListSearch {
 	function get_search_data(data){}
 	function fill_grid(){
 		//SafeCursorWait cursor_wait;
-		Fl.fl_cursor(FL_CURSOR_WAIT);
+		fl_cursor(FL_CURSOR_WAIT);
 		grid->clear_data_rows();
 		get_search_data(grid->_data);
 		grid->recalc_data();
-		Fl.fl_cursor(FL_CURSOR_DEFAULT);
+		fl_cursor(FL_CURSOR_DEFAULT);
 	}
 	function cb_btnSearch(sender, udata){
 		local pr = sender.parent_root();
@@ -554,7 +554,7 @@ class MyListSearchWindow extends ListSearch {
 	function create_search_by0(name, Klass, pack){
 		local sb = Klass(0,0,25,20, _tr(name));
 		sb->labelsize(pack->labelsize());
-		sb->w(Fl.fl_width(sb.label()) + Fl.fl_width("W"));
+		sb->w(fl_width(sb.label()) + fl_width("W"));
 		pack->add(sb);
 		return sb;
 	}

+ 1 - 1
ourbiz/utils-fltk.nut

@@ -94,4 +94,4 @@ Fl.visual(FL_RGB);
 Fl.option(Fl.OPTION_ARROW_FOCUS, true);
 setAppFont("erdana");
 Fl.add_focus_changing_handler(fltk_focus_changing);
-Fl.fl_preferences(Fl.FL_PREFERENCES_USER, "dadbiz", "ourbiz");
+fl_preferences(Fl.FL_PREFERENCES_USER, "dadbiz", "ourbiz");