Files
msime-windows/server/src/config/ime_config_toolbar.cpp
T
Lu Fan(SonnyCalcr) 42c2666a4d feat(server): 悬浮工具栏改用候选窗的柔和阴影,开着阴影也能贴边,并可在设置中关闭阴影 (#809)
* feat(server): 悬浮工具栏改用候选窗的柔和阴影,并可在设置中关闭阴影

- D2D 工具栏改用与候选窗相同的两层阴影(light α .18/.10,dark α .34/.22),
  透明边距与候选窗一致(16/14/32/34 DIP)
- 新增配置 general.floating_toolbar_shadow(默认开启),设置页「悬浮工具栏」
  加「工具栏阴影」开关;关闭后去掉阴影边距,工具栏可贴住屏幕边缘
- 关闭阴影时保留 1 DIP 边距,避免居中描边的外半边被窗口边缘裁掉
- WebView2 工具栏:开关同样生效;默认页阴影改为候选窗的近接层(宿主只留 8px)

* feat(server): 悬浮工具栏开着阴影也能贴住屏幕边缘

- 阴影边距允许伸出屏幕:拖动结束、改尺寸和默认位置都只要求工具栏本体
  (含描边)留在工作区内;伸出工作区的部分用窗口区域裁掉,不绘制、
  不挡任务栏点击,拖动时实时更新
- 伸出量按宿主实际像素尺寸和卡片位置计算,消除向上取整留下的 1-3 px
  缝隙;关掉阴影时同样贴边
- 切换阴影时保持工具栏本体位置不动,并按工作区重新判定边界,
  避免工具栏一部分跑到任务栏下面
- 设置页「工具栏阴影」说明改为「在工具栏周围显示与候选窗一致的柔和阴影」
2026-10-11 13:07:27 +08:00

200 lines
5.4 KiB
C++

// 悬浮工具栏与光标状态角标配置:显隐、按钮项、缩放与字号,以及角标的开关、聚焦时显示和位置。
#include "window/caret_state_indicator_policy.h"
#include "config/ime_config_internal.h"
#include <cmath>
#include <string>
using namespace ime_config_detail;
bool GetConfiguredFloatingToolbarEnabled()
{
return g_floating_toolbar_enabled;
}
bool SetConfiguredFloatingToolbarEnabled(bool enabled)
{
if (!WriteConfiguredValue("general", "floating_toolbar", enabled ? "true" : "false"))
{
return false;
}
g_floating_toolbar_enabled = enabled;
return true;
}
bool GetConfiguredCaretStateIndicatorEnabled()
{
return g_caret_state_indicator_enabled;
}
bool SetConfiguredCaretStateIndicatorEnabled(bool enabled)
{
if (!WriteConfiguredValue("general", "caret_state_indicator", enabled ? "true" : "false"))
{
return false;
}
g_caret_state_indicator_enabled = enabled;
return true;
}
bool GetConfiguredCaretStateIndicatorOnFocus()
{
return g_caret_state_indicator_on_focus;
}
bool SetConfiguredCaretStateIndicatorOnFocus(bool enabled)
{
if (!WriteConfiguredValue("general", "caret_state_indicator_on_focus", enabled ? "true" : "false"))
{
return false;
}
g_caret_state_indicator_on_focus = enabled;
return true;
}
const std::string &GetConfiguredCaretStateIndicatorPosition()
{
return g_caret_state_indicator_position;
}
bool SetConfiguredCaretStateIndicatorPosition(const std::string &position)
{
if (!FanyImeUi::IsValidCaretStatePosition(position))
return false;
if (!WriteConfiguredValue("general", "caret_state_indicator_position", EscapeTomlBasicString(position)))
return false;
g_caret_state_indicator_position = position;
return true;
}
const FloatingToolbarItemsConfig &GetConfiguredFloatingToolbarItems()
{
return g_floating_toolbar_items;
}
bool SetConfiguredFloatingToolbarItemEnabled(const std::string &item, bool enabled)
{
bool *target = nullptr;
if (item == "fullwidth")
target = &g_floating_toolbar_items.fullwidth;
else if (item == "punctuation")
target = &g_floating_toolbar_items.punctuation;
else if (item == "character_set")
target = &g_floating_toolbar_items.character_set;
else if (item == "emoji")
target = &g_floating_toolbar_items.emoji;
else if (item == "screen_keyboard")
target = &g_floating_toolbar_items.screen_keyboard;
else if (item == "settings")
target = &g_floating_toolbar_items.settings;
else
return false;
if (!WriteConfiguredValue("general", "floating_toolbar_" + item, enabled ? "true" : "false"))
return false;
*target = enabled;
return true;
}
namespace
{
double SnapFloatingToolbarScale(double scale)
{
static const double kAllowed[] = {0.75, 1.0, 1.25, 1.5};
double best = 1.0;
double bestDelta = std::abs(scale - best);
for (double candidate : kAllowed)
{
const double delta = std::abs(scale - candidate);
if (delta < bestDelta)
{
best = candidate;
bestDelta = delta;
}
}
return best;
}
std::string FormatFloatingToolbarScale(double scale)
{
if (std::abs(scale - 0.75) < 0.001)
return "0.75";
if (std::abs(scale - 1.25) < 0.001)
return "1.25";
if (std::abs(scale - 1.5) < 0.001)
return "1.5";
return "1.0";
}
} // namespace
double GetConfiguredFloatingToolbarScale()
{
return g_floating_toolbar_scale;
}
bool SetConfiguredFloatingToolbarScale(double scale)
{
if (scale < kFloatingToolbarScaleMin || scale > kFloatingToolbarScaleMax)
return false;
scale = SnapFloatingToolbarScale(scale);
if (!WriteConfiguredValue("general", "floating_toolbar_scale", FormatFloatingToolbarScale(scale)))
return false;
g_floating_toolbar_scale = scale;
return true;
}
int GetConfiguredFloatingToolbarFontSize()
{
return g_floating_toolbar_font_size;
}
bool SetConfiguredFloatingToolbarFontSize(int font_size)
{
if (font_size < kFloatingToolbarFontSizeMin || font_size > kFloatingToolbarFontSizeMax)
return false;
if (!WriteConfiguredValue("general", "floating_toolbar_font_size", std::to_string(font_size)))
return false;
g_floating_toolbar_font_size = font_size;
return true;
}
bool GetConfiguredFloatingToolbarAutoHide()
{
return g_floating_toolbar_auto_hide;
}
bool SetConfiguredFloatingToolbarAutoHide(bool enabled)
{
if (!WriteConfiguredValue("general", "floating_toolbar_auto_hide", enabled ? "true" : "false"))
return false;
g_floating_toolbar_auto_hide = enabled;
return true;
}
int GetConfiguredFloatingToolbarAutoHideDelay()
{
return g_floating_toolbar_auto_hide_delay;
}
bool SetConfiguredFloatingToolbarAutoHideDelay(int seconds)
{
if (seconds < kFloatingToolbarAutoHideDelayMin || seconds > kFloatingToolbarAutoHideDelayMax)
return false;
if (!WriteConfiguredValue("general", "floating_toolbar_auto_hide_delay", std::to_string(seconds)))
return false;
g_floating_toolbar_auto_hide_delay = seconds;
return true;
}
bool GetConfiguredFloatingToolbarShadow()
{
return g_floating_toolbar_shadow;
}
bool SetConfiguredFloatingToolbarShadow(bool enabled)
{
if (!WriteConfiguredValue("general", "floating_toolbar_shadow", enabled ? "true" : "false"))
return false;
g_floating_toolbar_shadow = enabled;
return true;
}