nodehub 1/5 | ai transform 2/3

This commit is contained in:
lovebird 2026-04-15 22:03:52 +02:00
parent 386b6171af
commit f65e282c21
26 changed files with 545 additions and 47 deletions

View File

@ -203,6 +203,7 @@ if(WIN32)
"${_UI_NEXT_DIR}/DropView.cpp"
"${_UI_NEXT_DIR}/FileQueue.cpp"
"${_UI_NEXT_DIR}/LogPanel.cpp"
"${_UI_NEXT_DIR}/FileInfoPanel.cpp"
"${_UI_NEXT_DIR}/SettingsPanel.cpp"
"${_UI_NEXT_DIR}/Mainfrm.cpp"
"${_UI_NEXT_DIR}/launch_ui_next.cpp"

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 KiB

View File

@ -31,4 +31,55 @@ private:
CString m_label;
};
// Generated preview dock (for showing AI-generated images on the right)
class CGenPreviewContainer : public CDockContainer
{
public:
CGenPreviewContainer() {
SetTabText(L"Generated");
SetDockCaption(L"Generated Preview");
SetView(m_preview);
}
virtual ~CGenPreviewContainer() override = default;
CImagePreview& GetPreview() { return m_preview; }
protected:
virtual LRESULT WndProc(UINT msg, WPARAM wparam, LPARAM lparam) override {
try { return WndProcDefault(msg, wparam, lparam); }
catch (const CException& e) {
CString s; s << e.GetText() << L'\n' << e.GetErrorString();
::MessageBox(nullptr, s, L"Error", MB_ICONERROR);
}
return 0;
}
private:
CGenPreviewContainer(const CGenPreviewContainer&) = delete;
CGenPreviewContainer& operator=(const CGenPreviewContainer&) = delete;
CImagePreview m_preview;
};
class CDockGenPreview : public CDocker
{
public:
CDockGenPreview() { SetView(m_container); SetBarWidth(8); }
virtual ~CDockGenPreview() override = default;
CGenPreviewContainer& GetContainer() { return m_container; }
protected:
virtual LRESULT WndProc(UINT msg, WPARAM wparam, LPARAM lparam) override {
try { return WndProcDefault(msg, wparam, lparam); }
catch (const CException& e) {
CString s; s << e.GetText() << L'\n' << e.GetErrorString();
::MessageBox(nullptr, s, L"Error", MB_ICONERROR);
}
return 0;
}
private:
CDockGenPreview(const CDockGenPreview&) = delete;
CDockGenPreview& operator=(const CDockGenPreview&) = delete;
CGenPreviewContainer m_container;
};
#endif // PM_UI_DROPVIEW_H

View File

