⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sgrlistboxcontrol.cpp

📁 一个基于BREW上的WEB service程序,通过扫描图书的条形码,登陆WEB站点,利用SOAP-RPC来查询图书信息.
💻 CPP
字号:
//
//      SGRListboxControl.cpp
//
//

#include "SGRListboxControl.hpp"

#define     ITEM_MARGIN             (4)
#define     ITEM_GREEN_COLOR        0xFF, 0xAA, 0xBB, 0x00
#define     ITEM_BLUE_COLOR         0xDD, 0xDD, 0xFF, 0x00
#define     DEFAULT_INTERVAL           100
#define     DEFAULT_FIRSTINTERVAL           500
#define     DEFAULT_SPEED              10

SGRListboxControl::SGRListboxControl(SFRResponderPtr responder, SFXRectangleConstRef rect) static_throws : SFRControl(responder, rect, SFXMargin(2, 2, 2, 2), SFMRESPONDERFILTER(LISTBOXCONTROL, BEHAVIOR_LISTBOXCONTROL), ATTRIBUTE_LISTBOXCONTROL)
{
    SFXRectangle temp;

    if (static_try()) {
        static_throw(RegisterHandler(SFEVT_KEY, HANDLER_AFTER, HANDLER_FUNCTION(OnKey)));
        if (static_try()) {
            static_throw(RegisterHandler(SREVT_RESPONDER_RENDER, SRP16_RENDER_BASE, HANDLER_BEFORE, HANDLER_FUNCTION(OnBase)));
            if (static_try()) {
                static_throw(RegisterHandler(SREVT_RESPONDER_RENDER, SRP16_RENDER_CONTENT, HANDLER_BEFORE, HANDLER_FUNCTION(OnContent)));
                if (static_try()) {
                    static_throw(RegisterHandler(SFEVT_APP_RESUME, HANDLER_BEFORE, HANDLER_FUNCTION(OnResume)));
                    if (static_try()) {
                        static_throw(RegisterHandler(SFEVT_APP_SUSPEND, HANDLER_AFTER, HANDLER_FUNCTION(OnSuspend)));
                        if (static_try()) {
                            temp = GetBaseBound();
                            temp.Deflate(2, 2);
                            _limit = 0;
                            _select = 0;
                            _offset = 0;
                            _speed = DEFAULT_SPEED;
                            _height = SFXGraphics::GetFontHeight(AEE_FONT_NORMAL) + ITEM_MARGIN;
                            _field = temp.GetHeight() / _height;
                            _delta = 0;
                            _interval = DEFAULT_INTERVAL;
                            _firstinterval = DEFAULT_FIRSTINTERVAL;
                            _drawWidth = temp.GetWidth();
                            temp.SetHeight(_field * _height);
                            temp.Deflate(-2, -2);
                            temp.Offset(SFXGrid((GetBaseBound().GetSize() - temp.GetSize()) / 2));
                            SetBaseBound(temp);
                        }
                    }
                }
            }
        }
    }
    return;
}

SGRListboxControl::~SGRListboxControl(Void)
{
    StopTimer();
    Clear();
    return;
}

SInt16 SGRListboxControl::GetItemCount(Void) const
{
    return _limit;
}

Void SGRListboxControl::SetSelect(SInt16 value)
{
    if (value >= _limit) {
        value = _limit - 1;
    }
    if (value < 0) {
        value = 0;
    }
    _select = value;
    RestartTimer();
    RefreshDelta();
    InvalidateContent();
    return;
}

SInt16 SGRListboxControl::GetSelect(Void) const
{
    return _select;
}

Void SGRListboxControl::SetDelta(SInt16 value)
{
    if (value > _limit - _field) {
        value = _limit - _field;
    }
    if (value < 0) {
        value = 0;
    }
    _delta = value;
    RefreshDelta();
    InvalidateContent();
    return;
}

SInt16 SGRListboxControl::GetDelta(Void) const
{
    return _delta;
}

Void SGRListboxControl::SetInterval(SInt16 interval)
{
    _interval = interval;
}

SInt16 SGRListboxControl::GetInterval(Void) const
{
    return _interval;
}

Void SGRListboxControl::SetFirstInterval(SInt16 interval)
{
    _firstinterval = interval;
}

SInt16 SGRListboxControl::GetFirstInterval(Void) const
{
    return _firstinterval;
}

Void SGRListboxControl::SetSpeed(SInt16 speed)
{
    _speed = speed;
}

SInt16 SGRListboxControl::GetSpeed(Void) const
{
    return _speed;
}

