feat: Implement screenshot capture functionality for specific regions and active windows in screenshot_utils

- Added CaptureHarnessScreenshotRegion function to capture a specified region of the renderer output.
- Introduced CaptureActiveWindow and CaptureWindowByName functions to capture screenshots of the currently active ImGui window or a specific window by name.
- Updated screenshot_utils.h to include new CaptureRegion struct and corresponding function declarations.
- Enhanced EditorManager to utilize the new capture modes based on user selection in the AgentChatWidget.
This commit is contained in:
scawful
2025-10-04 17:08:36 -04:00
parent 5f2c72bfc7
commit f182833afe
6 changed files with 282 additions and 12 deletions

View File

@@ -27,8 +27,8 @@ absl::Time ParseTimestamp(const Json& value) {
return absl::Now();
}
absl::Time parsed;
if (absl::ParseTime(absl::RFC3339_full, value.get<std::string>(),
absl::UTCTimeZone(), &parsed)) {
if (absl::ParseTime(absl::RFC3339_full, value.get<std::string>(), &parsed,
nullptr)) {
return parsed;
}
return absl::Now();

View File

@@ -484,6 +484,9 @@ void AgentChatWidget::Draw() {
}
EnsureHistoryLoaded();
// Poll for new messages in collaborative sessions
PollSharedHistory();
ImGui::Begin(title_.c_str(), &active_);
RenderHistory();
@@ -668,8 +671,31 @@ void AgentChatWidget::RenderMultimodalPanel() {
bool can_capture = static_cast<bool>(multimodal_callbacks_.capture_snapshot);
bool can_send = static_cast<bool>(multimodal_callbacks_.send_to_gemini);
// Capture mode selection
ImGui::Text("Capture Mode:");
ImGui::RadioButton("Full Window",
reinterpret_cast<int*>(&multimodal_state_.capture_mode),
static_cast<int>(CaptureMode::kFullWindow));
ImGui::SameLine();
ImGui::RadioButton("Active Editor",
reinterpret_cast<int*>(&multimodal_state_.capture_mode),
static_cast<int>(CaptureMode::kActiveEditor));
ImGui::SameLine();
ImGui::RadioButton("Specific Window",
reinterpret_cast<int*>(&multimodal_state_.capture_mode),
static_cast<int>(CaptureMode::kSpecificWindow));
// If specific window mode, show input for window name
if (multimodal_state_.capture_mode == CaptureMode::kSpecificWindow) {
ImGui::InputText("Window Name", multimodal_state_.specific_window_buffer,
IM_ARRAYSIZE(multimodal_state_.specific_window_buffer));
ImGui::TextDisabled("Examples: Overworld Editor, Dungeon Editor, Sprite Editor");
}
ImGui::Separator();
if (!can_capture) ImGui::BeginDisabled();
if (ImGui::Button("Capture Map Snapshot")) {
if (ImGui::Button("Capture Snapshot")) {
if (multimodal_callbacks_.capture_snapshot) {
std::filesystem::path captured_path;
absl::Status status =
@@ -822,6 +848,10 @@ void AgentChatWidget::SwitchToSharedHistory(const std::string& session_id) {
// Load shared history
EnsureHistoryLoaded();
// Initialize polling state
last_known_history_size_ = agent_service_.GetHistory().size();
last_shared_history_poll_ = absl::Now();
if (toast_manager_) {
toast_manager_->Show(
absl::StrFormat("Switched to shared chat history for session %s",
@@ -849,5 +879,44 @@ void AgentChatWidget::SwitchToLocalHistory() {
}
}
void AgentChatWidget::PollSharedHistory() {
if (!collaboration_state_.active) {
return; // Not in a collaborative session
}
const absl::Time now = absl::Now();
// Poll every 2 seconds
if (now - last_shared_history_poll_ < absl::Seconds(2)) {
return;
}
last_shared_history_poll_ = now;
// Check if the shared history file has been updated
auto result = AgentChatHistoryCodec::Load(history_path_);
if (!result.ok()) {
return; // File might not exist yet or be temporarily locked
}
const size_t new_size = result->history.size();
// If history has grown, reload it
if (new_size > last_known_history_size_) {
const size_t new_messages = new_size - last_known_history_size_;
agent_service_.ReplaceHistory(std::move(result->history));
last_history_size_ = new_size;
last_known_history_size_ = new_size;
if (toast_manager_) {
toast_manager_->Show(
absl::StrFormat("📬 %zu new message%s from collaborators",
new_messages, new_messages == 1 ? "" : "s"),
ToastType::kInfo, 3.0f);
}
}
}
} // namespace editor
} // namespace yaze

View File

@@ -62,11 +62,6 @@ class AgentChatWidget {
bool* active() { return &active_; }
bool is_active() const { return active_; }
void set_active(bool active) { active_ = active; }
CaptureMode capture_mode() const { return multimodal_state_.capture_mode; }
const char* specific_window_name() const {
return multimodal_state_.specific_window_buffer;
}
public:
struct CollaborationState {
@@ -91,10 +86,19 @@ public:
char specific_window_buffer[128] = {};
};
void EnsureHistoryLoaded();
void PersistHistory();
// Accessors for capture settings
CaptureMode capture_mode() const { return multimodal_state_.capture_mode; }
const char* specific_window_name() const {
return multimodal_state_.specific_window_buffer;
}
// Collaboration history management (public so EditorManager can call them)
void SwitchToSharedHistory(const std::string& session_id);
void SwitchToLocalHistory();
private:
void EnsureHistoryLoaded();
void PersistHistory();
void RenderHistory();
void RenderMessage(const cli::agent::ChatMessage& msg, int index);
void RenderProposalQuickActions(const cli::agent::ChatMessage& msg,