クリップボードを監視してリアルタイムでテキストを整形する
https://gyazo.com/54f8d915c42c51279271a3f158d925e5
Siv3D ではクリップボードからテキストを簡単に取得できます。
code:cpp
String text;
Clipboard::GetText(text);
また、クリップボードの内容が変化したかどうかの情報も得ることが可能です。
code:cpp
if (Clipboard::HasChanged())
{
...
}
これらの機能を利用し、クリップボードを監視してリアルタイムでテキストを整形するアプリを簡単に作ることができます。
【例】
code:cpp
// 矢印アイコン (アイコン名称: 'arrow-up', コードポイント: F005D) のテクスチャ
auto arrowUpTexture = Texture{ Icon{ 0xF005D }, textureSize };
そこで、アイコン名称とコードポイントから、以下のような変数定義を生成したいとします。
code:cpp
inline constexpr uint32 IconID_ArrowUp = 0xF005D;
inline constexpr uint32 IconID_ArrowDown = 0xF0045;
inline constexpr uint32 IconID_Headphones = 0xF02CB;
inline constexpr uint32 IconID_BatteryCharging90 = 0xF008B;
inline constexpr uint32 IconID_WeatherCloudy = 0xF0590;
...
次のようなプログラムで、上記のアイコンのサイトを眺めながら名称とコードポイントを順番にコピーしていくだけで、変数定義を作ることができます。
code:cpp
# include <Siv3D.hpp> // Siv3D v0.6.16
namespace
{
// クリップボードの内容が変化したとき、文字列として取得可能ならその文字列を返す
Optional<String> GetClipboardTextIfChanged()
{
if (not Clipboard::HasChanged()) return none;
String text;
if (not Clipboard::GetText(text)) return none;
return text;
}
// Material Design Icons の名称(ハイフン区切りの小文字表記)をキャメルケースにする
String MDIconNameToCamelCase(const String& mdIconName)
{
return mdIconName.split(U'-').map([](const auto& text) { return text.capitalized(); }).join(U"", U"", U"");
}
}
namespace
{
// 整形に必要な文字列の数
constexpr int TokenCount = 2;
// 整形したテキストを返す
String FormattedText(const Array<String>& tokens)
{
return U"inline constexpr uint32 IconID_{} = 0x{};"_fmt(MDIconNameToCamelCase(tokens0), tokens1); }
}
void Main()
{
Scene::SetBackground(Palette::Whitesmoke);
Window::SetStyle(WindowStyle::Sizable);
// GUI
ListBoxState lbState;
// 整形したテキストのリスト
Array<String>& formattedTextList = lbState.items;
// 直前にコピーしたテキスト
String previousText = U"";
Array<String> tokens;
while (System::Update())
{
if (auto text = GetClipboardTextIfChanged();
text)
{
// クリップボードのテキストが変化したとき、それをメモする
// ※特定の文字列が含まれる場合は処理しない(リストの内容をコピーするときに処理しないようにする)
// ※直前にコピーしたテキストと同じ内容の場合も処理しない
if (not text->includes(U"inline constexpr ") && (*text != previousText))
{
tokens.push_back(*text);
previousText = *text;
}
// メモしたテキストを整形してリストに追加する
if (tokens.size() >= TokenCount)
{
const String formatted = FormattedText(tokens);
formattedTextList.push_back(formatted);
tokens.clear();
}
}
// リストの内容をクリップボードにコピー
if (SimpleGUI::ButtonAt(U"Copy", Scene::Rect().bottomCenter() + Vec2{ -80, -32 }))
{
Clipboard::SetText(formattedTextList.join(U"\n", U"", U""));
}
// 状態をすべてクリア
if (SimpleGUI::ButtonAt(U"Clear", Scene::Rect().bottomCenter() + Vec2{ 80, -32 }))
{
formattedTextList.clear();
tokens.clear();
previousText = U"";
}
// 整形したテキストのリスト
SimpleGUI::ListBox(lbState, Vec2{ 0, 0 }, Scene::Width(), Scene::Height() - 64);
}
}