## textbutton-look.pkg
#
# View for text buttons.
# Compiled by:
#
src/lib/x-kit/widget/xkit-widget.sublib# This package gets used in:
#
#
src/lib/x-kit/widget/old/leaf/pushbuttons.pkg#
src/lib/x-kit/widget/old/leaf/toggleswitches.pkgstipulate
package g2d = geometry2d; # geometry2d is from
src/lib/std/2d/geometry2d.pkg #
package xc = xclient; # xclient is from
src/lib/x-kit/xclient/xclient.pkg #
package car = cartouche; # cartouche is from
src/lib/x-kit/draw/cartouche.pkg package d3 = three_d; # three_d is from
src/lib/x-kit/widget/old/lib/three-d.pkg package wg = widget; # widget is from
src/lib/x-kit/widget/old/basic/widget.pkg package wa = widget_attribute_old; # widget_attribute_old is from
src/lib/x-kit/widget/old/lib/widget-attribute-old.pkg package wt = widget_types; # widget_types is from
src/lib/x-kit/widget/old/basic/widget-types.pkgherein
package textbutton_look
: (weak) Button_Look # Button_Look is from
src/lib/x-kit/widget/old/leaf/button-look.api {
default_font_name = "8x13";
#
attributes
=
[ (wa::halign, wa::HALIGN, wa::HALIGN_VAL wt::HCENTER),
(wa::rounded, wa::BOOL, wa::BOOL_VAL FALSE),
(wa::width, wa::INT, wa::NO_VAL),
(wa::height, wa::INT, wa::NO_VAL),
(wa::border_thickness, wa::INT, wa::INT_VAL 2),
(wa::label, wa::STRING, wa::STRING_VAL ""),
(wa::font, wa::FONT, wa::STRING_VAL default_font_name),
(wa::color, wa::COLOR, wa::NO_VAL),
(wa::background, wa::COLOR, wa::STRING_VAL "white"),
(wa::foreground, wa::COLOR, wa::STRING_VAL "black")
];
Fontdata
=
{ font: xc::Font,
font_ascent: Int,
font_descent: Int
};
fun make_font font
=
{ (xc::font_high font)
->
{ ascent => font_ascent,
descent => font_descent
};
{ font, font_ascent, font_descent };
};
Labeldata
=
{ label: String,
lb: Int, # 'lb' is apparently 'left bound'.
rb: Int # 'rb' is apparently 'right bound'. width == lb - rb.
};
fun make_label (s, font)
=
{ ((xc::text_extents font s).overall_info)
->
xc::CHAR_INFO { left_bearing=>lb, right_bearing=>rb, ... };
{ label=>s, lb, rb };
};
Button_Look
=
BUTTON_LOOK
{
align: wt::Horizontal_Alignment,
rounded: Bool,
#
width: Null_Or( Int ),
height: Null_Or( Int ),
#
border_thickness: Int,
labeldata: Labeldata,
fontdata: Fontdata,
#
stipple: xc::Ro_Pixmap,
shades: wg::Shades,
#
forec: xc::Rgb,
color: xc::Rgb,
backc: xc::Rgb
};
fun make_button_look (root, view, args)
=
{ attributes = wg::find_attribute (wg::attributes (view, attributes, args));
#
font = wa::get_font (attributes wa::font);
backc = wa::get_color (attributes wa::background);
color = case (wa::get_color_opt (attributes wa::color))
#
THE c => c;
_ => backc;
esac;
BUTTON_LOOK
{
align => wa::get_halign (attributes wa::halign),
rounded => wa::get_bool (attributes wa::rounded),
width => wa::get_int_opt (attributes wa::width),
height => wa::get_int_opt (attributes wa::height),
border_thickness => wa::get_int (attributes wa::border_thickness),
labeldata => make_label (wa::get_string (attributes wa::label), font),
stipple => wg::ro_pixmap root "gray",
shades => wg::shades root color,
fontdata => make_font font,
forec => wa::get_color (attributes wa::foreground),
color,
backc
};
};
pad = 1;
rpad = 4;
fun configfn (BUTTON_LOOK v, window, size as { wide, high } )
=
drawf
where
d = xc::drawable_of_window window;
#
r = g2d::box::make (g2d::point::zero, size);
v -> { border_thickness, labeldata, fontdata, ... };
text_pen = xc::make_pen [xc::p::FOREGROUND (xc::rgb8_from_rgb v.forec) ];
inactive_text_pen
=
xc::clone_pen
( text_pen,
[ xc::p::FILL_STYLE_STIPPLED,
xc::p::STIPPLE v.stipple
]
);
v.shades -> { base, light, dark };
xoff = border_thickness + pad;
labeldata -> { lb, rb, label };
fontdata -> { font, font_ascent, font_descent };
col = case v.align
#
wt::HLEFT => xoff - lb;
wt::HRIGHT => wide - xoff - rb - 1;
wt::HCENTER => (wide - lb - rb) / 2;
esac;
row = (high + font_ascent - font_descent) / 2;
text_pt = { col, row };
border = d3::draw3drect d (r, border_thickness);
fun draw (text_pen, back_pen, top_pen, bot_pen)
=
{ xc::fill_box d back_pen r;
xc::draw_transparent_string d text_pen font (text_pt, label);
border { top=>top_pen, bottom=>bot_pen };
};
fun drawf { button_state => wt::ACTIVE TRUE , mousebutton_is_down => FALSE, has_mouse_focus } => draw ( text_pen, base, dark, light);
drawf { button_state => wt::ACTIVE FALSE, mousebutton_is_down => FALSE, ... } => draw ( text_pen, base, light, dark );
drawf { button_state => wt::ACTIVE TRUE , mousebutton_is_down => TRUE , ... } => draw ( text_pen, base, light, dark );
drawf { button_state => wt::ACTIVE FALSE, mousebutton_is_down => TRUE , ... } => draw ( text_pen, base, dark, light);
drawf { button_state => wt::INACTIVE TRUE , ... } => draw (inactive_text_pen, base, dark, light);
drawf { button_state => wt::INACTIVE FALSE, ... } => draw (inactive_text_pen, base, light, dark );
end;
end;
fun rconfigfn (BUTTON_LOOK v, window, size as { wide, high } ) # The "r" may be for "rounded" -- notice use of 'cartouche' and 'draw3dround_box'
=
drawf
where
d = xc::drawable_of_window window;
r = { col => 0,
row => 0,
wide => wide - 1,
high => high - 1
};
corner_radius = int::min (10, int::min (wide, high) / 6);
v -> { backc, color, border_thickness, labeldata, fontdata, ... };
text_pen = xc::make_pen [xc::p::FOREGROUND (xc::rgb8_from_rgb v.forec) ];
inactive_text_pen
=
xc::clone_pen
( text_pen,
[ xc::p::FILL_STYLE_STIPPLED,
xc::p::STIPPLE v.stipple
]
);
v.shades -> { base, light, dark };
labeldata -> { lb, rb, label };
fontdata -> { font_ascent, font_descent, font };
text_pt = { col=> (wide - lb - rb) / 2,
row=> (high + font_ascent - font_descent) / 2
};
fun draw (text_pen, back_pen, top_pen, bot_pen)
=
{ xc::clear_drawable d;
#
if (not (xc::same_rgb (backc, color)))
#
car::fill_cartouche d base { box=>r, corner_radius };
fi;
xc::draw_transparent_string d text_pen font (text_pt, label);
d3::draw3dround_box d
{ box=>r, c_wid=>corner_radius, c_ht=>corner_radius, width=>border_thickness }
{ top=>top_pen, bottom=>bot_pen };
};
fun drawf { button_state => wt::ACTIVE TRUE, mousebutton_is_down => FALSE, has_mouse_focus } => draw ( text_pen, base, dark, light);
drawf { button_state => wt::ACTIVE FALSE, mousebutton_is_down => FALSE, ... } => draw ( text_pen, base, light, dark);
drawf { button_state => wt::ACTIVE TRUE, mousebutton_is_down => TRUE, ... } => draw ( text_pen, base, light, dark);
drawf { button_state => wt::ACTIVE FALSE, mousebutton_is_down => TRUE, ... } => draw ( text_pen, base, dark, light);
drawf { button_state => wt::INACTIVE TRUE, ... } => draw (inactive_text_pen, base, dark, light);
drawf { button_state => wt::INACTIVE FALSE, ... } => draw (inactive_text_pen, base, light, dark);
end;
end;
fun bounds (BUTTON_LOOK v)
=
{ v -> { rounded, border_thickness, labeldata, fontdata, ... };
#
inset = border_thickness + (if rounded rpad; else pad;fi);
labeldata -> { lb, rb, ... };
fontdata -> { font_ascent, font_descent, ... };
lwid = rb - lb;
lht = font_ascent + font_descent;
col = case v.width
THE w => w;
NULL => lwid + 2*inset;
esac;
row = case v.height
THE h => h;
NULL => lht + 2*inset;
esac;
{ col_preference => wg::loose_preference col,
row_preference => wg::loose_preference row
};
};
fun make_button_drawfn (arg as (BUTTON_LOOK { rounded=>TRUE, ... }, window, size))
=>
rconfigfn arg;
make_button_drawfn arg
=>
configfn arg;
end;
fun window_args (BUTTON_LOOK { backc, ... } )
=
{ background => THE backc };
}; # package textbutton_look
end;