@ -0,0 +1,235 @@
#include "stdafx.h"
#include "FileInfoPanel.h"
#include <filesystem>
#include <sstream>
#include <iomanip>
#include <ctime>
#pragma comment(lib, "gdiplus.lib")
namespace fs = std::filesystem;
static std::wstring FormatFileSize(uintmax_t bytes) {
std::wostringstream oss;
if (bytes < 1024)
oss << bytes << L" B";
else if (bytes < 1024 * 1024)
oss << std::fixed << std::setprecision(1) << (bytes / 1024.0) << L" KB";
else if (bytes < 1024ULL * 1024 * 1024)
oss << std::fixed << std::setprecision(1) << (bytes / (1024.0 * 1024.0)) << L" MB";
else
oss << std::fixed << std::setprecision(2) << (bytes / (1024.0 * 1024.0 * 1024.0)) << L" GB";
return oss.str();
}
static std::wstring FormatFileTime(const fs::file_time_type& ft) {
auto sctp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(
ft - fs::file_time_type::clock::now() + std::chrono::system_clock::now());
std::time_t tt = std::chrono::system_clock::to_time_t(sctp);
struct tm local;
localtime_s(&local, &tt);
wchar_t buf[64];
wcsftime(buf, 64, L"%Y-%m-%d %H:%M:%S", &local);
return buf;
}
static std::wstring ReadExifString(Gdiplus::Image* img, PROPID id) {
UINT sz = img->GetPropertyItemSize(id);
if (sz == 0) return {};
std::vector<BYTE> buf(sz);
auto* item = reinterpret_cast<Gdiplus::PropertyItem*>(buf.data());
if (img->GetPropertyItem(id, sz, item) != Gdiplus::Ok) return {};
if (item->type == 2 && item->value) {
std::string s(reinterpret_cast<char*>(item->value));
return std::wstring(s.begin(), s.end());
}
return {};
}
static std::wstring ReadExifRational(Gdiplus::Image* img, PROPID id) {
UINT sz = img->GetPropertyItemSize(id);
if (sz == 0) return {};
std::vector<BYTE> buf(sz);
auto* item = reinterpret_cast<Gdiplus::PropertyItem*>(buf.data());
if (img->GetPropertyItem(id, sz, item) != Gdiplus::Ok) return {};
if (item->type == 5 && item->length >= 8) {
ULONG* r = reinterpret_cast<ULONG*>(item->value);
if (r[1] == 0) return L"0";
double v = (double)r[0] / r[1];
if (v < 1.0) {
std::wostringstream oss;
oss << r[0] << L"/" << r[1];
return oss.str();
}
std::wostringstream oss;
oss << std::fixed << std::setprecision(1) << v;
return oss.str();
}
return {};
}
static std::wstring ReadExifShort(Gdiplus::Image* img, PROPID id) {
UINT sz = img->GetPropertyItemSize(id);
if (sz == 0) return {};
std::vector<BYTE> buf(sz);
auto* item = reinterpret_cast<Gdiplus::PropertyItem*>(buf.data());
if (img->GetPropertyItem(id, sz, item) != Gdiplus::Ok) return {};
if (item->type == 3 && item->length >= 2) {
USHORT val = *reinterpret_cast<USHORT*>(item->value);
return std::to_wstring(val);
}
return {};
}
//////////////////////////////////////////
// CFileInfoView
//////////////////////////////////////////
int CFileInfoView::OnCreate(CREATESTRUCT&)
{
m_hEdit = ::CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_READONLY | ES_AUTOVSCROLL,
0, 0, 100, 100, GetHwnd(), nullptr, GetModuleHandleW(nullptr), nullptr);
HFONT hFont = static_cast<HFONT>(::GetStockObject(DEFAULT_GUI_FONT));
::SendMessage(m_hEdit, WM_SETFONT, (WPARAM)hFont, TRUE);
return 0;
}
void CFileInfoView::Clear()
{
if (m_hEdit)
::SetWindowTextW(m_hEdit, L"");
}
void CFileInfoView::ShowFileInfo(LPCWSTR path)
{
if (!m_hEdit || !path || !path[0]) { Clear(); return; }
std::wostringstream info;
std::error_code ec;
fs::path fp(path);
info << L"File: " << fp.filename().wstring() << L"\r\n";
info << L"Path: " << fp.parent_path().wstring() << L"\r\n";
if (fs::exists(fp, ec)) {
auto sz = fs::file_size(fp, ec);
if (!ec) info << L"Size: " << FormatFileSize(sz) << L"\r\n";
auto lwt = fs::last_write_time(fp, ec);
if (!ec) info << L"Modified: " << FormatFileTime(lwt) << L"\r\n";
}
info << L"\r\n";
// Read image dimensions and EXIF via GDI+
Gdiplus::GdiplusStartupInput si;
ULONG_PTR token = 0;
Gdiplus::GdiplusStartup(&token, &si, nullptr);
auto* img = Gdiplus::Image::FromFile(path);
if (img && img->GetLastStatus() == Gdiplus::Ok) {
info << L"Dimensions: " << img->GetWidth() << L" x " << img->GetHeight() << L"\r\n";
GUID rawFmt;
img->GetRawFormat(&rawFmt);
auto pixFmt = img->GetPixelFormat();
int bpp = (pixFmt >> 8) & 0xFF;
info << L"Bit depth: " << bpp << L"\r\n";
info << L"\r\n--- EXIF ---\r\n";
auto make = ReadExifString(img, 0x010F);
auto model = ReadExifString(img, 0x0110);
auto date = ReadExifString(img, 0x9003);
auto fnum = ReadExifRational(img, 0x829D);
auto expT = ReadExifRational(img, 0x829A);
auto iso = ReadExifShort(img, 0x8827);
auto focal = ReadExifRational(img, 0x920A);
auto focal35= ReadExifShort(img, 0xA405);
auto sw = ReadExifString(img, 0x0131);
if (!make.empty()) info << L"Make: " << make << L"\r\n";
if (!model.empty()) info << L"Camera: " << model << L"\r\n";
if (!date.empty()) info << L"Date taken: " << date << L"\r\n";
if (!fnum.empty()) info << L"Aperture: f/" << fnum << L"\r\n";
if (!expT.empty()) info << L"Shutter: " << expT << L"s\r\n";
if (!iso.empty()) info << L"ISO: " << iso << L"\r\n";
if (!focal.empty()) info << L"Focal length: " << focal << L"mm\r\n";
if (!focal35.empty()) info << L"Focal (35mm eq): " << focal35 << L"mm\r\n";
if (!sw.empty()) info << L"Software: " << sw << L"\r\n";
if (make.empty() && model.empty() && date.empty())
info << L"(no EXIF data)\r\n";
} else {
info << L"(could not read image)\r\n";
}
delete img;
if (token) Gdiplus::GdiplusShutdown(token);
::SetWindowTextW(m_hEdit, info.str().c_str());
}
LRESULT CFileInfoView::WndProc(UINT msg, WPARAM wparam, LPARAM lparam)
{
try {
if (msg == WM_SIZE) {
int w = LOWORD(lparam), h = HIWORD(lparam);
if (m_hEdit)
::MoveWindow(m_hEdit, 0, 0, w, h, TRUE);
}
return WndProcDefault(msg, wparam, lparam);
}
catch (const CException& e) {
CString s;
s << e.GetText() << L'\n' << e.GetErrorString();
::MessageBox(nullptr, s, L"Error", MB_ICONERROR);
}
return 0;
}
//////////////////////////////////////////
// CFileInfoContainer
//////////////////////////////////////////
CFileInfoContainer::CFileInfoContainer()
{
SetTabText(L"File Info");
SetDockCaption(L"File Info");
SetView(m_view);
}
LRESULT CFileInfoContainer::WndProc(UINT msg, WPARAM wparam, LPARAM lparam)
{
try { return WndProcDefault(msg, wparam, lparam); }
catch (const CException& e) {
CString s;
s << e.GetText() << L'\n' << e.GetErrorString();
::MessageBox(nullptr, s, L"Error", MB_ICONERROR);
}
return 0;
}
//////////////////////////////////////////
// CDockFileInfo
//////////////////////////////////////////
CDockFileInfo::CDockFileInfo()
{
SetView(m_container);
SetBarWidth(8);
}
LRESULT CDockFileInfo::WndProc(UINT msg, WPARAM wparam, LPARAM lparam)
{
try { return WndProcDefault(msg, wparam, lparam); }
catch (const CException& e) {
CString s;
s << e.GetText() << L'\n' << e.GetErrorString();
::MessageBox(nullptr, s, L"Error", MB_ICONERROR);
}
return 0;
}