SFCError SGRListboxControl::Append(SFXAnsiStringConstRef item)
{
    SFXAnsiStringPtr string;
    SFCError error(SFERR_NO_ERROR);

    if ((string = ::new SFXAnsiString(item)) != null) {
        if (_item.Append(string) == SFERR_NO_ERROR) {
            ++_limit;
            // 弶夞偼僞僀儅乕婲摦
            if (_item.GetSize() == 1) {
                StartTimer();
            }
            RefreshDelta();
            InvalidateContent();
        }
        else {
            ::delete string;
            error = SFERR_FAILED;
        }
    }
    else {
        error = SFERR_NO_MEMORY;
    }
    return error;
}

Void SGRListboxControl::Remove(SInt16 index)
{
    if (!_item.IsEmpty()) {
        if (index < 0) {
            index = 0;
        }
        else if (index >= _item.GetSize()) {
            index = static_cast<SInt16>(_item.GetSize()) - 1;
        }
        delete _item[index];
        _item.Remove(index);
        if (_item.GetSize() <= 0) {
            StopTimer();
        }
        --_limit;
        if (index < _select) {
            --_select;
            RefreshDelta();
            RestartTimer();
        }
        else if (_select >= _item.GetSize()) {
            if (_select > 0) {
                --_select;
            }
            if (_delta > 0) {
                --_delta;
            }
            RefreshDelta();
            RestartTimer();
        }
        InvalidateContent();
    }
}

Void SGRListboxControl::Clear(Void)
{
    SFXArray<SFXAnsiStringPtr>::Enumerator it(_item.GetEnumerator());

    if (it.IsValid()) {
        while (it.HasNext()) {
            ::delete it.GetNext();
        }
    }
    _item.Clear();
    _limit = 0;
    _select = 0;
    StopTimer();
    RefreshDelta();
    InvalidateContent();
    return;
}

HANDLER_IMPLEMENT_BOOLEVENT(SGRListboxControl, OnKey, event)
{
    Bool result(true);

    switch (event.GetP16()) {
        case AVK_SELECT:
            if (_limit > 0) {
                Invoke(SFXEvent(SREVT_CONTROL, _select, reinterpret_cast<UInt32>(this)));
            }
            break;
        case AVK_CLR:
            SetStatusTarget(false);
            Invoke(SFXEvent(SREVT_CONTROL, SRP16_ESCAPE, reinterpret_cast<UInt32>(this)));
            break;
        case AVK_UP:
            if (_select > 0) {
                --_select;
                RestartTimer();
                RefreshDelta();
                InvalidateContent();
            }
            break;
        case AVK_DOWN:
            if (_select < _limit - 1) {
                ++_select;
                RestartTimer();
                RefreshDelta();
                InvalidateContent();
            }
            break;
        default:
            result = false;
            break;
    }
    return result;
}

HANDLER_IMPLEMENT_VOIDRENDER(SGRListboxControl, OnBase, graphics)
{
    SFXRectangle rect(GetBaseWorld());
    SFXBevelColor frameRgb(SFXRGBColor(0xAA, 0xAA, 0xAA, 0x00), SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00), SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00));

    if (GetInheritEnable()) {
        graphics->DrawBevelRectangle(rect, frameRgb);
        rect.Deflate(1, 1);
        graphics->DrawRectangle(rect, SFXRGBColor(0x00, 0x00, 0x00, 0x00));
    }
    else {
        graphics->FillRectangle(rect, frameRgb.GetBase());
        rect.Deflate(1, 1);
        graphics->DrawRectangle(rect, SFXRGBColor(0x66, 0x66, 0x66, 0x00));
    }
    return;
}

HANDLER_IMPLEMENT_VOIDRENDER(SGRListboxControl, OnContent, graphics)
{
    SFXRectangle rect(GetContentWorld());
    SFXRectangle temp;
    SFXRGBColor blue(ITEM_BLUE_COLOR);
    SInt16 r0;
    Bool next;
    Bool previous;

    if (!GetInheritEnable()) {
        blue.AddRGB(0x11);
    }
    next = (_delta + _field < _limit);
    previous = (_delta > 0);
    rect.SetHeight(_height);
    for (r0 = 0; r0 < _field; ++r0) {
        graphics->FillRectangle(rect, ((r0 + _delta) % 2 == 0) ? SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00) : blue);
        if (r0 + _delta < _limit) {
            temp = rect;
            if (r0 + _delta == _select) {
                if (GetInheritEnable() && GetInheritFocus() && GetInheritTarget()) {
                    graphics->FillRectangle(temp, SFXRGBColor(ITEM_GREEN_COLOR));
                }
            }
            DrawItem(graphics, temp, r0 + _delta, next && (r0 == _field - 1), previous && (r0 == 0), r0 + _delta == _select ? _offset : 0);
        }
        rect.Offset(0, rect.GetHeight());
    }
    return;
}

