コード例 #1
0
ファイル: Input.cpp プロジェクト: h2so5/MikuMikuOnline
void Input::ProcessInput(InputManager* input)
{
    if (!input) {
        return;
    }

    // bool push_mouse_left = (input->GetMouseLeftCount() > 0);

    // bool first_key_shift = (input->GetKeyCount(KEY_INPUT_RSHIFT) == 1
    //        || input->GetKeyCount(KEY_INPUT_LSHIFT) == 1);

    bool push_key_shift = (input->GetKeyCount(KEY_INPUT_RSHIFT) > 0
            || input->GetKeyCount(KEY_INPUT_LSHIFT) > 0);

    bool push_key_v = (input->GetKeyCount(KEY_INPUT_V) > 0);
    bool push_key_ctrl = (input->GetKeyCount(KEY_INPUT_LCONTROL) > 0
            || input->GetKeyCount(KEY_INPUT_RCONTROL) > 0);
	
    bool push_key_return = (input->GetKeyCount(KEY_INPUT_RETURN) > 0);
    bool first_key_return = (input->GetKeyCount(KEY_INPUT_RETURN) == 1);

    bool push_repeat_key_return = (input->GetKeyCount(KEY_INPUT_RETURN)
            + KEY_REPEAT_FRAME) % (KEY_REPEAT_FRAME + 1) == 0;
    bool push_repeat_key_up = (input->GetKeyCount(KEY_INPUT_UP)
            + KEY_REPEAT_FRAME) % (KEY_REPEAT_FRAME + 1) == 0;
    bool push_repeat_key_down = (input->GetKeyCount(KEY_INPUT_DOWN)
            + KEY_REPEAT_FRAME) % (KEY_REPEAT_FRAME + 1) == 0;
    // bool push_long_backspace = (input->GetKeyCount(KEY_INPUT_BACK) > 60 * 1.5);

    auto input_text = text();
    if (!active() && push_key_v && push_key_ctrl) {
        set_active(true);
    } else {
        if (push_key_shift && push_key_return) {
            SetActiveKeyInput(input_handle_);
        } else if (first_key_return) {
            if (CheckKeyInput(input_handle_) == 1) {
                if (on_enter_) {
                    if (on_enter_(unicode::ToString(input_text))) {
                        SetKeyInputString(_T(""), input_handle_);
                    }
                }
                SetActiveKeyInput(input_handle_);
            }
        }
    }

    if (push_repeat_key_up) {
        cursor_moveto_y_ = cursor_y_ - font_height_ / 2;
        cursor_moveto_x_ = cursor_x_ + 2;
    } else if (push_repeat_key_down) {
        cursor_moveto_y_ = cursor_y_ + font_height_ + font_height_ / 2;
        cursor_moveto_x_ = cursor_x_ + 2;
    }

    if (push_key_shift && push_repeat_key_return && multiline_) {

        auto buffer = text();
        uint32_t pos = GetKeyInputCursorPosition(input_handle_);

        tstring cursor_front_str = buffer.substr(0, pos);       // カーソル前の文字列
        tstring cursor_back_str = buffer.substr(pos);           // カーソル後の文字列
        auto new_string = cursor_front_str + _T('\n') + cursor_back_str;

        SetKeyInputString(new_string.c_str(), input_handle_);
        SetKeyInputCursorPosition(pos + 1, input_handle_);
        CancelSelect();
        cursor_drag_count_ = 0;
    }

    int cursor_byte_pos, cursor_dot_pos;
    int draw_dot_pos = 0;

    TCHAR String[TEXT_BUFFER_SIZE];
    GetKeyInputString(String, input_handle_);

    // 単一行設定の時、最初の行だけを表示
    if (!multiline_) {
        tstring buffer(String, _tcslen(String));
        size_t pos;
        if ((pos = buffer.find(_T('\n'))) != std::string::npos) {
            SetKeyInputString(buffer.substr(0, pos).c_str(), input_handle_);
        }
    }

    int internal_width = width_ - INPUT_MARGIN_X * 2;
    // int internal_height = height_ - INPUT_MARGIN * 2;

    message_lines_.clear();

    if (message_.size() > 0) {
        int current_line = 0;
        tstring line_buffer;
        int line_width = 0;
        int char_count = 0;
        for (auto it = message_.begin(); it != message_.end(); ++it) {

        #ifdef UNICODE
            TCHAR c = *it;
            int width = GetDrawStringWidthToHandle(&c, 1, font_handle_);
            line_buffer += c;
            char_count++;
        #else
            unsigned char c = *it;
            TCHAR string[2] = { 0, 0 };

            int width = 0;
            if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)) {
                string[0] = c;
                string[1] = *(it + 1);
                ++it;
                width = GetDrawStringWidthToHandle(string, 2, font_handle_);
                line_buffer += string[0];
                line_buffer += string[1];
                char_count += 2;
            } else if (c == '\n') {
                char_count++;
            } else {
                string[0] = c;
                width = GetDrawStringWidthToHandle(string, 1, font_handle_);
                line_buffer += string[0];
                char_count++;
            }
        #endif

            line_width += width;
            if (c == _T('\n')
                    || line_width > internal_width - font_height_ / 2) {
                if (!line_buffer.empty() && line_buffer.back() == _T('\n')) {
                    line_buffer.pop_back();
                }
                message_lines_.push_back(line_buffer);
                current_line++;
                line_buffer.clear();
                line_width = 0;
            }
        }

        message_lines_.push_back(line_buffer);
    }

    if (active()) {
        // カーソル位置(byte)を取得
        cursor_byte_pos = GetKeyInputCursorPosition(input_handle_);
		if (prev_cursor_pos_ != cursor_byte_pos) {
			ResetCursorCount();
		}

		prev_cursor_pos_ = cursor_byte_pos;

        // カーソルのドット単位の位置を取得する
        cursor_dot_pos = GetDrawStringWidthToHandle(String, cursor_byte_pos,
                font_handle_);
        draw_dot_pos += cursor_dot_pos;

        tstring cursor_front_str(String, cursor_byte_pos); // カーソル前の文字列
        tstring cursor_back_str(String + cursor_byte_pos); // カーソル後の文字列

        std::vector<tstring> clauses;                              // 入力中の文節
        std::vector<tstring> candidates;                             // 変換候補

        lines_.clear();
        selecting_lines_.clear();
        clause_lines_.clear();
        selecting_clause_lines_.clear();
        candidates_.clear();

        // 文節データを取得
        // int selecting_clause = -1;
        selecting_candidate_ = -1;

        IMEINPUTDATA *ImeData = GetIMEInputData();
        if (ImeData && active()) {
            for (int i = 0; i < ImeData->ClauseNum; i++) {
                clauses.push_back(
                        tstring(
                                ImeData->InputString
                                        + ImeData->ClauseData[i].Position,
                                ImeData->ClauseData[i].Length));
            }
            selecting_clause_ = ImeData->SelectClause;

            if (ImeData->CandidateNum > 0) {
                for (int i = 0; i < ImeData->CandidateNum; i++) {
                    candidates_.push_back(
                            tstring(ImeData->CandidateList[i],
                                    _tcslen(ImeData->CandidateList[i])));
                }

                selecting_candidate_ = ImeData->SelectCandidate;
            }
        }

        // 選択範囲を取得
        int select_start, select_end;
        GetKeyInputSelectArea(&select_start, &select_end, input_handle_);
        if (select_start > select_end) {
            std::swap(select_start, select_end);
        }

        tstring line_buffer;
        int line_width = 0;
        int char_count = 0;

        // カーソル前のデータを描画
        for (auto it = cursor_front_str.begin(); it != cursor_front_str.end();
                ++it) {

        int prev_char_count = char_count;

        #ifdef UNICODE
            TCHAR c = *it;
            int width = GetDrawStringWidthToHandle(&c, 1, font_handle_);
            line_buffer += c;
			char_count++;
        #else
            unsigned char c = *it;
            TCHAR string[2] = { 0, 0 };

            int width = 0;
            if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)) {
                string[0] = c;
                string[1] = *(it + 1);
                ++it;
                width = GetDrawStringWidthToHandle(string, 2, font_handle_);
                line_buffer += string[0];
                line_buffer += string[1];
                char_count += 2;
            } else if (c == '\n') {
                char_count++;
            } else {
                string[0] = c;
                width = GetDrawStringWidthToHandle(string, 1, font_handle_);
                line_buffer += string[0];
                char_count++;
            }
        #endif

            // 選択範囲を記録
            if (select_start < char_count && char_count <= select_end) {
                selecting_lines_.resize(static_cast<int>(lines_.size() + message_lines_.size()) + 1,
                        std::pair<int, int>(99999, 0));
                selecting_lines_[static_cast<int>(lines_.size() + message_lines_.size())].first = std::min(
                        selecting_lines_[static_cast<int>(lines_.size() + message_lines_.size())].first, line_width);
                selecting_lines_[static_cast<int>(lines_.size() + message_lines_.size())].second = std::max(
                        selecting_lines_[static_cast<int>(lines_.size() + message_lines_.size())].second,
                        line_width + std::max(width, 3));
            }

            if (line_width - width / 2 <= cursor_moveto_x_
                    && cursor_moveto_x_ <= line_width + width
                    && static_cast<int>(lines_.size() + message_lines_.size()) * font_height_ <= cursor_moveto_y_
                    && cursor_moveto_y_ <= (static_cast<int>(lines_.size() + message_lines_.size()) + 1) * font_height_) {
                SetKeyInputCursorPosition(prev_char_count, input_handle_);
                cursor_moveto_x_ = -1;
                cursor_moveto_y_ = -1;
            }

            line_width += width;
            if (c == _T('\n') || line_width > internal_width - font_height_ / 2) {
                if (!line_buffer.empty() && line_buffer.back() == _T('\n')) {
                    line_buffer.pop_back();
                }

                lines_.push_back(line_buffer);

                if (cursor_moveto_x_ >= line_width
                        && static_cast<int>(lines_.size() + message_lines_.size()) * font_height_ <= cursor_moveto_y_
                        && cursor_moveto_y_
                                <= (static_cast<int>(lines_.size() + message_lines_.size()) + 1) * font_height_) {
                    if (c == _T('\n')) {
                        SetKeyInputCursorPosition(char_count - 1,
                                input_handle_);
                    } else {
                        SetKeyInputCursorPosition(char_count, input_handle_);
                    }
                    cursor_moveto_x_ = -1;
                    cursor_moveto_y_ = -1;
                }

                line_buffer.clear();
                line_width = 0;
            }
        }

        cursor_x_ = line_width;
        cursor_y_ = static_cast<int>(lines_.size() + message_lines_.size()) * font_height_;

        // 変換中データを描画
        for (uint32_t index = 0; index < clauses.size(); index++) {
            for (auto it = clauses[index].begin(); it != clauses[index].end();
                    ++it) {
        #ifdef UNICODE
            TCHAR c = *it;
            int width = GetDrawStringWidthToHandle(&c, 1, font_handle_);
            line_buffer += tstring(&c, 1);
			char_count++;
        #else
            unsigned char c = *it;
            TCHAR string[2] = { 0, 0 };

            int width = 0;
            if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)) {
                string[0] = c;
                string[1] = *(it + 1);
                ++it;
                width = GetDrawStringWidthToHandle(string, 2, font_handle_);
                line_buffer += string[0];
                line_buffer += string[1];
                char_count += 2;
            } else if (c == '\n') {
                char_count++;
            } else {
                string[0] = c;
                width = GetDrawStringWidthToHandle(string, 1, font_handle_);
                line_buffer += string[0];
                char_count++;
            }
        #endif

                clause_lines_.resize(static_cast<int>(lines_.size() + message_lines_.size()) + 1,
                        std::pair<int, int>(99999, 0));
                clause_lines_[static_cast<int>(lines_.size() + message_lines_.size())].first = std::min(
                        clause_lines_[static_cast<int>(lines_.size() + message_lines_.size())].first, line_width);
                clause_lines_[static_cast<int>(lines_.size() + message_lines_.size())].second = std::max(
                        clause_lines_[static_cast<int>(lines_.size() + message_lines_.size())].second, line_width + width);

                if (index == static_cast<uint32_t>(selecting_clause_)) {
                    selecting_clause_lines_.resize(static_cast<int>(lines_.size() + message_lines_.size()) + 1,
                            std::pair<int, int>(99999, 0));
                    selecting_clause_lines_[static_cast<int>(lines_.size() + message_lines_.size())].first = std::min(
                            selecting_clause_lines_[static_cast<int>(lines_.size() + message_lines_.size())].first,
                            line_width);
                    selecting_clause_lines_[static_cast<int>(lines_.size() + message_lines_.size())].second = std::max(
                            selecting_clause_lines_[static_cast<int>(lines_.size() + message_lines_.size())].second,
                            line_width + width);
                }

                line_width += width;
                if (line_width > internal_width - font_height_ / 2) {
                    lines_.push_back(line_buffer);
                    line_buffer.clear();
                    line_width = 0;
                }
            }
        }

        // カーソル後のデータを描画
        for (auto it = cursor_back_str.begin(); it != cursor_back_str.end();
                ++it) {
            int prev_char_count = char_count;

        #ifdef UNICODE
            TCHAR c = *it;
            int width = GetDrawStringWidthToHandle(&c, 1, font_handle_);
            line_buffer += tstring(&c, 1);
        #else
            unsigned char c = *it;
            TCHAR string[2] = { 0, 0 };

            int width = 0;
            if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)) {
                string[0] = c;
                string[1] = *(it + 1);
                ++it;
                width = GetDrawStringWidthToHandle(string, 2, font_handle_);
                line_buffer += string[0];
                line_buffer += string[1];
                char_count += 2;
            } else if (c == '\n') {
                char_count++;
            } else {
                string[0] = c;
                width = GetDrawStringWidthToHandle(string, 1, font_handle_);
                line_buffer += string[0];
                char_count++;
            }
        #endif

            // 選択範囲を記録
            if (select_start < char_count && char_count <= select_end) {
                selecting_lines_.resize(static_cast<int>(lines_.size() + message_lines_.size()) + 1,
                        std::pair<int, int>(99999, 0));
                selecting_lines_[static_cast<int>(lines_.size() + message_lines_.size())].first = std::min(
                        selecting_lines_[static_cast<int>(lines_.size() + message_lines_.size())].first, line_width);
                selecting_lines_[static_cast<int>(lines_.size() + message_lines_.size())].second = std::max(
                        selecting_lines_[static_cast<int>(lines_.size() + message_lines_.size())].second,
                        line_width + std::max(width, 3));
            }

            if (line_width - width / 2 <= cursor_moveto_x_
                    && cursor_moveto_x_ <= line_width + width
                    && static_cast<int>(lines_.size() + message_lines_.size()) * font_height_ <= cursor_moveto_y_
                    && cursor_moveto_y_ <= (static_cast<int>(lines_.size() + message_lines_.size()) + 1) * font_height_) {
                SetKeyInputCursorPosition(prev_char_count, input_handle_);
                cursor_moveto_x_ = -1;
                cursor_moveto_y_ = -1;
            }

            line_width += width;
            if (c == _T('\n') || line_width > internal_width - font_height_ / 2) {
                if (!line_buffer.empty() && line_buffer.back() == _T('\n')) {
                    line_buffer.pop_back();
                }
                lines_.push_back(line_buffer);

                if (cursor_moveto_x_ >= line_width
                        && static_cast<int>(lines_.size() + message_lines_.size()) * font_height_ <= cursor_moveto_y_
                        && cursor_moveto_y_
                                <= (static_cast<int>(lines_.size() + message_lines_.size()) + 1) * font_height_) {
                    if (c == _T('\n')) {
                        SetKeyInputCursorPosition(char_count - 1,
                                input_handle_);
                    } else {
                        SetKeyInputCursorPosition(char_count, input_handle_);
                    }
                    cursor_moveto_x_ = -1;
                    cursor_moveto_y_ = -1;
                }
                line_buffer.clear();
                line_width = 0;
            }
        }

        // バッファの残りを描画
        lines_.push_back(line_buffer);

        if (cursor_moveto_x_ >= line_width
                && static_cast<int>(lines_.size() + message_lines_.size()) * font_height_ <= cursor_moveto_y_
                && static_cast<int>(cursor_moveto_y_) <= static_cast<int>(lines_.size() + message_lines_.size()) * font_height_) {
            SetKeyInputCursorPosition(char_count, input_handle_);
            cursor_moveto_x_ = -1;
            cursor_moveto_y_ = -1;
        }

        height_ = static_cast<int>(lines_.size() + message_lines_.size()) * font_height_ + INPUT_MARGIN_Y * 2;
        // height_ = max(height_, min_height_);

        line_buffer.clear();
        line_width = 0;

        //if (push_key_shift && (push_repeat_key_up || push_repeat_key_down)) {
        //    SetKeyInputSelectArea(GetKeyInputCursorPosition(input_handle_),
        //            prev_cursor_pos_, input_handle_);
        //}

    }

    if (active()) {
        input->CancelKeyCountAll();
    }
}
コード例 #2
0
ファイル: dxInput_v1_00.cpp プロジェクト: hmito/hmLib_v2
		IMEINPUTDATA* cInput::getIMEPtr(){
			return GetIMEInputData();
		}