View File

@ -0,0 +1,59 @@
#ifndef PM_UI_FILEINFOPANEL_H
#define PM_UI_FILEINFOPANEL_H
#include "stdafx.h"
#include <gdiplus.h>
class CFileInfoView : public CWnd
{
public:
CFileInfoView() = default;
virtual ~CFileInfoView() override = default;
void ShowFileInfo(LPCWSTR path);
void Clear();
protected:
virtual int OnCreate(CREATESTRUCT& cs) override;
virtual LRESULT WndProc(UINT msg, WPARAM wparam, LPARAM lparam) override;
private:
CFileInfoView(const CFileInfoView&) = delete;
CFileInfoView& operator=(const CFileInfoView&) = delete;
HWND m_hEdit = nullptr;
};
class CFileInfoContainer : public CDockContainer
{
public:
CFileInfoContainer();
virtual ~CFileInfoContainer() override = default;
CFileInfoView& GetInfoView() { return m_view; }
protected:
virtual LRESULT WndProc(UINT msg, WPARAM wparam, LPARAM lparam) override;
private:
CFileInfoContainer(const CFileInfoContainer&) = delete;
CFileInfoContainer& operator=(const CFileInfoContainer&) = delete;
CFileInfoView m_view;
};
class CDockFileInfo : public CDocker
{
public:
CDockFileInfo();
virtual ~CDockFileInfo() override = default;
CFileInfoContainer& GetInfoContainer() { return m_container; }
protected:
virtual LRESULT WndProc(UINT msg, WPARAM wparam, LPARAM lparam) override;
private:
CDockFileInfo(const CDockFileInfo&) = delete;
CDockFileInfo& operator=(const CDockFileInfo&) = delete;
CFileInfoContainer m_container;
};
#endif // PM_UI_FILEINFOPANEL_H

View File