HANDLER_IMPLEMENT_VOIDRESUME(SGRListboxControl, OnResume, environment)
{
    unused(environment);

    StartTimer();
    return;
}

HANDLER_IMPLEMENT_VOIDSUSPEND(SGRListboxControl, OnSuspend, reason, info)
{
    unused(reason);
    unused(info);

    StopTimer();
    return;
}

Void SGRListboxControl::RefreshDelta(Void)
{
    if (_select < _delta) {
        _delta = _select;
    }
    else if (_select >= _delta + _field) {
        _delta = _select - _field + 1;
    }
    return;
}

Void SGRListboxControl::DrawItem(SFXGraphicsPtr graphics, SFXRectangleConstRef rect, SInt16 index, Bool next, Bool previous, SInt16 offset)
{
    SFXRectangle text(rect);
    SFXGrid grid;
    SFXRectangle icon;
    SInt16 temp;

    text.Deflate(4, 1);
    if (next || previous) {
        icon = text;
        icon.Deflate(icon.GetWidth() - icon.GetHeight(), 0, -1, 0);
        temp = 0;
        if (previous) {
            temp = DrawTriangle(graphics, icon, false, SFXRGBColor(0x00, 0x00, 0x00, 0x00));
        }
        if (next) {
            temp = DrawTriangle(graphics, icon, true, SFXRGBColor(0x00, 0x00, 0x00, 0x00));
        }
        text.Deflate(0, 0, temp, 0);
    }
    grid = text.GetOrigin();
    grid.SubX(offset);
    graphics->DrawText(*_item.Get(index), grid, text, SFXRGBColor(0x00, 0x00, 0x00, 0x00), IDF_ALIGN_LEFT);

    return;
}

SInt16 SGRListboxControl::DrawTriangle(SFXGraphicsPtr graphics, SFXRectangleConstRef rect, Bool figure, SFXRGBColorConstRef color)
{
    SFXTriangle triangle;
    SFXPixel point;
    SFXSize size;

    size.SetHeight(rect.GetHeight() / 4);
    size.SetWidth(size.GetHeight() * 2 - 1);
    point.Set(rect.GetX() + rect.GetWidth() - size.GetHeight() - size.GetWidth() + 1, rect.GetY() + ((figure) ? (rect.GetHeight() - size.GetWidth()) : (size.GetWidth() - 1)));
    triangle.SetFirst(point);
    point.Offset((size.GetWidth() - 1) / 2, (figure) ? (size.GetHeight() - 1) : (1 - size.GetHeight()));
    triangle.SetSecond(point);
    point.Offset((size.GetWidth() - 1) / 2, (figure) ? (1 - size.GetHeight()) : (size.GetHeight() - 1));
    triangle.SetThird(point);
    graphics->SetForeColor(color);
    graphics->SetFillColor(color);
    graphics->SetFillMode(true);
    graphics->DrawTriangle(triangle);
    return size.GetWidth() + (size.GetHeight() - 1) * 2;
}

Void SGRListboxControl::OnTimer(Void)
{
    SInt16 textWidth;

    textWidth = SFXGraphics::MeasureText(AEE_FONT_NORMAL, *_item.Get(_select));
    if (textWidth > _drawWidth) {
        _offset += _speed;
    }
    if (_offset > textWidth) {
        _offset =  -_drawWidth;
    }
    InvalidateContent();
    SFRApplication::GetInstance()->Invoke(SFXEvent(SREVT_RESPONDER_RENDER, SRP16_RENDER_INVOKE, false));
    SFBShell::GetInstance()->SetTimer(_interval, OnTimerEntry, this);
}

Void SGRListboxControl::OnTimerEntry(VoidPtr reference)
{
    static_cast<SGRListboxControlPtr>(reference)->OnTimer();
}

Void SGRListboxControl::StartTimer(Void)
{
    SFBShell::GetInstance()->SetTimer(_firstinterval, OnTimerEntry, this);
}

Void SGRListboxControl::StopTimer(Void)
{
    _offset = 0;
    SFBShell::GetInstance()->CancelTimer(OnTimerEntry, this);
}

Void SGRListboxControl::RestartTimer(Void)
{
    SFBShell::GetInstance()->CancelTimer(OnTimerEntry, this);
    _offset = 0;
    SFBShell::GetInstance()->SetTimer(_firstinterval, OnTimerEntry, this);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -