Re[5]: Пример того как это делается
От: PM  
Дата: 30.10.12 05:49
Оценка: 56 (2)
Здравствуйте, 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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.