diff --git a/RimeWithWeasel/RimeWithWeasel.cpp b/RimeWithWeasel/RimeWithWeasel.cpp index 9fbdd8ef5..d21a6a271 100644 --- a/RimeWithWeasel/RimeWithWeasel.cpp +++ b/RimeWithWeasel/RimeWithWeasel.cpp @@ -1224,6 +1224,8 @@ static void _UpdateUIStyle(RimeConfig* config, UI* ui, bool initialize) { true, false); _RimeGetBool(config, "style/vertical_auto_reverse", initialize, style.vertical_auto_reverse, true, false); + _RimeGetBool(config, "style/comment_on_top", initialize, style.comment_on_top, + true, false); const std::map _preeditMap = { {std::string("composition"), UIStyle::COMPOSITION}, {std::string("preview"), UIStyle::PREVIEW}, diff --git a/WeaselUI/HorizontalLayout.cpp b/WeaselUI/HorizontalLayout.cpp index 99d8e64cb..1ca8d086d 100644 --- a/WeaselUI/HorizontalLayout.cpp +++ b/WeaselUI/HorizontalLayout.cpp @@ -93,21 +93,15 @@ void HorizontalLayout::DoLayout(CDCHandle dc, PDWR pDWR) { std::wstring label = GetLabelText(labels, i, _style.label_text_format.c_str()); GetTextSizeDW(label, label.length(), pDWR->pLabelTextFormat, pDWR, &size); - _candidateLabelRects[i].SetRect(w, height, w + size.cx * labelFontValid, - height + size.cy); - w += size.cx * labelFontValid; - current_cand_width += size.cx * labelFontValid; + int labelWidth = size.cx * labelFontValid, labelHeight = size.cy; /* Text */ - w += _style.hilite_spacing; const std::wstring& text = candidates.at(i).str; GetTextSizeDW(text, text.length(), pDWR->pTextFormat, pDWR, &size); - _candidateTextRects[i].SetRect(w, height, w + size.cx * textFontValid, - height + size.cy); - w += size.cx * textFontValid; - current_cand_width += (size.cx + _style.hilite_spacing) * textFontValid; + int textWidth = size.cx * textFontValid, textHeight = size.cy; /* Comment */ + int cmtWidth = 0, cmtHeight = 0; bool cmtFontNotTrans = (i == id && (_style.hilited_comment_text_color & 0xff000000)) || (i != id && (_style.comment_text_color & 0xff000000)); @@ -115,24 +109,79 @@ void HorizontalLayout::DoLayout(CDCHandle dc, PDWR pDWR) { const std::wstring& comment = comments.at(i).str; GetTextSizeDW(comment, comment.length(), pDWR->pCommentTextFormat, pDWR, &size); + cmtWidth = size.cx * cmtFontValid; + cmtHeight = size.cy; + } + + int totalHeight = 0; + + if (_style.comment_on_top) { + totalHeight = max(labelHeight, textHeight) + cmtHeight; + int maxWidthTextOrCmt = max(textWidth, cmtWidth); + int maxHeightTextOrLabel = max(textHeight, labelHeight); + + _candidateLabelRects[i].SetRect(w, height + cmtHeight, w + labelWidth, + height + cmtHeight + labelHeight); + w += labelWidth; + current_cand_width += labelWidth; + w += _style.hilite_spacing; - _candidateCommentRects[i].SetRect(w, height, w + size.cx * cmtFontValid, - height + size.cy); - w += size.cx * cmtFontValid; - current_cand_width += (size.cx + _style.hilite_spacing) * cmtFontValid; - } else /* Used for highlighted candidate calculation below */ - _candidateCommentRects[i].SetRect(w, height, w, height + size.cy); + current_cand_width += _style.hilite_spacing * textFontValid; + + _candidateTextRects[i].SetRect(w, height + cmtHeight, w + textWidth, + height + cmtHeight + textHeight); + _candidateCommentRects[i].SetRect(w, height, w + cmtWidth, + height + cmtHeight); + w += maxWidthTextOrCmt; + current_cand_width += maxWidthTextOrCmt; + + _candidateLabelRects[i].OffsetRect( + 0, (maxHeightTextOrLabel - labelHeight) / 2); + _candidateTextRects[i].OffsetRect( + (maxWidthTextOrCmt - textWidth) / 2, + (maxHeightTextOrLabel - textHeight) / 2); + _candidateCommentRects[i].OffsetRect((maxWidthTextOrCmt - cmtWidth) / 2, + 0); + } else { + totalHeight = max(labelHeight, max(textHeight, cmtHeight)); + _candidateLabelRects[i].SetRect(w, height, w + labelWidth, + height + labelHeight); + w += labelWidth; + current_cand_width += labelWidth; + + w += _style.hilite_spacing; + current_cand_width += _style.hilite_spacing * textFontValid; + + _candidateTextRects[i].SetRect(w, height, w + textWidth, + height + textHeight); + w += textWidth; + current_cand_width += textWidth; + + if (cmtWidth > 0) { + w += _style.hilite_spacing; + current_cand_width += _style.hilite_spacing * cmtFontValid; + + _candidateCommentRects[i].SetRect(w, height, w + cmtWidth, + height + cmtHeight); + + w += cmtWidth; + current_cand_width += cmtWidth; + } else { + _candidateCommentRects[i].SetRect(w, height, w + cmtWidth, + height + cmtHeight); + } + } int base_left = (i == id) ? _candidateLabelRects[i].left - base_offset : _candidateLabelRects[i].left; // if not the first candidate of current row, and current candidate's // right > _style.max_width if (_style.max_width > 0 && (base_left > real_margin_x + offsetX) && - (_candidateCommentRects[i].right - offsetX + real_margin_x > - _style.max_width)) { + (w - offsetX + real_margin_x > _style.max_width)) { // max_width_of_rows current row max_width_of_rows = - max(max_width_of_rows, _candidateCommentRects[i - 1].right); + max(max_width_of_rows, max(_candidateCommentRects[i - 1].right, + _candidateTextRects[i - 1].right)); w = offsetX + real_margin_x + (i == id ? base_offset : 0); int ofx = w - _candidateLabelRects[i].left; int ofy = height_of_rows[row_cnt] + _style.candidate_spacing; @@ -142,8 +191,9 @@ void HorizontalLayout::DoLayout(CDCHandle dc, PDWR pDWR) { _candidateCommentRects[i].OffsetRect(ofx, ofy); // max width of next row, if it's the last candidate, make sure // max_width_of_rows calc right - max_width_of_rows = - max(max_width_of_rows, _candidateCommentRects[i].right); + max_width_of_rows = max( + max_width_of_rows, + max(_candidateCommentRects[i].right, _candidateTextRects[i].right)); mintop_of_rows[row_cnt] = height; height += ofy; // re calc rect position, decrease offsetX for origin @@ -153,12 +203,7 @@ void HorizontalLayout::DoLayout(CDCHandle dc, PDWR pDWR) { max_width_of_rows = max(max_width_of_rows, w); // calculate height of current row is the max of three rects mintop_of_rows[row_cnt] = height; - height_of_rows[row_cnt] = - max(height_of_rows[row_cnt], _candidateLabelRects[i].Height()); - height_of_rows[row_cnt] = - max(height_of_rows[row_cnt], _candidateTextRects[i].Height()); - height_of_rows[row_cnt] = - max(height_of_rows[row_cnt], _candidateCommentRects[i].Height()); + height_of_rows[row_cnt] = max(height_of_rows[row_cnt], totalHeight); // set row info of current candidate row_of_candidate[i] = row_cnt; } @@ -168,32 +213,47 @@ void HorizontalLayout::DoLayout(CDCHandle dc, PDWR pDWR) { for (auto i = 0; i < candidates_count && i < MAX_CANDIDATES_COUNT; ++i) { int base_left = (i == id) ? _candidateLabelRects[i].left - base_offset : _candidateLabelRects[i].left; - _candidateRects[i].SetRect(base_left, mintop_of_rows[row_of_candidate[i]], - _candidateCommentRects[i].right, - mintop_of_rows[row_of_candidate[i]] + - height_of_rows[row_of_candidate[i]]); - int ol = 0, ot = 0, oc = 0; - if (_style.align_type == UIStyle::ALIGN_CENTER) { - ol = (height_of_rows[row_of_candidate[i]] - - _candidateLabelRects[i].Height()) / - 2; - ot = (height_of_rows[row_of_candidate[i]] - - _candidateTextRects[i].Height()) / - 2; - oc = (height_of_rows[row_of_candidate[i]] - - _candidateCommentRects[i].Height()) / - 2; - } else if (_style.align_type == UIStyle::ALIGN_BOTTOM) { - ol = (height_of_rows[row_of_candidate[i]] - - _candidateLabelRects[i].Height()); - ot = (height_of_rows[row_of_candidate[i]] - - _candidateTextRects[i].Height()); - oc = (height_of_rows[row_of_candidate[i]] - - _candidateCommentRects[i].Height()); + _candidateRects[i].SetRect( + base_left, mintop_of_rows[row_of_candidate[i]], + max(_candidateCommentRects[i].right, _candidateTextRects[i].right), + mintop_of_rows[row_of_candidate[i]] + + height_of_rows[row_of_candidate[i]]); + if (_style.comment_on_top) { + int ot = 0; + int height_of_candidate = + _candidateTextRects[i].bottom - _candidateCommentRects[i].top; + if (_style.align_type == UIStyle::ALIGN_CENTER) { + ot = (height_of_rows[row_of_candidate[i]] - height_of_candidate) / 2; + } else if (_style.align_type == UIStyle::ALIGN_BOTTOM) { + ot = (height_of_rows[row_of_candidate[i]] - height_of_candidate); + } + _candidateLabelRects[i].OffsetRect(0, ot); + _candidateTextRects[i].OffsetRect(0, ot); + _candidateCommentRects[i].OffsetRect(0, ot); + } else { + int ol = 0, ot = 0, oc = 0; + if (_style.align_type == UIStyle::ALIGN_CENTER) { + ol = (height_of_rows[row_of_candidate[i]] - + _candidateLabelRects[i].Height()) / + 2; + ot = (height_of_rows[row_of_candidate[i]] - + _candidateTextRects[i].Height()) / + 2; + oc = (height_of_rows[row_of_candidate[i]] - + _candidateCommentRects[i].Height()) / + 2; + } else if (_style.align_type == UIStyle::ALIGN_BOTTOM) { + ol = (height_of_rows[row_of_candidate[i]] - + _candidateLabelRects[i].Height()); + ot = (height_of_rows[row_of_candidate[i]] - + _candidateTextRects[i].Height()); + oc = (height_of_rows[row_of_candidate[i]] - + _candidateCommentRects[i].Height()); + } + _candidateLabelRects[i].OffsetRect(0, ol); + _candidateTextRects[i].OffsetRect(0, ot); + _candidateCommentRects[i].OffsetRect(0, oc); } - _candidateLabelRects[i].OffsetRect(0, ol); - _candidateTextRects[i].OffsetRect(0, ot); - _candidateCommentRects[i].OffsetRect(0, oc); } height = mintop_of_rows[row_cnt] + height_of_rows[row_cnt] - offsetY; width = max(width, max_width_of_rows); diff --git a/include/WeaselIPCData.h b/include/WeaselIPCData.h index 09f22f91c..9d3fd1e77 100644 --- a/include/WeaselIPCData.h +++ b/include/WeaselIPCData.h @@ -264,6 +264,7 @@ struct UIStyle { int shadow_offset_x; int shadow_offset_y; bool vertical_auto_reverse; + bool comment_on_top; // color scheme int text_color; int candidate_text_color; @@ -337,6 +338,7 @@ struct UIStyle { shadow_offset_x(0), shadow_offset_y(0), vertical_auto_reverse(false), + comment_on_top(false), text_color(0), candidate_text_color(0), candidate_back_color(0), @@ -399,8 +401,8 @@ struct UIStyle { shadow_offset_x != st.shadow_offset_x || shadow_offset_y != st.shadow_offset_y || vertical_auto_reverse != st.vertical_auto_reverse || - baseline != st.baseline || linespacing != st.linespacing || - text_color != st.text_color || + comment_on_top != st.comment_on_top || baseline != st.baseline || + linespacing != st.linespacing || text_color != st.text_color || candidate_text_color != st.candidate_text_color || candidate_back_color != st.candidate_back_color || candidate_shadow_color != st.candidate_shadow_color || @@ -473,6 +475,7 @@ void serialize(Archive& ar, weasel::UIStyle& s, const unsigned int version) { ar & s.shadow_offset_x; ar & s.shadow_offset_y; ar & s.vertical_auto_reverse; + ar & s.comment_on_top; // color scheme ar & s.text_color; ar & s.candidate_text_color; diff --git a/output/data/weasel.yaml b/output/data/weasel.yaml index b4e331515..205c06d6b 100644 --- a/output/data/weasel.yaml +++ b/output/data/weasel.yaml @@ -42,6 +42,7 @@ style: vertical_text: false vertical_text_left_to_right: false vertical_text_with_wrap: false + comment_on_top: false layout: align_type: center max_width: 0 #set 0 to disable max width