@ -75,9 +75,13 @@ STDMETHODIMP CMainFrame::Execute(UINT32 cmdID, UI_EXECUTIONVERB verb,
SwitchSettingsMode(CSettingsView::MODE_RESIZE);
OnResize();
break;
case IDC_CMD_TRANSFORM:
case IDC_CMD_PROMPT:
SwitchSettingsMode(CSettingsView::MODE_TRANSFORM);
OnTransform();
OnPrompt();
break;
case IDC_CMD_RUN:
SwitchSettingsMode(CSettingsView::MODE_TRANSFORM);
OnRun();
break;
case IDC_CMD_PRESETS: OnPresets(); break;
case IDC_CMD_ABOUT: OnHelp(); break;
@ -243,7 +247,6 @@ void CMainFrame::OnInitialUpdate()
m_pDockQueue = static_cast<CDockQueue*>(pDockQ);
m_pDockQueue->GetQueueContainer().SetHideSingleTab(TRUE);
// Log panel docked below the queue
auto pDockL = m_pDockQueue->AddDockedChild(std::make_unique<CDockLog>(),
DS_DOCKED_RIGHT | style, DpiScaleInt(360));
m_pDockLog = static_cast<CDockLog*>(pDockL);
@ -254,6 +257,18 @@ void CMainFrame::OnInitialUpdate()
m_pDockSettings = static_cast<CDockSettings*>(pDockS);
m_pDockSettings->GetSettingsContainer().SetHideSingleTab(TRUE);
// Generated preview (transform mode) below settings
auto pDockGP = m_pDockSettings->AddDockedChild(std::make_unique<CDockGenPreview>(),
DS_DOCKED_BOTTOM | style, DpiScaleInt(200));
m_pDockGenPreview = static_cast<CDockGenPreview*>(pDockGP);
m_pDockGenPreview->GetContainer().SetHideSingleTab(TRUE);
// File Info panel below generated preview
auto pDockFI = m_pDockGenPreview->AddDockedChild(std::make_unique<CDockFileInfo>(),
DS_DOCKED_BOTTOM | style, DpiScaleInt(160));
m_pDockFileInfo = static_cast<CDockFileInfo*>(pDockFI);
m_pDockFileInfo->GetInfoContainer().SetHideSingleTab(TRUE);
DragAcceptFiles(TRUE);
SetWindowText(L"pm-image");
GetStatusBar().SetPartText(0, L"Drop files or use Add Files to begin.");
@ -540,7 +555,21 @@ static HWND CreatePromptDialog(HWND parent, std::wstring& prompt)
return (result == IDOK) ? parent : nullptr;
}
void CMainFrame::OnTransform()
void CMainFrame::OnPrompt()
{
std::wstring prompt = m_lastPrompt;
if (!CreatePromptDialog(GetHwnd(), prompt))
return;
m_lastPrompt = prompt;
if (!prompt.empty()) {
CString s;
s.Format(L"Prompt set: %.60s%s", prompt.c_str(), prompt.size() > 60 ? L"\u2026" : L"");
GetStatusBar().SetPartText(0, s);
LogMessage(s);
}
}
void CMainFrame::OnRun()
{
if (m_processing) {
::MessageBox(GetHwnd(), L"Already processing.", L"pm-image", MB_ICONWARNING);
@ -554,18 +583,13 @@ void CMainFrame::OnTransform()
return;
}
std::wstring prompt = m_lastPrompt;
if (!CreatePromptDialog(GetHwnd(), prompt))
return;
if (prompt.empty()) {
::MessageBox(GetHwnd(), L"Prompt cannot be empty.", L"pm-image", MB_ICONWARNING);
return;
if (m_lastPrompt.empty()) {
OnPrompt();
if (m_lastPrompt.empty()) return;
}
m_lastPrompt = prompt;
std::string promptUtf8 = wide_to_utf8(prompt);
std::string promptUtf8 = wide_to_utf8(m_lastPrompt);
// Resolve API key
std::string api_key;
const char* env_key = std::getenv("IMAGE_TRANSFORM_GOOGLE_API_KEY");
if (env_key && env_key[0] != '\0') api_key = env_key;
@ -618,11 +642,17 @@ void CMainFrame::OnTransform()
if (result.ok) {
++ok;
::PostMessage(hwnd, UWM_TRANSFORM_PROGRESS, (WPARAM)idx, 2);
// Notify main thread about generated file
std::wstring wout = utf8_to_wide_mf(result.output_path);
auto* ws = new wchar_t[wout.size() + 1];
wcscpy_s(ws, wout.size() + 1, wout.c_str());
::PostMessage(hwnd, UWM_GENERATED_FILE, (WPARAM)ws, 0);
// Send both source path and generated path as a pair
std::wstring wsrc = std::wstring(input.begin(), input.end());
std::wstring wout;
int n = MultiByteToWideChar(CP_UTF8, 0, result.output_path.c_str(),
(int)result.output_path.size(), nullptr, 0);
if (n > 0) { wout.resize(n); MultiByteToWideChar(CP_UTF8, 0,
result.output_path.c_str(), (int)result.output_path.size(), wout.data(), n); }
auto* pair = new std::pair<std::wstring, std::wstring>(wsrc, wout);
::PostMessage(hwnd, UWM_GENERATED_FILE, (WPARAM)pair, 0);
} else {
++fail;
::PostMessage(hwnd, UWM_TRANSFORM_PROGRESS, (WPARAM)idx, 3);
@ -723,17 +753,45 @@ LRESULT CMainFrame::OnLogMessage(WPARAM wparam)
LRESULT CMainFrame::OnGeneratedFile(WPARAM wparam)
{
auto* ws = reinterpret_cast<wchar_t*>(wparam);
if (ws && m_pDockQueue) {
auto* pair = reinterpret_cast<std::pair<std::wstring, std::wstring>*>(wparam);
if (pair && m_pDockQueue) {
m_generatedMap[pair->first] = pair->second;
auto& lv = m_pDockQueue->GetQueueContainer().GetListView();
int idx = lv.AddFile(CString(ws));
int idx = lv.AddFile(CString(pair->second.c_str()));
lv.SetItemStatus(idx, L"\u2728 Generated");
LogMessage(CString(L"Generated: ") + ws);
delete[] ws;
LogMessage(CString(L"Generated: ") + pair->second.c_str());
delete pair;
}
return 0;
}
void CMainFrame::UpdateFileInfoForSelection(int idx)
{
if (!m_pDockQueue) return;
CString path = m_pDockQueue->GetQueueContainer().GetListView().GetItemPath(idx);
if (path.IsEmpty()) return;
// Update file info panel
if (m_pDockFileInfo)
m_pDockFileInfo->GetInfoContainer().GetInfoView().ShowFileInfo(path.c_str());
// In transform mode, check if a generated version exists and show it
if (m_pDockGenPreview && m_pDockSettings) {
auto& sv = m_pDockSettings->GetSettingsContainer().GetSettingsView();
if (sv.GetMode() == CSettingsView::MODE_TRANSFORM) {
std::wstring srcKey(path.c_str());
auto it = m_generatedMap.find(srcKey);
auto& gp = m_pDockGenPreview->GetContainer().GetPreview();
if (it != m_generatedMap.end()) {
gp.LoadPicture(it->second.c_str());
} else {
gp.ClearPicture();
}
}
}
}
// ── Presets ─────────────────────────────────────────────
void CMainFrame::LoadPresets()
@ -938,6 +996,7 @@ LRESULT CMainFrame::WndProc(UINT msg, WPARAM wparam, LPARAM lparam)
CString path = m_pDockQueue->GetQueueContainer().GetListView().GetItemPath(idx);
if (!path.IsEmpty())
m_view.LoadPicture(path.c_str());
UpdateFileInfoForSelection(idx);
}
return 0;
}

View File

@ -5,9 +5,11 @@
#include "FileQueue.h"
#include "SettingsPanel.h"
#include "LogPanel.h"
#include "FileInfoPanel.h"
#include "Resource.h"
#include "core/transform.hpp"
#include <nlohmann/json.hpp>
#include <map>
struct PromptPreset {
std::string name;
@ -43,10 +45,12 @@ private:
void OnAddFolder();
void OnClearQueue();
void OnResize();
void OnTransform();
void OnPrompt();
void OnRun();
void OnExit();
void OnPresets();
void SwitchSettingsMode(CSettingsView::Mode mode);
void UpdateFileInfoForSelection(int idx);
void InvalidateToggle(UINT32 cmdID);
bool IsToggleSelected(UINT32 cmdID) const;
@ -76,6 +80,9 @@ private:
CDockQueue* m_pDockQueue = nullptr;
CDockSettings* m_pDockSettings = nullptr;
CDockLog* m_pDockLog = nullptr;
CDockFileInfo* m_pDockFileInfo = nullptr;
CDockGenPreview* m_pDockGenPreview = nullptr;
std::thread m_worker;
bool m_processing = false;
@ -89,6 +96,9 @@ private:
// Prompt presets
std::vector<PromptPreset> m_presets;
std::string m_settingsPath;
// Source → generated file mapping
std::map<std::wstring, std::wstring> m_generatedMap;
};
#endif // PM_UI_MAINFRM_H

View File

@ -90,26 +90,44 @@
<String Id="4131">Presets</String>
</Command.LabelTitle>
</Command>
<Command Name="cmdGroupTransform" Id="411">
<Command Name="cmdGroupPrompt" Id="414">
<Command.LabelTitle>
<String Id="4111">Transform</String>
<String Id="4141">Prompt</String>
</Command.LabelTitle>
</Command>
<Command Name="cmdTransform" Symbol="IDC_CMD_TRANSFORM" Id="310">
<Command Name="cmdGroupRun" Id="411">
<Command.LabelTitle>
<String Id="3101">Transform</String>
<String Id="4111">Run</String>
</Command.LabelTitle>
</Command>
<Command Name="cmdPrompt" Symbol="IDC_CMD_PROMPT" Id="311">
<Command.LabelTitle>
<String Id="3111">Prompt</String>
</Command.LabelTitle>
<Command.LargeImages>
<Image Id="3102">res/TransformL.bmp</Image>
<Image Id="3112">res/PromptL.bmp</Image>
</Command.LargeImages>
<Command.SmallImages>
<Image Id="3103">res/TransformS.bmp</Image>
<Image Id="3113">res/PromptS.bmp</Image>
</Command.SmallImages>
</Command>
<Command Name="cmdRun" Symbol="IDC_CMD_RUN" Id="312">
<Command.LabelTitle>
<String Id="3121">Run</String>
</Command.LabelTitle>
<Command.LargeImages>
<Image Id="3122">res/RunL.bmp</Image>
</Command.LargeImages>
<Command.SmallImages>
<Image Id="3123">res/RunS.bmp</Image>
</Command.SmallImages>
</Command>
<!-- AI settings dropdown commands -->
<Command Name="cmdModelSelect" Symbol="IDC_CMD_MODEL_SELECT" Id="320">
<Command.LabelTitle><String Id="3200">Model</String></Command.LabelTitle>
<Command.LargeImages><Image Id="3201">res/ModelL.bmp</Image></Command.LargeImages>
<Command.SmallImages><Image Id="3202">res/ModelS.bmp</Image></Command.SmallImages>
</Command>
<Command Name="cmdModelPro" Symbol="IDC_CMD_MODEL_PRO" Id="321">
<Command.LabelTitle><String Id="3210">Gemini 3 Pro Image</String></Command.LabelTitle>
@ -120,6 +138,8 @@
<Command Name="cmdAspectSelect" Symbol="IDC_CMD_ASPECT_SELECT" Id="325">
<Command.LabelTitle><String Id="3250">Aspect</String></Command.LabelTitle>
<Command.LargeImages><Image Id="3251">res/AspectL.bmp</Image></Command.LargeImages>
<Command.SmallImages><Image Id="3252">res/AspectS.bmp</Image></Command.SmallImages>
</Command>
<Command Name="cmdAspectAuto" Symbol="IDC_CMD_ASPECT_AUTO" Id="326">
<Command.LabelTitle><String Id="3260">(auto)</String></Command.LabelTitle>
@ -142,6 +162,8 @@
<Command Name="cmdSizeSelect" Symbol="IDC_CMD_SIZE_SELECT" Id="335">
<Command.LabelTitle><String Id="3350">Size</String></Command.LabelTitle>
<Command.LargeImages><Image Id="3351">res/SizeL.bmp</Image></Command.LargeImages>
<Command.SmallImages><Image Id="3352">res/SizeS.bmp</Image></Command.SmallImages>
</Command>
<Command Name="cmdSizeDefault" Symbol="IDC_CMD_SIZE_DEFAULT" Id="336">
<Command.LabelTitle><String Id="3360">(default)</String></Command.LabelTitle>
@ -158,6 +180,8 @@
<Command Name="cmdPresets" Symbol="IDC_CMD_PRESETS" Id="345">
<Command.LabelTitle><String Id="3450">Presets</String></Command.LabelTitle>
<Command.LargeImages><Image Id="3451">res/PresetsL.bmp</Image></Command.LargeImages>
<Command.SmallImages><Image Id="3452">res/PresetsS.bmp</Image></Command.SmallImages>
</Command>
<!-- Misc -->
@ -212,12 +236,12 @@
<ScalingPolicy>
<ScalingPolicy.IdealSizes>
<Scale Group="cmdGroupAISettings" Size="Large" />
<Scale Group="cmdGroupPresets" Size="Large" />
<Scale Group="cmdGroupTransform" Size="Large" />
<Scale Group="cmdGroupPrompt" Size="Large" />
<Scale Group="cmdGroupRun" Size="Large" />
</ScalingPolicy.IdealSizes>
<Scale Group="cmdGroupAISettings" Size="Medium" />
<Scale Group="cmdGroupPresets" Size="Popup" />
<Scale Group="cmdGroupTransform" Size="Popup" />
<Scale Group="cmdGroupPrompt" Size="Popup" />
<Scale Group="cmdGroupRun" Size="Popup" />
</ScalingPolicy>
</Tab.ScalingPolicy>
<Group CommandName="cmdGroupAISettings" SizeDefinition="ThreeButtons">
@ -246,11 +270,12 @@
</MenuGroup>
</DropDownButton>
</Group>
<Group CommandName="cmdGroupPresets" SizeDefinition="OneButton">
<Group CommandName="cmdGroupPrompt" SizeDefinition="TwoButtons">
<Button CommandName="cmdPrompt" />
<Button CommandName="cmdPresets" />
</Group>
<Group CommandName="cmdGroupTransform" SizeDefinition="OneButton">
<Button CommandName="cmdTransform" />
<Group CommandName="cmdGroupRun" SizeDefinition="OneButton">
<Button CommandName="cmdRun" />
</Group>
</Tab>
</Ribbon.Tabs>

View File

@ -36,20 +36,30 @@
#define cmdGroupAISettings_LabelTitle_RESID 4121
#define cmdGroupPresets 413
#define cmdGroupPresets_LabelTitle_RESID 4131
#define cmdGroupTransform 411
#define cmdGroupTransform_LabelTitle_RESID 4111
#define IDC_CMD_TRANSFORM 310
#define IDC_CMD_TRANSFORM_LabelTitle_RESID 3101
#define IDC_CMD_TRANSFORM_SmallImages_RESID 3103
#define IDC_CMD_TRANSFORM_LargeImages_RESID 3102
#define cmdGroupPrompt 414
#define cmdGroupPrompt_LabelTitle_RESID 4141
#define cmdGroupRun 411
#define cmdGroupRun_LabelTitle_RESID 4111
#define IDC_CMD_PROMPT 311
#define IDC_CMD_PROMPT_LabelTitle_RESID 3111
#define IDC_CMD_PROMPT_SmallImages_RESID 3113
#define IDC_CMD_PROMPT_LargeImages_RESID 3112
#define IDC_CMD_RUN 312
#define IDC_CMD_RUN_LabelTitle_RESID 3121
#define IDC_CMD_RUN_SmallImages_RESID 3123
#define IDC_CMD_RUN_LargeImages_RESID 3122
#define IDC_CMD_MODEL_SELECT 320
#define IDC_CMD_MODEL_SELECT_LabelTitle_RESID 3200
#define IDC_CMD_MODEL_SELECT_SmallImages_RESID 3202
#define IDC_CMD_MODEL_SELECT_LargeImages_RESID 3201
#define IDC_CMD_MODEL_PRO 321
#define IDC_CMD_MODEL_PRO_LabelTitle_RESID 3210
#define IDC_CMD_MODEL_FLASH 322
#define IDC_CMD_MODEL_FLASH_LabelTitle_RESID 3220
#define IDC_CMD_ASPECT_SELECT 325
#define IDC_CMD_ASPECT_SELECT_LabelTitle_RESID 3250
#define IDC_CMD_ASPECT_SELECT_SmallImages_RESID 3252
#define IDC_CMD_ASPECT_SELECT_LargeImages_RESID 3251
#define IDC_CMD_ASPECT_AUTO 326
#define IDC_CMD_ASPECT_AUTO_LabelTitle_RESID 3260
#define IDC_CMD_ASPECT_1_1 327
@ -64,6 +74,8 @@
#define IDC_CMD_ASPECT_3_2_LabelTitle_RESID 3310
#define IDC_CMD_SIZE_SELECT 335
#define IDC_CMD_SIZE_SELECT_LabelTitle_RESID 3350
#define IDC_CMD_SIZE_SELECT_SmallImages_RESID 3352
#define IDC_CMD_SIZE_SELECT_LargeImages_RESID 3351
#define IDC_CMD_SIZE_DEFAULT 336
#define IDC_CMD_SIZE_DEFAULT_LabelTitle_RESID 3360
#define IDC_CMD_SIZE_1K 337
@ -74,6 +86,8 @@
#define IDC_CMD_SIZE_4K_LabelTitle_RESID 3390
#define IDC_CMD_PRESETS 345
#define IDC_CMD_PRESETS_LabelTitle_RESID 3450
#define IDC_CMD_PRESETS_SmallImages_RESID 3452
#define IDC_CMD_PRESETS_LargeImages_RESID 3451
#define cmdAppMenu 710
#define IDC_RIBBONHELP 700
#define IDC_QAT 701

View File

@ -74,21 +74,35 @@ END
STRINGTABLE
BEGIN
cmdGroupTransform_LabelTitle_RESID L"Transform" /* LabelTitle cmdGroupTransform_LabelTitle_RESID: (null) */
cmdGroupPrompt_LabelTitle_RESID L"Prompt" /* LabelTitle cmdGroupPrompt_LabelTitle_RESID: (null) */
END
STRINGTABLE
BEGIN
IDC_CMD_TRANSFORM_LabelTitle_RESID L"Transform" /* LabelTitle IDC_CMD_TRANSFORM_LabelTitle_RESID: (null) */
cmdGroupRun_LabelTitle_RESID L"Run" /* LabelTitle cmdGroupRun_LabelTitle_RESID: (null) */
END
IDC_CMD_TRANSFORM_SmallImages_RESID BITMAP "res\\TransformS.bmp" /* SmallImages IDC_CMD_TRANSFORM_SmallImages_RESID: (null) */
IDC_CMD_TRANSFORM_LargeImages_RESID BITMAP "res\\TransformL.bmp" /* LargeImages IDC_CMD_TRANSFORM_LargeImages_RESID: (null) */
STRINGTABLE
BEGIN
IDC_CMD_PROMPT_LabelTitle_RESID L"Prompt" /* LabelTitle IDC_CMD_PROMPT_LabelTitle_RESID: (null) */
END
IDC_CMD_PROMPT_SmallImages_RESID BITMAP "res\\PromptS.bmp" /* SmallImages IDC_CMD_PROMPT_SmallImages_RESID: (null) */
IDC_CMD_PROMPT_LargeImages_RESID BITMAP "res\\PromptL.bmp" /* LargeImages IDC_CMD_PROMPT_LargeImages_RESID: (null) */
STRINGTABLE
BEGIN
IDC_CMD_RUN_LabelTitle_RESID L"Run" /* LabelTitle IDC_CMD_RUN_LabelTitle_RESID: (null) */
END
IDC_CMD_RUN_SmallImages_RESID BITMAP "res\\RunS.bmp" /* SmallImages IDC_CMD_RUN_SmallImages_RESID: (null) */
IDC_CMD_RUN_LargeImages_RESID BITMAP "res\\RunL.bmp" /* LargeImages IDC_CMD_RUN_LargeImages_RESID: (null) */
STRINGTABLE
BEGIN
IDC_CMD_MODEL_SELECT_LabelTitle_RESID L"Model" /* LabelTitle IDC_CMD_MODEL_SELECT_LabelTitle_RESID: (null) */
END
IDC_CMD_MODEL_SELECT_SmallImages_RESID BITMAP "res\\ModelS.bmp" /* SmallImages IDC_CMD_MODEL_SELECT_SmallImages_RESID: (null) */
IDC_CMD_MODEL_SELECT_LargeImages_RESID BITMAP "res\\ModelL.bmp" /* LargeImages IDC_CMD_MODEL_SELECT_LargeImages_RESID: (null) */
STRINGTABLE
BEGIN
IDC_CMD_MODEL_PRO_LabelTitle_RESID L"Gemini 3 Pro Image" /* LabelTitle IDC_CMD_MODEL_PRO_LabelTitle_RESID: (null) */
@ -104,6 +118,8 @@ BEGIN
IDC_CMD_ASPECT_SELECT_LabelTitle_RESID L"Aspect" /* LabelTitle IDC_CMD_ASPECT_SELECT_LabelTitle_RESID: (null) */
END
IDC_CMD_ASPECT_SELECT_SmallImages_RESID BITMAP "res\\AspectS.bmp" /* SmallImages IDC_CMD_ASPECT_SELECT_SmallImages_RESID: (null) */
IDC_CMD_ASPECT_SELECT_LargeImages_RESID BITMAP "res\\AspectL.bmp" /* LargeImages IDC_CMD_ASPECT_SELECT_LargeImages_RESID: (null) */
STRINGTABLE
BEGIN
IDC_CMD_ASPECT_AUTO_LabelTitle_RESID L"(auto)" /* LabelTitle IDC_CMD_ASPECT_AUTO_LabelTitle_RESID: (null) */
@ -139,6 +155,8 @@ BEGIN
IDC_CMD_SIZE_SELECT_LabelTitle_RESID L"Size" /* LabelTitle IDC_CMD_SIZE_SELECT_LabelTitle_RESID: (null) */
END
IDC_CMD_SIZE_SELECT_SmallImages_RESID BITMAP "res\\SizeS.bmp" /* SmallImages IDC_CMD_SIZE_SELECT_SmallImages_RESID: (null) */
IDC_CMD_SIZE_SELECT_LargeImages_RESID BITMAP "res\\SizeL.bmp" /* LargeImages IDC_CMD_SIZE_SELECT_LargeImages_RESID: (null) */
STRINGTABLE
BEGIN
IDC_CMD_SIZE_DEFAULT_LabelTitle_RESID L"(default)" /* LabelTitle IDC_CMD_SIZE_DEFAULT_LabelTitle_RESID: (null) */
@ -164,4 +182,6 @@ BEGIN
IDC_CMD_PRESETS_LabelTitle_RESID L"Presets" /* LabelTitle IDC_CMD_PRESETS_LabelTitle_RESID: (null) */
END
IDC_CMD_PRESETS_SmallImages_RESID BITMAP "res\\PresetsS.bmp" /* SmallImages IDC_CMD_PRESETS_SmallImages_RESID: (null) */
IDC_CMD_PRESETS_LargeImages_RESID BITMAP "res\\PresetsL.bmp" /* LargeImages IDC_CMD_PRESETS_LargeImages_RESID: (null) */
APPLICATION_RIBBON UIFILE "C:\\Users\\zx\\Desktop\\polymech\\polymech-mono\\packages\\media\\cpp\\src\\win\\ui_next\\RibbonUI.bml"

View File

@ -46,4 +46,28 @@ Convert-PngToBmp "$resDir\32x32_0060\arrow_out.png" "$resDir\ResizeL.bmp" 32
Convert-PngToBmp "$resDir\32x32_0700\paintcan.png" "$resDir\TransformL.bmp" 32
Convert-PngToBmp "$resDir\16x16_0700\paintbrush.png" "$resDir\TransformS.bmp" 16
# Model -> cog.png
Convert-PngToBmp "$resDir\32x32_0240\cog.png" "$resDir\ModelL.bmp" 32
Convert-PngToBmp "$resDir\16x16_0240\cog.png" "$resDir\ModelS.bmp" 16
# Aspect -> shape_handles.png
Convert-PngToBmp "$resDir\32x32_0800\shape_handles.png" "$resDir\AspectL.bmp" 32
Convert-PngToBmp "$resDir\16x16_0800\shape_handles.png" "$resDir\AspectS.bmp" 16
# Size -> magnifier_zoom_in.png
Convert-PngToBmp "$resDir\32x32_0560\magnifier_zoom_in.png" "$resDir\SizeL.bmp" 32
Convert-PngToBmp "$resDir\16x16_0560\magnifier_zoom_in.png" "$resDir\SizeS.bmp" 16
# Presets -> book.png
Convert-PngToBmp "$resDir\32x32_0100\book.png" "$resDir\PresetsL.bmp" 32
Convert-PngToBmp "$resDir\16x16_0100\book.png" "$resDir\PresetsS.bmp" 16
# Prompt -> comment_edit.png
Convert-PngToBmp "$resDir\32x32_0260\comment_edit.png" "$resDir\PromptL.bmp" 32
Convert-PngToBmp "$resDir\16x16_0260\comment_edit.png" "$resDir\PromptS.bmp" 16
# Run -> control_play_blue.png
Convert-PngToBmp "$resDir\32x32_0300\control_play_blue.png" "$resDir\RunL.bmp" 32
Convert-PngToBmp "$resDir\16x16_0300\control_play_blue.png" "$resDir\RunS.bmp" 16
Write-Output "Done."

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB