Здравствуйте, PM, Вы писали:
PM>Здравствуйте, c-smile, Вы писали:
CS>>Вот пример для Sciter. Портирование в HTMLayout — на совести вопрошающего.
Вот, портировал, вдруг кому еще пригодится. Спасибо c-smile, все оказалось не так страшно
#include "behavior_aux.h"
namespace htmlayout {
/** behavior:hexnumber, hexadecimal number edit.
* Behaves like number, size attribute defines width of value
*
* <input type="hex-number" size="4" step="1 minvalue="0" maxvalue="65535" />
*
**/
class hexnumber : public behavior
{
public:
hexnumber()
: behavior(HANDLE_MOUSE | HANDLE_KEY | HANDLE_BEHAVIOR_EVENT | HANDLE_METHOD_CALL, "hexnumber")
{
char const css[] = " input[type=\"hex-number\"] { style-set: \"hex-edit\"; }"
"@set hex-edit {"
" :root {"
" behavior:hexnumber;"
" font-rendering-mode:snap-pixel; font-family:monospace;"
" background-image:url(theme:edit-normal); background-repeat:stretch; "
" padding:system-border-width; width: 6em; height: min-intrinsic;"
" color:windowtext; cursor:text; white-space: nowrap; text-align:right;"
" flow:\"1 2\""
" \"1 3\"; }"
" :root:rtl {"
" flow:\"2 1\""
" \"3 1\"; }"
" :root > caption {"
" display:block; flow:text; behavior: edit; size:*; padding:2px; cursor:text;"
" white-space:pre; overflow-x:hidden-scroll; -filter:\"0~9A~Fa~f\";"
" text-selection: windowtext threedface; }"
" :root > caption:focus { text-selection: highlighttext highlight; }"
" :root:disabled { background-image:url(theme:edit-disabled); color:graytext; }"
" :root:invalid { color:red; }"
" :root > button { display:block; padding:0; behavior:clickable; cursor:default; height:0.5*; min-height:10dip; }"
" :root > button.minus { margin: 0 -2px -2px 0;"
" background-image:url(theme:v-spin-minus-normal); background-repeat:stretch; width:system-scrollbar-width; }"
" :root > button.minus:hover { transition:none; background-image:url(theme:v-spin-minus-hover); }"
" :root > button.minus:active { background-image:url(theme:v-spin-minus-pressed); }"
" :root > button.minus:disabled { background-image:url(theme:v-spin-minus-disabled); }"
" :root > button.plus { margin: -2px -2px -1 0;"
" background-image:url(theme:v-spin-plus-normal); background-repeat:stretch; width:system-scrollbar-width; }"
" :root > button.plus:hover { transition:none; background-image:url(theme:v-spin-plus-hover); }"
" :root > button.plus:active { background-image:url(theme:v-spin-plus-pressed); }"
" :root > button.plus:disabled { background-image:url(theme:v-spin-plus-disabled); }"
"}";
::HTMLayoutAppendMasterCSS((LPCBYTE)css, sizeof(css));
}
private:
// behavior implementation
virtual void attached(HELEMENT he)
{
dom::element self = he;
dom::element caption = dom::element::create("caption");
self.append(caption);
if ( step(self) )
{
dom::element inc = dom::element::create("button");
inc.set_attribute("class", L"plus");
self.append(inc);
dom::element dec = dom::element::create("button");
dec.set_attribute("class", L"minus");
self.append(dec);
}
int const val = self.get_attribute_int("value", -1);
if ( val >= 0 )
{
set_value(self, val);
}
}
virtual BOOL handle_event(HELEMENT he, BEHAVIOR_EVENT_PARAMS& params)
{
if ( params.cmd == BUTTON_CLICK )
{
if ( params.heTarget == inc(he) )
{
do_inc(he);
return true;
}
else if ( params.heTarget == dec(he) )
{
do_dec(he);
return true;
}
}
return false;
}
virtual BOOL handle_mouse(HELEMENT he, MOUSE_PARAMS& params)
{
if ( params.cmd == MOUSE_WHEEL )
{
int const wheel_delta = params.button_state;
if ( wheel_delta < 0 && dec(he) )
{
do_dec(he);
return true;
}
else if ( wheel_delta > 0 && inc(he) )
{
do_inc(he);
return true;
}
}
return false;
}
virtual BOOL handle_key(HELEMENT he, KEY_PARAMS& params)
{
if ( params.cmd == KEY_DOWN )
{
if ( params.key_code == VK_UP && inc(he) )
{
do_inc(he);
return true;
}
else if ( params.key_code == VK_DOWN && dec(he) )
{
do_dec(he);
return true;
}
}
return false;
}
virtual BOOL handle_method_call(HELEMENT he, METHOD_PARAMS& params)
{
if ( params.methodID == GET_VALUE )
{
static_cast<VALUE_PARAMS&>(params).val = get_value(he);
return true;
}
else if ( params.methodID == SET_VALUE )
{
set_value(he, static_cast<VALUE_PARAMS&>(params).val);
return true;
}
return false;
}
private:
static void set_value(dom::element self, json::value val)
{
dom::element caption = self.find_first("caption");
if ( caption )
{
if ( val.is_int() )
{
int const width = max(self.get_attribute_int("size", 1), 1);
std::vector<wchar_t> buf(width + std::numeric_limits<unsigned>::digits / 4 + 1);
swprintf(&buf[0], buf.size(), L"%.*X", width, val.get(0));
val = &buf[0];
}
caption.set_value(val);
}
}
static json::value get_value(dom::element self)
{
json::value result;
dom::element caption = self.find_first("caption");
if ( caption )
{
int val = 0;
json::string const str = caption.get_value().get(L"");
if ( swscanf(str.c_str(), L"%x", &val) == 1 )
{
val = max(min_value(self), min(val, max_value(self)));
result = val;
}
}
return result;
}
static int step(dom::element self)
{
return self.get_attribute_int("step", 0);
}
static int min_value(dom::element self)
{
return self.get_attribute_int("minvalue", 0);
}
static int max_value(dom::element self)
{
return self.get_attribute_int("maxvalue", 0xFFFF);
}
static dom::element inc(dom::element self)
{
return self.find_first("button[class='plus']");
}
static dom::element dec(dom::element self)
{
return self.find_first("button[class='minus']");
}
static void do_inc(dom::element self)
{
json::value val = get_value(self);
val = val.is_int()? min(val.get(0) + step(self), max_value(self)) : min_value(self);
set_value(self, val);
}
static void do_dec(dom::element self)
{
json::value val = get_value(self);
val = val.is_int()? max(val.get(0) - step(self), min_value(self)) : max_value(self);
set_value(self, val);
}
};
// instantiating and attaching it to the global list
hexnumber hexnumber_instance;
} // htmlayout namespace