340 lines
10 KiB
C++
340 lines
10 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "backends/imgui/IconsMaterialSymbols.h"
|
|
#include "backends/imgui/imgui_utils.h"
|
|
#include "director/director.h"
|
|
#include "director/debugger/dt-internal.h"
|
|
|
|
#include "director/cast.h"
|
|
#include "director/castmember/bitmap.h"
|
|
#include "director/castmember/text.h"
|
|
#include "director/castmember/shape.h"
|
|
#include "director/castmember/richtext.h"
|
|
#include "director/castmember/script.h"
|
|
#include "director/movie.h"
|
|
#include "director/types.h"
|
|
#include "director/window.h"
|
|
|
|
namespace Director {
|
|
namespace DT {
|
|
|
|
static const char *toString(ScriptType scriptType) {
|
|
static const char *scriptTypes[] = {
|
|
"Score",
|
|
"Cast",
|
|
"Movie",
|
|
"Event",
|
|
"Test",
|
|
"???",
|
|
"???",
|
|
"Parent",
|
|
};
|
|
if (scriptType < 0 || scriptType > kMaxScriptType)
|
|
return "???";
|
|
return scriptTypes[(int)scriptType];
|
|
}
|
|
|
|
static const char *toIcon(CastType castType) {
|
|
static const char *castTypes[] = {
|
|
"", // Empty
|
|
ICON_MS_BACKGROUND_DOT_LARGE, // Bitmap
|
|
ICON_MS_THEATERS, // FilmLoop
|
|
ICON_MS_MATCH_CASE, // Text
|
|
ICON_MS_PALETTE, // Palette
|
|
ICON_MS_IMAGESMODE, // Picture
|
|
ICON_MS_VOLUME_UP, // Sound
|
|
ICON_MS_SLAB_SERIF, // Button
|
|
ICON_MS_SHAPES, // Shape
|
|
ICON_MS_MOVIE, // Movie
|
|
ICON_MS_ANIMATED_IMAGES, // DigitalVideo
|
|
ICON_MS_FORMS_APPS_SCRIPT, // Script
|
|
ICON_MS_BRAND_FAMILY, // RTE
|
|
"?", // ???
|
|
ICON_MS_TRANSITION_FADE}; // Transition
|
|
if (castType < 0 || castType > kCastTransition)
|
|
return "";
|
|
return castTypes[(int)castType];
|
|
}
|
|
|
|
const char *toString(CastType castType) {
|
|
static const char *castTypes[] = {
|
|
"Empty",
|
|
"Bitmap",
|
|
"FilmLoop",
|
|
"Text",
|
|
"Palette",
|
|
"Picture",
|
|
"Sound",
|
|
"Button",
|
|
"Shape",
|
|
"Movie",
|
|
"DigitalVideo",
|
|
"Script",
|
|
"RTE",
|
|
"???",
|
|
"Transition"};
|
|
if (castType < 0 || castType > kCastTransition)
|
|
return "???";
|
|
return castTypes[(int)castType];
|
|
}
|
|
|
|
Common::String getDisplayName(CastMember *castMember) {
|
|
const CastMemberInfo *castMemberInfo = castMember->getInfo();
|
|
Common::String name(castMemberInfo ? castMemberInfo->name : "");
|
|
if (!name.empty())
|
|
return name;
|
|
if (castMember->_type == kCastText) {
|
|
TextCastMember *textCastMember = (TextCastMember *)castMember;
|
|
return textCastMember->getText();
|
|
}
|
|
return Common::String::format("%u", castMember->getID());
|
|
}
|
|
|
|
void showCast() {
|
|
if (!_state->_w.cast)
|
|
return;
|
|
|
|
ImGui::SetNextWindowPos(ImVec2(20, 160), ImGuiCond_FirstUseEver);
|
|
ImGui::SetNextWindowSize(ImVec2(480, 480), ImGuiCond_FirstUseEver);
|
|
|
|
if (ImGui::Begin("Cast", &_state->_w.cast)) {
|
|
Window *selectedWindow = windowListCombo(&_state->_castWindow);
|
|
|
|
// display a toolbar with: grid/list/filters buttons + name filter
|
|
ImGuiEx::toggleButton(ICON_MS_LIST, &_state->_cast._listView);
|
|
ImGui::SetItemTooltip("List");
|
|
ImGui::SameLine();
|
|
ImGuiEx::toggleButton(ICON_MS_GRID_VIEW, &_state->_cast._listView, true);
|
|
ImGui::SetItemTooltip("Grid");
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button(ICON_MS_FILTER_ALT)) {
|
|
ImGui::OpenPopup("filters_popup");
|
|
}
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::BeginPopup("filters_popup")) {
|
|
ImGui::CheckboxFlags("All", &_state->_cast._typeFilter, 0x7FFF);
|
|
ImGui::Separator();
|
|
for (int i = 0; i <= 14; i++) {
|
|
ImGui::PushID(i);
|
|
Common::String option(Common::String::format("%s %s", toIcon((CastType)i), toString((CastType)i)));
|
|
ImGui::CheckboxFlags(option.c_str(), &_state->_cast._typeFilter, 1 << i);
|
|
ImGui::PopID();
|
|
}
|
|
ImGui::EndPopup();
|
|
}
|
|
_state->_cast._nameFilter.Draw();
|
|
ImGui::Separator();
|
|
|
|
// display a list or a grid
|
|
const float sliderHeight = _state->_cast._listView ? 0.f : 38.f;
|
|
const ImVec2 childsize = ImGui::GetContentRegionAvail();
|
|
Movie *movie = selectedWindow->getCurrentMovie();
|
|
ImGui::BeginChild("##cast", ImVec2(childsize.x, childsize.y - sliderHeight));
|
|
if (_state->_cast._listView) {
|
|
if (ImGui::BeginTable("Resources", 5, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg)) {
|
|
ImGui::TableSetupColumn("Name", 0, 120.f);
|
|
ImGui::TableSetupColumn("#", 0, 20.f);
|
|
ImGui::TableSetupColumn("Script", 0, 80.f);
|
|
ImGui::TableSetupColumn("Type", 0, 80.f);
|
|
ImGui::TableSetupColumn("Preview", ImGuiTableColumnFlags_WidthStretch, 50.f);
|
|
ImGui::TableHeadersRow();
|
|
|
|
for (auto it : *movie->getCasts()) {
|
|
Cast *cast = it._value;
|
|
if (!cast->_loadedCast)
|
|
continue;
|
|
|
|
for (auto castMember : *cast->_loadedCast) {
|
|
if (!castMember._value->isLoaded())
|
|
continue;
|
|
|
|
Common::String name(getDisplayName(castMember._value));
|
|
if (!_state->_cast._nameFilter.PassFilter(name.c_str()))
|
|
continue;
|
|
if ((castMember._value->_type != kCastTypeAny) && !(_state->_cast._typeFilter & (1 << (int)castMember._value->_type)))
|
|
continue;
|
|
|
|
ImGui::TableNextRow();
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%s %s", toIcon(castMember._value->_type), name.c_str());
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%d", castMember._key);
|
|
|
|
ImGui::TableNextColumn();
|
|
if (castMember._value->_type == CastType::kCastLingoScript) {
|
|
ScriptCastMember *scriptMember = (ScriptCastMember *)castMember._value;
|
|
ImGui::Text("%s", toString(scriptMember->_scriptType));
|
|
}
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%s", toString(castMember._value->_type));
|
|
|
|
ImGui::TableNextColumn();
|
|
float columnWidth = ImGui::GetColumnWidth();
|
|
|
|
ImGuiImage imgID = {};
|
|
switch (castMember._value->_type) {
|
|
case kCastBitmap:
|
|
{
|
|
imgID = getImageID(castMember._value);
|
|
if (imgID.id) {
|
|
float offsetX = (columnWidth - 32.f) * 0.5f;
|
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + offsetX);
|
|
showImage(imgID, name.c_str(), 32.f);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kCastText:
|
|
case kCastRichText:
|
|
case kCastButton:
|
|
{
|
|
imgID = getTextID(castMember._value);
|
|
if (imgID.id) {
|
|
float offsetX = (columnWidth - 32.f) * 0.5f;
|
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + offsetX);
|
|
showImage(imgID, name.c_str(), 32.f);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kCastShape:
|
|
{
|
|
imgID = getShapeID(castMember._value);
|
|
if (imgID.id) {
|
|
float offsetX = (columnWidth - 32.f) * 0.5f;
|
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + offsetX);
|
|
showImage(imgID, name.c_str(), 32.f);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
ImGui::EndTable();
|
|
}
|
|
} else {
|
|
const float thumbnailSize = (float)_state->_cast._thumbnailSize;
|
|
const float contentWidth = ImGui::GetContentRegionAvail().x;
|
|
int columns = contentWidth / (thumbnailSize + 8.f);
|
|
columns = columns < 1 ? 1 : columns;
|
|
if (ImGui::BeginTable("Cast", columns)) {
|
|
for (auto it : *movie->getCasts()) {
|
|
const Cast *cast = it._value;
|
|
if (!cast->_loadedCast)
|
|
continue;
|
|
|
|
for (auto castMember : *cast->_loadedCast) {
|
|
if (!castMember._value->isLoaded())
|
|
continue;
|
|
|
|
Common::String name(getDisplayName(castMember._value));
|
|
if (!_state->_cast._nameFilter.PassFilter(name.c_str()))
|
|
continue;
|
|
if ((castMember._value->_type != kCastTypeAny) && !(_state->_cast._typeFilter & (1 << (int)castMember._value->_type)))
|
|
continue;
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::BeginGroup();
|
|
const ImVec2 textSize = ImGui::CalcTextSize(name.c_str());
|
|
float textWidth = textSize.x;
|
|
float textHeight = textSize.y;
|
|
if (textWidth > thumbnailSize) {
|
|
textWidth = thumbnailSize;
|
|
textHeight *= (textSize.x / textWidth);
|
|
}
|
|
|
|
ImGuiImage imgID = {};
|
|
switch (castMember._value->_type) {
|
|
case kCastBitmap:
|
|
{
|
|
imgID = getImageID(castMember._value);
|
|
if (imgID.id) {
|
|
showImage(imgID, name.c_str(), thumbnailSize);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kCastText:
|
|
case kCastRichText:
|
|
case kCastButton:
|
|
{
|
|
imgID = getTextID(castMember._value);
|
|
if (imgID.id) {
|
|
showImage(imgID, name.c_str(), thumbnailSize);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kCastShape:
|
|
{
|
|
imgID = getShapeID(castMember._value);
|
|
if (imgID.id) {
|
|
showImage(imgID, name.c_str(), thumbnailSize);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!imgID.id) {
|
|
ImGui::PushID(castMember._key);
|
|
ImGui::InvisibleButton("##canvas", ImVec2(thumbnailSize, thumbnailSize));
|
|
ImGui::PopID();
|
|
const ImVec2 p0 = ImGui::GetItemRectMin();
|
|
const ImVec2 p1 = ImGui::GetItemRectMax();
|
|
ImGui::PushClipRect(p0, p1, true);
|
|
ImDrawList *draw_list = ImGui::GetWindowDrawList();
|
|
draw_list->AddRect(p0, p1, IM_COL32_WHITE);
|
|
const ImVec2 pos = p0 + ImVec2((thumbnailSize - textWidth) * 0.5f, (thumbnailSize - textHeight) * 0.5f);
|
|
draw_list->AddText(nullptr, 0.f, pos, IM_COL32_WHITE, name.c_str(), 0, thumbnailSize);
|
|
draw_list->AddText(nullptr, 0.f, p1 - ImVec2(16, 16), IM_COL32_WHITE, toIcon(castMember._value->_type));
|
|
ImGui::PopClipRect();
|
|
}
|
|
ImGui::EndGroup();
|
|
}
|
|
}
|
|
ImGui::EndTable();
|
|
}
|
|
}
|
|
ImGui::EndChild();
|
|
|
|
// in the footer display a slider for the grid view: thumbnail size
|
|
if (!_state->_cast._listView) {
|
|
ImGui::Spacing();
|
|
ImGui::Separator();
|
|
ImGui::Spacing();
|
|
ImGui::SliderInt("Thumbnail Size", &_state->_cast._thumbnailSize, 32, 256);
|
|
}
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
} // namespace DT
|
|
} // namespace Director
|