<commit_before>#include "stdafx.h"
#include "SearchWindow.h"
#include "NaiveSearchWindow.h"
#include "DataSource.h"
#include "WinampControl.h"

class NaiveSearchWindow sealed :
    public vl::presentation::controls::GuiWindow,
    public IPlugin
{
private:
    DataSource * dataSource;
    GuiVirtualTextList* listBox;
    GuiSinglelineTextBox * searchBox;

    static inline bool IsContorlKeyClean(const NativeWindowKeyInfo& info)
    {
        return !(info.alt || info.ctrl || info.shift);
    }

    vl::Ptr<vl::presentation::INativeDelay> lastChangeDelay, refreshPLDelay;
    SearchWindowStartUpParam* p;

    void NaiveHide()
    {
        auto thiswinf = vl::presentation::windows::GetWindowsForm(this->GetNativeWindow());
        ShowWindow(thiswinf->GetWindowHandle(), SW_HIDE);
    }
public:

    void InitializeComponents()
    {
        this->SetTitleBar(false);
        this->SetTopMost(true);

        this->SetBounds({200, 200, 400, 600});

        GuiTableComposition * table = new GuiTableComposition();
        table->SetRowsAndColumns(2, 1);
        table->SetCellPadding(3);
        table->SetAlignmentToParent({ 0, 0, 0, 0 });

        table->SetRowOption(0, GuiCellOption::AbsoluteOption(30));
        table->SetRowOption(1, GuiCellOption::PercentageOption(1.0));

        table->SetColumnOption(0, GuiCellOption::PercentageOption(1.0));


        this->GetContainerComposition()->AddChild(table);

        {
            GuiCellComposition* cell = new GuiCellComposition();
            table->AddChild(cell);
            cell->SetSite(0, 0, 1, 1);

            searchBox = g::NewTextBox();
            searchBox->GetBoundsComposition()->SetAlignmentToParent({ 0, 0, 0, 0 });
            searchBox->TextChanged.AttachMethod(this, &NaiveSearchWindow::searchBox_TextChanged);

            cell->AddChild(searchBox->GetBoundsComposition());
        }

        {
            GuiCellComposition* cell = new GuiCellComposition();
            table->AddChild(cell);
            cell->SetSite(1, 0, 1, 1);

            dataSource = new DataSource;
            this->OnListRefresh();

            listBox = new GuiVirtualTextList(GetCurrentTheme()->CreateTextListStyle(), GetCurrentTheme()->CreateTextListItemStyle(), dataSource);
            listBox->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
            listBox->SetHorizontalAlwaysVisible(false);
            listBox->SetMultiSelect(false);
            listBox->ItemLeftButtonDoubleClick.AttachMethod(this, &NaiveSearchWindow::listBox_ItemLeftButtonDoubleClick);
            listBox->SetVerticalAlwaysVisible(false);

            cell->AddChild(listBox->GetBoundsComposition());
        }

        this->GetNativeWindow()->HideInTaskBar();
        GetApplication()->DelayExecuteInMainThread([this]()
        {
            this->NaiveHide();
        }, 200);
#pragma region Window Events
        this->WindowLostFocus.AttachMethod(this, &NaiveSearchWindow::window_WindowLostFocus);
#pragma endregion End Window Events
    }

    NaiveSearchWindow(SearchWindowStartUpParam * param)
        : vl::presentation::controls::GuiWindow(GetCurrentTheme()->CreateWindowStyle()),
        p(param)
    {
        InitializeComponents();
        p->SearchPlugin = this;
    }

#pragma region IPlugin
    //
    //IPlugin
    //
    void OnConfig() override
    {
        //TODO:Add Config Window
        Show();
    }

    void OnExit() override
    {
        GetApplication()->InvokeLambdaInMainThreadAndWait([=](){ this->Close(); }, 500);
    }

    void OnHotkeyPressed() override
    {
        this->Show();
    }

    void OnListRefresh() override
    {
        if (refreshPLDelay)
        {
            if (refreshPLDelay->GetStatus() == INativeDelay::Pending)
            {
                refreshPLDelay->Cancel();
            }
        }
        refreshPLDelay = GetApplication()->DelayExecute([=]()
        {
            dataSource->UpdatePlaylist(p->Plugin->hwndParent);
        }, 200);
    }
#pragma endregion

#pragma region GuiWindow

    //
    //GuiWindow
    //
    void Show()
    {
        auto app = GetApplication();
        if (app->IsInMainThread())
        {
            GuiWindow::Show();
            auto thiswinf = vl::presentation::windows::GetWindowsForm(this->GetNativeWindow());
            ShowWindow(thiswinf->GetWindowHandle(), SW_SHOWNORMAL);
            BringWindowToTop(thiswinf->GetWindowHandle());
            SetForegroundWindow(thiswinf->GetWindowHandle());

            this->SetActivated();
            searchBox->SelectAll();
            searchBox->SetFocus();
        }
        else
        {
            app->InvokeLambdaInMainThread([=](){ this->Show(); });
        }
    }

    void KeyDown(const NativeWindowKeyInfo& info) override
    {
        if (info.code == VKEY_RETURN && IsContorlKeyClean(info))
        {
            auto index = listBox->GetSelectedItemIndex();
            if (index == -1)
            {
                index = 0;
            }
            PlayIndex(dataSource->TranslateIndex(index));
        }
        else if (info.code == VKEY_TAB && IsContorlKeyClean(info))
        {
            auto index = listBox->GetSelectedItemIndex();
            auto count = dataSource->Count();
            if (index != -1)
            {
                listBox->SetSelected(index, false);
            }
            listBox->SetSelected((index + 1) % count, true);
            
            listBox->SetFocus();
        }
        else if (info.code == VKEY_Q && IsContorlKeyClean(info))
        {
            if (p->QueueApi)
            {
                auto index = listBox->GetSelectedItemIndex();
                if (index == -1)
                {
                    index = 0;
                }
                QueueIndex(p->QueueApi, dataSource->TranslateIndex(index));
            }
        }
        else if (info.code == VKEY_ESCAPE)
        {
            this->NaiveHide();
        }
    }

    template <int r>
    static bool IsNear(const int& x1, const int& y1, const int& x2, const int& y2)
    {<commit_msg>完善按键逻辑<commit_after>#include "stdafx.h"
#include "SearchWindow.h"
#include "NaiveSearchWindow.h"
#include "DataSource.h"
#include "WinampControl.h"

class NaiveSearchWindow sealed :
    public vl::presentation::controls::GuiWindow,
    public IPlugin
{
private:
    DataSource * dataSource;
    GuiVirtualTextList* listBox;
    GuiSinglelineTextBox * searchBox;

    static inline bool IsContorlKeyClean(
        const NativeWindowKeyInfo& info,
        bool altstatus = false,
        bool ctrlstatus = false,
        bool shiftstatus = false)
    {
        return (info.alt == altstatus && info.ctrl == ctrlstatus && info.shift == shiftstatus);
    }

    vl::Ptr<vl::presentation::INativeDelay> lastChangeDelay, refreshPLDelay;
    SearchWindowStartUpParam* p;

    void NaiveHide()
    {
        auto thiswinf = vl::presentation::windows::GetWindowsForm(this->GetNativeWindow());
        ShowWindow(thiswinf->GetWindowHandle(), SW_HIDE);
    }
public:

    void InitializeComponents()
    {
        this->SetTitleBar(false);
        this->SetTopMost(true);

        this->SetBounds({200, 200, 400, 600});

        GuiTableComposition * table = new GuiTableComposition();
        table->SetRowsAndColumns(2, 1);
        table->SetCellPadding(3);
        table->SetAlignmentToParent({ 0, 0, 0, 0 });

        table->SetRowOption(0, GuiCellOption::AbsoluteOption(30));
        table->SetRowOption(1, GuiCellOption::PercentageOption(1.0));

        table->SetColumnOption(0, GuiCellOption::PercentageOption(1.0));


        this->GetContainerComposition()->AddChild(table);

        {
            GuiCellComposition* cell = new GuiCellComposition();
            table->AddChild(cell);
            cell->SetSite(0, 0, 1, 1);

            searchBox = g::NewTextBox();
            searchBox->GetBoundsComposition()->SetAlignmentToParent({ 0, 0, 0, 0 });
            searchBox->TextChanged.AttachMethod(this, &NaiveSearchWindow::searchBox_TextChanged);

            cell->AddChild(searchBox->GetBoundsComposition());
        }

        {
            GuiCellComposition* cell = new GuiCellComposition();
            table->AddChild(cell);
            cell->SetSite(1, 0, 1, 1);

            dataSource = new DataSource;
            this->OnListRefresh();

            listBox = new GuiVirtualTextList(GetCurrentTheme()->CreateTextListStyle(), GetCurrentTheme()->CreateTextListItemStyle(), dataSource);
            listBox->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
            listBox->SetHorizontalAlwaysVisible(false);
            listBox->SetMultiSelect(false);
            listBox->ItemLeftButtonDoubleClick.AttachMethod(this, &NaiveSearchWindow::listBox_ItemLeftButtonDoubleClick);
            listBox->SetVerticalAlwaysVisible(false);

            cell->AddChild(listBox->GetBoundsComposition());
        }

        this->GetNativeWindow()->HideInTaskBar();
        GetApplication()->DelayExecuteInMainThread([this]()
        {
            this->NaiveHide();
        }, 200);
#pragma region Window Events
        this->WindowLostFocus.AttachMethod(this, &NaiveSearchWindow::window_WindowLostFocus);
#pragma endregion End Window Events
    }

    NaiveSearchWindow(SearchWindowStartUpParam * param)
        : vl::presentation::controls::GuiWindow(GetCurrentTheme()->CreateWindowStyle()),
        p(param)
    {
        InitializeComponents();
        p->SearchPlugin = this;
    }

#pragma region IPlugin
    //
    //IPlugin
    //
    void OnConfig() override
    {
        //TODO:Add Config Window
        Show();
    }

    void OnExit() override
    {
        GetApplication()->InvokeLambdaInMainThreadAndWait([=](){ this->Close(); }, 500);
    }

    void OnHotkeyPressed() override
    {
        this->Show();
    }

    void OnListRefresh() override
    {
        if (refreshPLDelay)
        {
            if (refreshPLDelay->GetStatus() == INativeDelay::Pending)
            {
                refreshPLDelay->Cancel();
            }
        }
        refreshPLDelay = GetApplication()->DelayExecute([=]()
        {
            dataSource->UpdatePlaylist(p->Plugin->hwndParent);
        }, 200);
    }
#pragma endregion

#pragma region GuiWindow

    //
    //GuiWindow
    //
    void Show()
    {
        auto app = GetApplication();
        if (app->IsInMainThread())
        {
            GuiWindow::Show();
            auto thiswinf = vl::presentation::windows::GetWindowsForm(this->GetNativeWindow());
            ShowWindow(thiswinf->GetWindowHandle(), SW_SHOWNORMAL);
            BringWindowToTop(thiswinf->GetWindowHandle());
            SetForegroundWindow(thiswinf->GetWindowHandle());

            this->SetActivated();
            searchBox->SelectAll();
            searchBox->SetFocus();
        }
        else
        {
            app->InvokeLambdaInMainThread([=](){ this->Show(); });
        }
    }

    void KeyDown(const NativeWindowKeyInfo& info) override
    {
        if (info.code == VKEY_RETURN && IsContorlKeyClean(info)) //Enter
        {
            auto index = listBox->GetSelectedItemIndex();
            if (index == -1)
            {
                index = 0;
            }
            PlayIndex(dataSource->TranslateIndex(index));
        }
        else if (info.code == VKEY_TAB && IsContorlKeyClean(info)) //Tab
        {
            auto index = listBox->GetSelectedItemIndex();
            auto count = dataSource->Count();
            if (index != -1)
            {
                listBox->SetSelected(index, false);
            }
            index = (index + 1) % count;
            listBox->SetSelected(index, true);
            listBox->EnsureItemVisible(index);
            listBox->SetFocus();
        }
        else if (info.code == VKEY_Q && IsContorlKeyClean(info)) //Q
        {
            if (p->QueueApi)
            {
                auto index = listBox->GetSelectedItemIndex();
                if (index == -1)
                {
                    index = 0;
                }
                QueueIndex(p->QueueApi, dataSource->TranslateIndex(index));
            }
        }
        else if (info.code == VKEY_ESCAPE) //ESC
        {
            this->NaiveHide();
        }
    }

    template <int r>
    static bool IsNear(const int& x1, const int& y1, const int& x2, const int& y2)
    {
{'fraction_non_alphanumeric': 0.1254355400696864, 'fraction_numerical': 0.01020986954055587, 'mean_word_length': 2.1875, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 150, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3613758', 'n_tokens_mistral': 3577, 'n_tokens_neox': 3409, 'n_words': 584}