2 * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton)
4 * ShapeFusion is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * ShapeFusion is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with ShapeFusion; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "ShapesView.h"
21 #include "ShapesDocument.h"
22 #include "../DefaultNames.h"
23 #include "utilities.h"
24 #include <wx/wfstream.h>
26 #define INT_TO_WXSTRING(a) wxString::Format(wxT("%d"), a)
28 BEGIN_EVENT_TABLE(ShapesView, wxView)
29 EVT_MENU(EDIT_MENU_COPY, ShapesView::MenuEditCopy)
30 EVT_MENU(EDIT_MENU_DELETE, ShapesView::MenuEditDelete)
31 EVT_MENU(EDIT_MENU_PASTE, ShapesView::MenuEditPaste)
32 EVT_MENU_RANGE(VIEW_MENU_COLORTABLE_0, VIEW_MENU_COLORTABLE_7, ShapesView::MenuViewCT)
33 EVT_MENU_RANGE(VIEW_MENU_TNSIZE_SMALL, VIEW_MENU_TNSIZE_AUTO, ShapesView::MenuViewTNSize)
34 EVT_MENU(VIEW_MENU_TRANSPARENCY, ShapesView::MenuViewTransparency)
35 EVT_MENU(VIEW_MENU_CENTERORIGIN, ShapesView::MenuViewCenterOrigin)
36 EVT_MENU(SHAPES_MENU_ADDCOLORTABLE, ShapesView::MenuShapesAddColorTable)
37 EVT_MENU(SHAPES_MENU_SAVECOLORTABLE, ShapesView::MenuShapesSaveColorTable)
38 EVT_MENU(SHAPES_MENU_SAVECOLORTABLETOPS, ShapesView::MenuShapesSaveColorTable)
39 EVT_MENU(SHAPES_MENU_ADDBITMAP, ShapesView::MenuShapesAddBitmap)
40 EVT_MENU(SHAPES_MENU_EXPORTBITMAP, ShapesView::MenuShapesExportBitmap)
41 EVT_MENU(SHAPES_MENU_EXPORTMASK, ShapesView::MenuShapesExportBitmapMask)
42 EVT_MENU(SHAPES_MENU_EXPORTBITMAPS, ShapesView::MenuShapesExportBitmaps)
43 EVT_MENU(SHAPES_MENU_EXPORTMASKS, ShapesView::MenuShapesExportBitmapMasks)
44 EVT_MENU(SHAPES_MENU_ADDFRAME, ShapesView::MenuShapesNewFrame)
45 EVT_MENU(SHAPES_MENU_ADDSEQUENCE, ShapesView::MenuShapesNewSequence)
46 EVT_MENU(SHAPES_MENU_GENERATEPATCH, ShapesView::MenuShapesGeneratePatch)
47 EVT_MENU(SHAPES_MENU_IMPORTPATCH, ShapesView::MenuShapesImportPatch)
48 EVT_TREE_SEL_CHANGED(-1, ShapesView::OnTreeSelect)
50 EVT_COMMAND(BITMAP_BROWSER, wxEVT_BITMAPBROWSER, ShapesView::OnBitmapSelect)
51 EVT_COMMAND(BITMAP_BROWSER, wxEVT_BITMAPBROWSER_DELETE, ShapesView::BitmapDelete)
52 EVT_COMMAND_RANGE(CB_COLUMN_ORDER, CB_ENABLE_TRANSPARENCY, wxEVT_COMMAND_CHECKBOX_CLICKED, ShapesView::ToggleBitmapCheckboxes)
54 EVT_COMMAND(wxID_ANY, wxEVT_CTBROWSER, ShapesView::OnCTSelect)
55 EVT_COMMAND(wxID_ANY, wxEVT_CTVIEW_SELECTION, ShapesView::CTColorSelect)
56 EVT_COMMAND(wxID_ANY, wxEVT_CTVIEW_COLOR, ShapesView::CTColorChanged)
57 EVT_COMMAND(CB_SELF_LUMINESCENT, wxEVT_COMMAND_CHECKBOX_CLICKED, ShapesView::ToggleSelfLuminCheckbox)
58 EVT_BUTTON(BTN_GRADIENT, ShapesView::MakeCTGradient)
60 EVT_COMMAND(FRAME_BROWSER, wxEVT_FRAMEBROWSER, ShapesView::OnFrameSelect)
61 EVT_COMMAND(FRAME_BROWSER, wxEVT_FRAMEBROWSER_DELETE, ShapesView::FrameDelete)
62 EVT_COMMAND(FRAME_VIEW, wxEVT_FRAMEVIEW_DRAG, ShapesView::OnFramePointDrag)
63 EVT_SPINCTRL(FIELD_BITMAP_INDEX, ShapesView::BitmapIndexSpin)
64 EVT_COMMAND_RANGE(CB_XMIRROR, CB_KEYPOINT, wxEVT_COMMAND_CHECKBOX_CLICKED, ShapesView::ToggleFrameCheckboxes)
65 EVT_TEXT(FIELD_ORIGIN_X, ShapesView::EditFrameFields)
66 EVT_TEXT(FIELD_ORIGIN_Y, ShapesView::EditFrameFields)
67 EVT_TEXT(FIELD_KEY_X, ShapesView::EditFrameFields)
68 EVT_TEXT(FIELD_KEY_Y, ShapesView::EditFrameFields)
69 EVT_TEXT(FIELD_FRAME_SCALEFACTOR, ShapesView::EditFrameFields)
70 EVT_TEXT(FIELD_MIN_LIGHT_INT, ShapesView::EditFrameFields)
72 EVT_TEXT(FIELD_SEQ_NAME, ShapesView::EditSequenceFields)
73 EVT_BUTTON(BTN_DELETE_SEQ, ShapesView::DeleteSequence)
74 EVT_CHOICE(MENU_SEQ_TYPE, ShapesView::EditSequenceType)
75 EVT_TEXT(FIELD_SEQ_FRAMES_PER_VIEW, ShapesView::EditSequenceFields)
76 EVT_TEXT(FIELD_SEQ_TICKS_PER_FRAME, ShapesView::EditSequenceFields)
77 EVT_TEXT(FIELD_SEQ_LOOP_FRAME, ShapesView::EditSequenceFields)
78 EVT_TEXT(FIELD_SEQ_KEY_FRAME, ShapesView::EditSequenceFields)
79 EVT_CHOICE(MENU_SEQ_XFER_MODE, ShapesView::EditSequenceXferMode)
80 EVT_TEXT(FIELD_SEQ_XFER_MODE_PERIOD, ShapesView::EditSequenceFields)
81 EVT_TEXT(FIELD_SEQ_FIRST_FRAME_SND, ShapesView::EditSequenceFields)
82 EVT_TEXT(FIELD_SEQ_KEY_FRAME_SND, ShapesView::EditSequenceFields)
83 EVT_TEXT(FIELD_SEQ_LAST_FRAME_SND, ShapesView::EditSequenceFields)
86 IMPLEMENT_DYNAMIC_CLASS(ShapesView, wxView)
88 ShapesView::ShapesView(void):
89 wxView(), mSelectedColl(-1), mSelectedVers(-1), mSelectedSequence(-1), mViewColorTable(-1)
91 mFrame = (wxFrame *)NULL;
94 ShapesView::~ShapesView(void)
98 bool ShapesView::OnCreate(wxDocument *doc, long WXUNUSED(flags))
100 wxString frameTitle = _T("ShapeFusion : Shapes : ");
102 frameTitle.Append(doc->GetFilename());
103 mFrame = wxGetApp().CreateChildFrame(doc, this, frameTitle, wxPoint(0, 0), wxSize(900, 600));
104 mFrame->SetSizeHints(200, 200);
105 CreateViewMenu(mFrame->GetMenuBar());
106 CreateShapesMenu(mFrame->GetMenuBar());
107 menubar = mFrame->GetMenuBar();
109 // Add everything to panel, so background is same as a dialog
110 main_panel = new wxPanel(mFrame);
113 mainbox = new wxBoxSizer(wxHORIZONTAL);
114 // create the collection tree
115 colltree = new wxTreeCtrl(main_panel, -1, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT);
116 colltree->DeleteAllItems();
117 wxTreeItemId treeroot = colltree->AddRoot(doc->GetFilename());
118 mainbox->Add(colltree, 2, wxEXPAND);
119 // empty space (e.g. what is displayed when selecting the Sequences node)
120 // adding at least a panel is apparently needed to make sizers work
121 dummy_sizer = new wxBoxSizer(wxVERTICAL);
122 wxPanel *dummy_panel = new wxPanel(main_panel);
123 dummy_sizer->Add(dummy_panel, 1, wxEXPAND);
124 mainbox->Add(dummy_sizer, 5, wxEXPAND);
125 // collection section
126 coll_sizer = new wxBoxSizer(wxVERTICAL);
127 coll_text = new wxStaticText(main_panel, -1, wxT("Collection info"));
128 coll_static_box = new wxStaticBox(main_panel, -1, wxT("Collection info"));
129 coll_inner_box = new wxStaticBoxSizer(coll_static_box, wxVERTICAL);
130 coll_inner_box->Add(coll_text, 0, wxALL, 5);
131 coll_sizer->AddStretchSpacer();
132 coll_sizer->Add(coll_inner_box, 0, wxALIGN_CENTER);
133 coll_sizer->AddStretchSpacer();
134 mainbox->Add(coll_sizer, 5, wxEXPAND);
135 mainbox->Show(coll_sizer, false);
137 chunk_sizer = new wxBoxSizer(wxVERTICAL);
138 chunk_static_box = new wxStaticBox(main_panel, -1, wxT("Version info"));
139 chunk_static_box->SetThemeEnabled(true);
140 chunk_inner_box = new wxStaticBoxSizer(chunk_static_box, wxVERTICAL);
141 chunk_undef_label = new wxStaticText(main_panel, -1, wxT("Not defined"));
142 chunk_inner_box->Add(chunk_undef_label, 0, wxCENTER | wxALL, 5);
143 chunk_grid = new wxFlexGridSizer(2, 4, 0, 0);
144 chunk_inner_box->Add(chunk_grid, 0, wxCENTER | wxALL, 5);
145 chunk_version_label = new wxStaticText(main_panel, -1, wxT("Version:"));
146 chunk_type_label = new wxStaticText(main_panel, -1, wxT("Collection type:"));
147 chunk_flags_label = new wxStaticText(main_panel, -1, wxT("Flags:"));
148 chunk_sf_label = new wxStaticText(main_panel, -1, wxT("Collection scale factor:"));
149 chunk_version_field = new wxTextCtrl(main_panel, -1, wxT("0"));
150 wxString coll_type_labels[] = { wxT("Unused"),
151 wxT("Wall textures"),
153 wxT("Interface graphics"),
154 wxT("Scenery objects") };
155 chunk_type_menu = new wxChoice(main_panel, -1, wxDefaultPosition, wxDefaultSize, 5, coll_type_labels, 0);
156 chunk_flags_field = new wxTextCtrl(main_panel, -1, wxT("0"));
157 chunk_sf_field = new wxTextCtrl(main_panel, -1, wxT("0"));
158 chunk_grid->Add(chunk_version_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
159 chunk_grid->Add(chunk_version_field, 0, wxALIGN_LEFT);
160 chunk_grid->Add(chunk_type_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
161 chunk_grid->Add(chunk_type_menu, 0, wxALIGN_LEFT);
162 chunk_grid->Add(chunk_flags_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
163 chunk_grid->Add(chunk_flags_field, 0, wxALIGN_LEFT);
164 chunk_grid->Add(chunk_sf_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
165 chunk_grid->Add(chunk_sf_field, 0, wxALIGN_LEFT);
166 chunk_version_field->Enable(false);
167 chunk_type_menu->Enable(false);
168 chunk_flags_field->Enable(false);
169 chunk_sf_field->Enable(false);
170 chunk_sizer->AddStretchSpacer();
171 chunk_sizer->Add(chunk_inner_box, 0, wxALIGN_CENTER);
172 chunk_sizer->AddStretchSpacer();
173 mainbox->Add(chunk_sizer, 5, wxEXPAND);
174 mainbox->Show(chunk_sizer, false);
175 // create the color tables section
176 ct_outer_sizer = new wxBoxSizer(wxVERTICAL);
177 ctb = new CTBrowser(main_panel);
178 ct_count_label = new wxStaticText(main_panel, -1, wxT("N color tables"));
179 ct_edit_static_box = new wxStaticBox(main_panel, -1, wxT("Color table N of M"));
180 ct_edit_box = new wxStaticBoxSizer(ct_edit_static_box, wxVERTICAL);
181 ct_view = new CTView(main_panel);
182 ct_inner_edit_box = new wxBoxSizer(wxHORIZONTAL);
183 ct_self_lumin_checkbox = new wxCheckBox(main_panel, CB_SELF_LUMINESCENT, wxT("Self-luminescent color"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE);
184 ct_gradient_button = new wxButton(main_panel, BTN_GRADIENT, wxT("Make gradient"));
185 ct_edit_box->Add(ct_view, 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT | wxBOTTOM, 5);
186 ct_edit_box->Add(ct_inner_edit_box, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT | wxBOTTOM, 5);
187 ct_inner_edit_box->Add(ct_self_lumin_checkbox, 0, wxALIGN_CENTER);
188 ct_inner_edit_box->AddStretchSpacer();
189 ct_inner_edit_box->Add(ct_gradient_button, 0, wxALIGN_CENTER);
190 ct_outer_sizer->Add(ctb, 1, wxGROW);
191 ct_outer_sizer->Add(ct_count_label, 1, wxALIGN_LEFT | wxLEFT | wxTOP | wxBOTTOM, 10);
192 ct_outer_sizer->Add(ct_edit_box, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP | wxBOTTOM, 10);
193 ct_outer_sizer->Show(ct_edit_box, false);
194 mainbox->Add(ct_outer_sizer, 5, wxEXPAND);
195 mainbox->Show(ct_outer_sizer, false);
196 // create the bitmaps section
197 b_outer_sizer = new wxBoxSizer(wxVERTICAL);
198 bb = new BitmapBrowser(main_panel, BITMAP_BROWSER);
199 bb->SetThumbnailSize(64);
200 b_count_label = new wxStaticText(main_panel, -1, wxT("N bitmaps"));
201 b_edit_static_box = new wxStaticBox(main_panel, -1, wxT("Bitmap N of M"));
202 b_edit_box = new wxStaticBoxSizer(b_edit_static_box, wxHORIZONTAL);
203 b_edit_inner_box = new wxBoxSizer(wxVERTICAL);
204 b_info_label = new wxStaticText(main_panel, -1, wxT("AxB pixels"));
205 b_order_checkbox = new wxCheckBox(main_panel, CB_COLUMN_ORDER, wxT("Store pixels in column order"));
206 b_transparency_checkbox = new wxCheckBox(main_panel, CB_ENABLE_TRANSPARENCY, wxT("Enable transparency"));
207 b_view = new BitmapView(main_panel);
208 b_edit_inner_box->Add(b_info_label, 0, wxALIGN_LEFT | wxBOTTOM, 10);
209 b_edit_inner_box->Add(b_order_checkbox, 0, wxALIGN_LEFT);
210 b_edit_inner_box->Add(b_transparency_checkbox, 0, wxALIGN_LEFT);
211 b_edit_inner_box->AddStretchSpacer();
212 b_edit_box->Add(b_edit_inner_box, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT | wxBOTTOM, 5);
213 b_edit_box->Add(b_view, 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT | wxBOTTOM, 5);
214 b_outer_sizer->Add(bb, 1, wxGROW);
215 b_outer_sizer->Add(b_count_label, 1, wxALIGN_LEFT | wxLEFT | wxTOP | wxBOTTOM, 10);
216 b_outer_sizer->Add(b_edit_box, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP | wxBOTTOM, 10);
217 b_outer_sizer->Show(b_edit_box, false);
218 mainbox->Add(b_outer_sizer, 5, wxEXPAND);
219 mainbox->Show(b_outer_sizer, false);
220 // create the frames section
221 f_outer_sizer = new wxBoxSizer(wxVERTICAL);
222 // FIXME the FrameView should be initialized later, but spurious event handlers
223 // dereferencing it are triggered during initialization
224 f_view = new FrameView(main_panel, FRAME_VIEW);
225 fb = new FrameBrowser(main_panel, FRAME_BROWSER);
226 fb->SetThumbnailSize(64);
227 f_count_label = new wxStaticText(main_panel, -1, wxT("N frames"));
228 f_edit_static_box = new wxStaticBox(main_panel, -1, wxT("Frame N"));
229 f_edit_box = new wxStaticBoxSizer(f_edit_static_box, wxHORIZONTAL);
230 f_bitmap_label = new wxStaticText(main_panel, -1, wxT("Associated bitmap:"));
231 f_bitmap_id = new wxSpinCtrl(main_panel, FIELD_BITMAP_INDEX, wxT("0"), wxDefaultPosition, wxSize(60, -1));
232 f_xmirror_checkbox = new wxCheckBox(main_panel, CB_XMIRROR, wxT("X mirror"));
233 f_ymirror_checkbox = new wxCheckBox(main_panel, CB_YMIRROR, wxT("Y mirror"));
234 f_keypoint_checkbox = new wxCheckBox(main_panel, CB_KEYPOINT, wxT("Keypoint obscured"));
235 f_origin_x_label = new wxStaticText(main_panel, -1, wxT("Origin X:"), wxDefaultPosition, wxSize(150, -1));
236 f_origin_x_field = new wxTextCtrl(main_panel, FIELD_ORIGIN_X, wxT("0"), wxDefaultPosition, wxSize(60, -1));
237 f_origin_y_label = new wxStaticText(main_panel, -1, wxT("Origin Y:"), wxDefaultPosition, wxSize(150, -1));
238 f_origin_y_field = new wxTextCtrl(main_panel, FIELD_ORIGIN_Y, wxT("0"), wxDefaultPosition, wxSize(60, -1));
239 f_key_x_label = new wxStaticText(main_panel, -1, wxT("Keypoint X:"), wxDefaultPosition, wxSize(150, -1));
240 f_key_x_field = new wxTextCtrl(main_panel, FIELD_KEY_X, wxT("0"), wxDefaultPosition, wxSize(60, -1));
241 f_key_y_label = new wxStaticText(main_panel, -1, wxT("Keypoint Y:"), wxDefaultPosition, wxSize(150, -1));
242 f_key_y_field = new wxTextCtrl(main_panel, FIELD_KEY_Y, wxT("0"), wxDefaultPosition, wxSize(60, -1));
243 f_scalefactor_label = new wxStaticText(main_panel, -1, wxT("Scale factor:"), wxDefaultPosition, wxSize(150, -1));
244 f_scalefactor_field = new wxTextCtrl(main_panel, FIELD_FRAME_SCALEFACTOR, wxT("0"), wxDefaultPosition, wxSize(60, -1));
245 f_mli_label = new wxStaticText(main_panel, -1, wxT("Minimum lightness (%):"), wxDefaultPosition, wxSize(150, -1));
246 f_mli_field = new wxTextCtrl(main_panel, FIELD_MIN_LIGHT_INT, wxT("0"), wxDefaultPosition, wxSize(60, -1));
247 f_origin_box = new wxFlexGridSizer(10, 2, 5, 0);
248 f_origin_box->Add(f_bitmap_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
249 f_origin_box->Add(f_bitmap_id, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
250 f_origin_box->Add(f_xmirror_checkbox, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
251 f_origin_box->AddStretchSpacer();
252 f_origin_box->Add(f_ymirror_checkbox, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
253 f_origin_box->AddStretchSpacer();
254 f_origin_box->Add(f_scalefactor_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
255 f_origin_box->Add(f_scalefactor_field, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
256 f_origin_box->Add(f_origin_x_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
257 f_origin_box->Add(f_origin_x_field, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
258 f_origin_box->Add(f_origin_y_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
259 f_origin_box->Add(f_origin_y_field, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
260 f_origin_box->Add(f_key_x_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
261 f_origin_box->Add(f_key_x_field, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
262 f_origin_box->Add(f_key_y_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
263 f_origin_box->Add(f_key_y_field, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
264 f_origin_box->Add(f_keypoint_checkbox, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
265 f_origin_box->AddStretchSpacer();
266 f_origin_box->Add(f_mli_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
267 f_origin_box->Add(f_mli_field, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
268 f_edit_inner_box = new wxBoxSizer(wxVERTICAL);
269 f_edit_inner_box->Add(f_origin_box, 0, wxALIGN_LEFT);
270 f_edit_box->Add(f_edit_inner_box, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP | wxBOTTOM, 5);
271 f_edit_box->Add(f_view, 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT | wxBOTTOM, 5);
272 f_outer_sizer->Add(fb, 1, wxGROW);
273 f_outer_sizer->Add(f_count_label, 1, wxALIGN_LEFT | wxLEFT | wxTOP | wxBOTTOM, 10);
274 f_outer_sizer->Add(f_edit_box, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP | wxBOTTOM, 10);
275 f_outer_sizer->Show(f_edit_box, false);
276 mainbox->Add(f_outer_sizer, 5, wxEXPAND);
277 mainbox->Show(f_outer_sizer, false);
278 // create the sequences section
279 s_outer_static_box = new wxStaticBox(main_panel, -1, wxT("Sequence"));
280 s_outer_sizer = new wxStaticBoxSizer(s_outer_static_box, wxVERTICAL);
282 s_box1 = new wxBoxSizer(wxHORIZONTAL);
283 s_outer_sizer->Add(s_box1, 0, wxEXPAND | wxALIGN_TOP | wxALL, 5);
284 s_name_label = new wxStaticText(main_panel, -1, wxT("Name:"));
285 s_name_field = new wxTextCtrl(main_panel, FIELD_SEQ_NAME, wxT("foobar"));
286 s_delete_button = new wxButton(main_panel, BTN_DELETE_SEQ, wxT("Delete sequence"));
287 s_box1->Add(s_name_label, 0, wxALIGN_CENTER | wxRIGHT, 5);
288 s_box1->Add(s_name_field, 1, wxALIGN_CENTER);
289 s_box1->Add(s_delete_button, 0, wxALIGN_CENTER | wxLEFT, 20);
291 s_box2 = new wxBoxSizer(wxHORIZONTAL);
292 s_outer_sizer->Add(s_box2, 0, wxEXPAND | wxALIGN_TOP | wxALL, 5);
293 s_grid_box = new wxFlexGridSizer(5, 2, 4, 0);
294 s_box2->Add(s_grid_box, 0, wxEXPAND | wxALIGN_TOP);
295 s_type_label = new wxStaticText(main_panel, -1, wxT("Sequence type:"), wxDefaultPosition, wxSize(120, -1));
296 wxString anim_type_labels[] = { wxT("Display a random frame"),
297 wxT("Animation with 1 view"),
298 wxT("Animation with 4 views"),
299 wxT("Animation with 5 views"),
300 wxT("Animation with 8 views") };
301 s_type_menu = new wxChoice(main_panel, MENU_SEQ_TYPE, wxDefaultPosition, wxDefaultSize, 5, anim_type_labels, 0);
302 s_fpv_label = new wxStaticText(main_panel, -1, wxT("Frames per view:"), wxDefaultPosition, wxSize(120, -1));
303 s_fpv_field = new wxTextCtrl(main_panel, FIELD_SEQ_FRAMES_PER_VIEW, wxT("1"));
304 s_tpf_label = new wxStaticText(main_panel, -1, wxT("Ticks per frame:"), wxDefaultPosition, wxSize(120, -1));
305 s_tpf_field = new wxTextCtrl(main_panel, FIELD_SEQ_TICKS_PER_FRAME, wxT("1"));
306 s_lf_label = new wxStaticText(main_panel, -1, wxT("Loop at frame:"), wxDefaultPosition, wxSize(120, -1));
307 s_lf_field = new wxTextCtrl(main_panel, FIELD_SEQ_LOOP_FRAME, wxT("0"));
308 s_kf_label = new wxStaticText(main_panel, -1, wxT("Key frame:"), wxDefaultPosition, wxSize(120, -1));
309 s_kf_field = new wxTextCtrl(main_panel, FIELD_SEQ_KEY_FRAME, wxT("0"));
310 s_grid_box->Add(s_type_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
311 s_grid_box->Add(s_type_menu, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
312 s_grid_box->Add(s_fpv_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
313 s_grid_box->Add(s_fpv_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
314 s_grid_box->Add(s_tpf_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
315 s_grid_box->Add(s_tpf_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
316 s_grid_box->Add(s_lf_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
317 s_grid_box->Add(s_lf_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
318 s_grid_box->Add(s_kf_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
319 s_grid_box->Add(s_kf_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
321 s_separator = new wxPanel(main_panel);
322 s_box2->Add(s_separator, 1, wxEXPAND);
324 s_grid_box2 = new wxFlexGridSizer(5, 2, 4, 0);
325 s_box2->Add(s_grid_box2, 0, wxEXPAND | wxALIGN_TOP);
326 s_xfermode_label = new wxStaticText(main_panel, -1, wxT("Transfer mode:"), wxDefaultPosition, wxSize(140, -1));
327 wxString xfermode_labels[] = { wxT("Normal"),
328 wxT("Fade out to black"),
329 wxT("50% invisibility"),
330 wxT("75% invisibility"),
338 wxT("Fade out static"),
339 wxT("Pulsating static"),
342 wxT("Horizontal slide"),
343 wxT("Fast horizontal slide"),
344 wxT("Vertical slide"),
345 wxT("Fast vertical slide"),
350 s_xfermode_menu = new wxChoice(main_panel, MENU_SEQ_XFER_MODE, wxDefaultPosition, wxDefaultSize, 22, xfermode_labels, 0);
351 s_xferperiod_label = new wxStaticText(main_panel, -1, wxT("Transfer mode period:"), wxDefaultPosition, wxSize(150, -1));
352 s_xferperiod_field = new wxTextCtrl(main_panel, FIELD_SEQ_XFER_MODE_PERIOD, wxT("1"));
353 s_ffs_label = new wxStaticText(main_panel, -1, wxT("First frame sound:"), wxDefaultPosition, wxSize(150, -1));
354 s_ffs_field = new wxTextCtrl(main_panel, FIELD_SEQ_FIRST_FRAME_SND, wxT("0"));
355 s_kfs_label = new wxStaticText(main_panel, -1, wxT("Key frame sound:"), wxDefaultPosition, wxSize(150, -1));
356 s_kfs_field = new wxTextCtrl(main_panel, FIELD_SEQ_KEY_FRAME_SND, wxT("0"));
357 s_lfs_label = new wxStaticText(main_panel, -1, wxT("Last frame sound:"), wxDefaultPosition, wxSize(150, -1));
358 s_lfs_field = new wxTextCtrl(main_panel, FIELD_SEQ_LAST_FRAME_SND, wxT("0"));
359 s_grid_box2->Add(s_xfermode_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxRIGHT, 5);
360 s_grid_box2->Add(s_xfermode_menu, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
361 s_grid_box2->Add(s_xferperiod_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxRIGHT, 5);
362 s_grid_box2->Add(s_xferperiod_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
363 s_grid_box2->Add(s_ffs_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
364 s_grid_box2->Add(s_ffs_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
365 s_grid_box2->Add(s_kfs_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
366 s_grid_box2->Add(s_kfs_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
367 s_grid_box2->Add(s_lfs_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
368 s_grid_box2->Add(s_lfs_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
370 s_fb = new SequenceView(main_panel, wxID_ANY);
371 s_outer_sizer->Add(s_fb, 1, wxEXPAND | wxALL, 5);
372 mainbox->Add(s_outer_sizer, 5, wxEXPAND | wxLEFT | wxRIGHT | wxTOP | wxBOTTOM, 10);
373 mainbox->Show(s_outer_sizer, false);
376 main_panel->SetSizer(mainbox);
378 // X seems to require a forced resize
381 mFrame->GetSize(&x, &y);
382 mFrame->SetSize(wxDefaultCoord, wxDefaultCoord, x, y);
390 void ShapesView::OnDraw(wxDC *WXUNUSED(dc))
394 void ShapesView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint))
396 unsigned int collCount = ((ShapesDocument*)GetDocument())->CollectionCount();
401 // update all levels of the tree control
402 for (unsigned int i = 0; i < collCount; i++) {
403 // collection name nodes
404 ShapesTreeItemData *itemdata = new ShapesTreeItemData(i, -1, TREESECTION_COLLECTION);
405 wxTreeItemId coll = colltree->AppendItem(colltree->GetRootItem(), GetName(wxT("collection"), i),
408 for (unsigned int j = 0; j < 2; j++) {
409 // color version nodes
410 ShapesTreeItemData *id = new ShapesTreeItemData(i, j, TREESECTION_VERSION);
413 if (j == COLL_VERSION_8BIT)
414 label = wxT("8-bit color version");
415 else if (j == COLL_VERSION_TRUECOLOR)
416 label = wxT("True color version");
417 wxTreeItemId coll2 = colltree->AppendItem(coll, label, -1, -1, id);
419 if (((ShapesDocument*)GetDocument())->CollectionDefined(i, j)) {
421 ShapesTreeItemData *id_b = new ShapesTreeItemData(i, j, TREESECTION_BITMAPS),
422 *id_ct = new ShapesTreeItemData(i, j, TREESECTION_COLORTABLES),
423 *id_f = new ShapesTreeItemData(i, j, TREESECTION_FRAMES),
424 *id_s = new ShapesTreeItemData(i, j, TREESECTION_SEQUENCES);
425 wxTreeItemId coll_b = colltree->AppendItem(coll2, wxT("Bitmaps"), -1, -1, id_b),
426 coll_ct = colltree->AppendItem(coll2, wxT("Color tables"), -1, -1, id_ct),
427 coll_f = colltree->AppendItem(coll2, wxT("Frames"), -1, -1, id_f),
428 coll_s = colltree->AppendItem(coll2, wxT("Sequences"), -1, -1, id_s);
430 for (unsigned int k = 0; k < ((ShapesDocument*)GetDocument())->CollectionSequenceCount(i, j); k++) {
432 ShapesSequence *seq = ((ShapesDocument*)GetDocument())->GetSequence(i, j, k);
434 ShapesTreeItemData *id_seq = new ShapesTreeItemData(i, j, TREESECTION_SEQUENCES, k);
437 if (seq->Name().Length() > 0)
438 blabel << wxT(" - ") << seq->Name();
439 colltree->AppendItem(coll_s, blabel, -1, -1, id_seq);
446 bool ShapesView::OnClose(bool deleteWindow)
448 if (!GetDocument()->Close())
458 // return the id of the "Sequences" tree item relative to
459 // the specified collection and color version
460 wxTreeItemId ShapesView::GetSequencesTreeItem(unsigned int collection, unsigned int version) const
462 wxTreeItemIdValue thecookie;
463 wxTreeItemId rootid = colltree->GetRootItem(),
464 collnameid = colltree->GetFirstChild(rootid, thecookie);
466 // descend into the tree towards the right item
467 while (collnameid.IsOk()) {
468 ShapesTreeItemData *collname_data = dynamic_cast<ShapesTreeItemData *>(colltree->GetItemData(collnameid));
470 if (collname_data->CollID() == (int)collection) {
471 // found right collection branch
472 wxTreeItemIdValue thecookieII;
473 wxTreeItemId collversid = colltree->GetFirstChild(collnameid, thecookieII);
475 while (collversid.IsOk()) {
476 ShapesTreeItemData *collvers_data = dynamic_cast<ShapesTreeItemData *>(colltree->GetItemData(collversid));
478 if (collvers_data->Version() == (int)version) {
479 // found right version node
480 wxTreeItemIdValue thecookieIII;
481 wxTreeItemId sectid = colltree->GetFirstChild(collversid, thecookieIII);
483 while (sectid.IsOk()) {
484 ShapesTreeItemData *sect_data = dynamic_cast<ShapesTreeItemData *>(colltree->GetItemData(sectid));
486 if (sect_data->Section() == TREESECTION_SEQUENCES) {
490 sectid = colltree->GetNextChild(collversid, thecookieIII);
493 collversid = colltree->GetNextChild(collnameid, thecookieII);
496 collnameid = colltree->GetNextChild(rootid, thecookie);
498 return wxTreeItemId(); // ctor makes it invalid, so ok
501 void ShapesView::MenuEditCopy(wxCommandEvent& e)
503 ShapesTreeItemData* selected_item_data = dynamic_cast<ShapesTreeItemData*>(colltree->GetItemData(colltree->GetSelection()));
505 if (selected_item_data != NULL) {
506 switch (selected_item_data->Section()) {
507 case TREESECTION_BITMAPS:
508 DoCopyBitmap(bb->GetSelection());
510 case TREESECTION_VERSION:
511 DoCopyChunk(selected_item_data->CollID(), selected_item_data->Version());
519 // handle the Edit->Delete menu command, which is context-sensitive
520 void ShapesView::MenuEditDelete(wxCommandEvent &e)
522 ShapesTreeItemData *selected_item_data = dynamic_cast<ShapesTreeItemData *>(colltree->GetItemData(colltree->GetSelection()));
524 if (selected_item_data != NULL) {
525 // what should we delete?
526 switch (selected_item_data->Section()) {
527 case TREESECTION_COLORTABLES:
528 DoDeleteColorTable(ctb->GetSelection());
530 case TREESECTION_BITMAPS:
531 DoDeleteBitmap(bb->GetSelection());
533 case TREESECTION_FRAMES:
534 DoDeleteFrame(fb->GetSelection());
536 case TREESECTION_SEQUENCES:
542 void ShapesView::MenuEditPaste(wxCommandEvent& e)
544 ShapesTreeItemData* selected_item_data = dynamic_cast<ShapesTreeItemData*>(colltree->GetItemData(colltree->GetSelection()));
546 if (selected_item_data != NULL) {
547 switch (selected_item_data->Section()) {
548 case TREESECTION_BITMAPS:
549 DoPasteBitmap(bb->GetSelection());
551 case TREESECTION_VERSION:
552 DoPasteChunk(selected_item_data->CollID(), selected_item_data->Version());
560 void ShapesView::MenuViewTransparency(wxCommandEvent &e)
562 bool showTranspPixels = e.IsChecked();
565 bb->SetTranspPixelsDisplay(!showTranspPixels);
566 b_view->SetTranspPixelsDisplay(!showTranspPixels);
567 fb->SetTranspPixelsDisplay(!showTranspPixels);
568 f_view->SetTranspPixelsDisplay(!showTranspPixels);
569 s_fb->SetTranspPixelsDisplay(!showTranspPixels);
573 void ShapesView::MenuViewCenterOrigin(wxCommandEvent &e)
575 f_view->SetCenterOrigin(e.IsChecked());
578 // color table menu handler
579 void ShapesView::MenuViewCT(wxCommandEvent &e)
581 mViewColorTable = e.GetId() - VIEW_MENU_COLORTABLE_0;
583 ShapesColorTable *ctp = ((ShapesDocument*)GetDocument())->GetColorTable(
584 mSelectedColl, mSelectedVers, mViewColorTable);
587 bb->SetColorTable(ctp);
588 b_view->SetColorTable(ctp);
589 fb->SetColorTable(ctp);
590 f_view->SetColorTable(ctp);
591 s_fb->SetColorTable(ctp);
595 // thumbnail size menu handler
596 void ShapesView::MenuViewTNSize(wxCommandEvent &e)
601 case VIEW_MENU_TNSIZE_SMALL:
604 case VIEW_MENU_TNSIZE_MEDIUM:
607 case VIEW_MENU_TNSIZE_LARGE:
610 case VIEW_MENU_TNSIZE_AUTO:
615 bb->SetThumbnailSize(size);
616 fb->SetThumbnailSize(size);
617 s_fb->SetThumbnailSize(size);
621 void ShapesView::MenuShapesAddColorTable(wxCommandEvent &e)
623 wxFileDialog *dlg = new wxFileDialog(mFrame, wxT("Import a color table"), wxT(""), wxT(""),
624 wxT("Photoshop color table|*.act|Gimp palette|*.gpl"), wxOPEN);
626 if (dlg->ShowModal() == wxID_OK) {
627 wxString filename = dlg->GetPath();
628 std::ifstream ifs(filename.mb_str(), std::ios::binary);
631 ShapesColorTable *newct = new ShapesColorTable(ifs, filename.AfterLast('.')),
632 *firstct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, 0);
635 if (newct->ColorCount() > 0) {
636 if (newct->GetColor(0)->Red() != 0 || newct->GetColor(0)->Green() != 0 || newct->GetColor(0)->Blue() != 255<<8)
637 wxMessageBox(wxT("The first color of the table being imported is not the usual Marathon chroma key color"
638 " (no red, no green, maximum blue). It should be corrected manually to avoid problems."),
639 wxT("Invalid chroma key color"), wxOK | wxICON_WARNING, mFrame);
640 if (firstct != NULL) {
641 // handle cases in which the new color table has more or less colors than existing ones
642 if (newct->ColorCount() > firstct->ColorCount()) {
643 // more colors, append dummy colors to existing tables
644 unsigned int numcolors = newct->ColorCount() - firstct->ColorCount(),
645 numcts = ((ShapesDocument*)GetDocument())->CollectionColorTableCount(mSelectedColl, mSelectedVers);
647 for (unsigned int i = 0; i < numcts; i++) {
648 ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, i);
650 for (unsigned int j = 0; j < numcolors; j++)
651 ct->InsertColor(new ShapesColor(0, 0, 0, numcolors + j));
653 } else if (newct->ColorCount() < firstct->ColorCount()) {
654 // less colors, append dummy colors to the new table
655 unsigned int numcolors = firstct->ColorCount() - newct->ColorCount();
657 for (unsigned int i = 0; i < numcolors; i++)
658 newct->InsertColor(new ShapesColor(0, 0, 0, newct->ColorCount() + i));
661 ((ShapesDocument*)GetDocument())->InsertColorTable(newct, mSelectedColl, mSelectedVers);
662 ((ShapesDocument*)GetDocument())->Modify(true);
664 ctb->AddColorTable(newct);
665 unsigned int colorTableCount = ((ShapesDocument*)GetDocument())->CollectionColorTableCount(
666 mSelectedColl, mSelectedVers);
667 wxMenu *colortables_submenu;
668 menubar->FindItem(VIEW_MENU_COLORTABLE_0, &colortables_submenu);
669 for (unsigned int i = 0; i < colortables_submenu->GetMenuItemCount(); i++) {
670 menubar->Enable(VIEW_MENU_COLORTABLE_0 + i, i < colorTableCount);
671 menubar->Check(VIEW_MENU_COLORTABLE_0 + mViewColorTable, i == (unsigned int)mViewColorTable);
676 errormsg << wxT("Sorry, could not load a color table from ") << filename << wxT(" because the file format is unknown or the file contains no colors.");
677 wxMessageBox(errormsg, wxT("Error loading color table"), wxOK | wxICON_ERROR, mFrame);
683 errormsg << wxT("Sorry, could not load a color table from ") << filename << wxT(" because the file is not readable.");
684 wxMessageBox(errormsg, wxT("Error loading color table"), wxOK | wxICON_ERROR, mFrame);
690 // prompt the user and save the selected color table, either in
691 // Gimp or PhotoShop format (depending on event id)
692 void ShapesView::MenuShapesSaveColorTable(wxCommandEvent &e)
694 if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) {
695 int selection = ctb->GetSelection();
697 if (selection >= 0) {
698 bool ps = (e.GetId() == SHAPES_MENU_SAVECOLORTABLETOPS);
699 wxString prompt = wxString::Format(wxT("Save color table %d"), selection),
703 name = wxString::Format(wxT("ColorTable%d.act"), selection);
704 ctpath = wxFileSelector(prompt, wxT(""), name, wxT(""),
705 wxT("PhotoShop color table|*.act"),
706 wxSAVE | wxOVERWRITE_PROMPT);
708 name = wxString::Format(wxT("ColorTable%d.gpl"), selection);
709 ctpath = wxFileSelector(prompt, wxT(""), name, wxT(""),
710 wxT("Gimp color table|*.gpl"),
711 wxSAVE | wxOVERWRITE_PROMPT);
714 if (!ctpath.empty()) {
715 ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, selection);
719 err = ct->SaveToPhotoshop(ctpath);
721 err = ct->SaveToGimp(ctpath);
726 errormsg << wxT("Sorry, could not save color table to ") << ctpath << wxT(".");
727 wxMessageBox(errormsg, wxT("Error saving color table"), wxOK | wxICON_ERROR, mFrame);
734 void ShapesView::MenuShapesAddBitmap(wxCommandEvent &e)
736 if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) {
737 wxFileDialog *dlg = new wxFileDialog(mFrame, wxT("Choose a bitmap to add"), wxT(""), wxT(""),
738 wxT("Common bitmap files (BMP, JPEG, PNG, GIF, TIFF)|*.bmp;*.jpg;*.jpeg;*.tif;*.tiff;*.png;*.gif"),
741 if (dlg->ShowModal() == wxID_OK) {
742 wxString filename = dlg->GetPath();
745 if (img.LoadFile(filename)) {
747 // we have the wxImage now. Encode it to a new bitmap
748 ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, mViewColorTable);
749 ShapesBitmap *newbmp = new ShapesBitmap(img, ct);
751 // automagically initialize bitmap flags
752 if (((ShapesDocument*)GetDocument())->CollectionType(mSelectedColl, mSelectedVers) == _object_collection ||
753 ((ShapesDocument*)GetDocument())->CollectionType(mSelectedColl, mSelectedVers) == _scenery_collection) {
754 // compress weapons, monsters and scenery
755 newbmp->SetBytesPerRow(-1);
756 } else if (((ShapesDocument*)GetDocument())->CollectionType(mSelectedColl, mSelectedVers) == _interface_collection) {
757 // interface elements are row-ordered (not so important with A1 actually)
758 newbmp->SetColumnOrdered(false);
760 ((ShapesDocument*)GetDocument())->InsertBitmap(newbmp, mSelectedColl, mSelectedVers);
763 unsigned int bitmap_count = ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers);
764 ShapesBitmap *pnewbitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, bitmap_count-1);
765 wxString count_string = wxString::Format(wxT("%u bitmap"), bitmap_count);
767 bb->AddBitmap(pnewbitmap);
768 fb->AddBitmap(pnewbitmap);
769 if (bitmap_count != 1)
770 count_string << wxT("s");
771 b_count_label->SetLabel(count_string);
774 ((ShapesDocument*)GetDocument())->Modify(true);
778 errormsg << wxT("Sorry, could not load bitmap from ") << filename << wxT(".");
779 wxMessageBox(errormsg, wxT("Error adding bitmap"), wxOK | wxICON_ERROR, mFrame);
786 // export selected bitmap to a BMP file
787 void ShapesView::MenuShapesExportBitmap(wxCommandEvent &e)
789 if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) {
790 int selection = bb->GetSelection();
792 if (selection >= 0) {
793 wxString prompt = wxString::Format(wxT("Export bitmap %d"), selection),
794 name = wxString::Format(wxT("bitmap%.3d.bmp"), selection),
795 path = wxFileSelector(prompt, wxT(""), name, wxT(""), wxT("BMP image|*.bmp"), wxSAVE | wxOVERWRITE_PROMPT);
798 ShapesBitmap *bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, selection);
799 ShapesColorTable *colorTable = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, mViewColorTable);
801 bitmap->SaveToBMP(path, colorTable);
807 void ShapesView::MenuShapesExportBitmapMask(wxCommandEvent &e)
809 if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) {
810 int selection = bb->GetSelection();
812 if (selection >= 0) {
813 wxString prompt = wxString::Format(wxT("Export bitmap %d mask"), selection),
814 name = wxString::Format(wxT("bitmap%.3dmask.bmp"), selection),
815 path = wxFileSelector(prompt, wxT(""), name, wxT(""), wxT("BMP image|*.bmp"), wxSAVE | wxOVERWRITE_PROMPT);
818 ShapesBitmap *bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, selection);
820 bitmap->SaveMaskToBMP(path);
826 // export all bitmaps of the selected collection to separate BMP files in a folder
827 void ShapesView::MenuShapesExportBitmaps(wxCommandEvent &e)
829 if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) {
830 wxString dirPath = wxDirSelector(wxT("Select destination folder"));
832 if (!dirPath.empty()) {
833 ShapesColorTable *colorTable = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, mViewColorTable);
836 for (unsigned int i = 0; i < ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers); i++) {
837 wxString name = wxString::Format(wxT("bitmap%.3d.bmp"), i);
838 ShapesBitmap *bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, i);
840 bitmap->SaveToBMP(dirPath + wxT("/") + name, colorTable);
847 void ShapesView::MenuShapesExportBitmapMasks(wxCommandEvent &e)
849 if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) {
850 wxString dirPath = wxDirSelector(wxT("Select destination folder"));
852 if (!dirPath.empty()) {
854 for (unsigned int i = 0; i < ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers); i++) {
855 wxString name = wxString::Format(wxT("bitmap%.3dmask.bmp"), i);
856 ShapesBitmap *bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, i);
858 bitmap->SaveMaskToBMP(dirPath + wxT("/") + name);
865 void ShapesView::MenuShapesNewFrame(wxCommandEvent &e)
867 if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) {
868 // append an empty frame
869 ShapesFrame *newframe = new ShapesFrame();
871 newframe->SetScaleFactor(((ShapesDocument*)GetDocument())->CollectionScaleFactor(mSelectedColl, mSelectedVers));
872 if (((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers) > ((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers)) {
873 newframe->SetBitmapIndex(((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers));
875 ((ShapesDocument*)GetDocument())->InsertFrame(newframe, mSelectedColl, mSelectedVers);
876 fb->AddFrame(((ShapesDocument*)GetDocument())->GetFrame(mSelectedColl, mSelectedVers, ((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers)-1));
877 // update frame count label
878 unsigned int frame_count = ((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers);
879 wxString count_string = wxString::Format(wxT("%u frame"), frame_count);
881 if (frame_count != 1)
882 count_string << wxT("s");
883 f_count_label->SetLabel(count_string);
884 ((ShapesDocument*)GetDocument())->Modify(true);
888 void ShapesView::MenuShapesNewSequence(wxCommandEvent &e)
890 if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) {
891 // append an empty sequence
892 ShapesSequence *newseq = new ShapesSequence();
894 ((ShapesDocument*)GetDocument())->InsertSequence(newseq, mSelectedColl, mSelectedVers);
896 // insert the new entry in the main tree
897 wxTreeItemId thenode = GetSequencesTreeItem(mSelectedColl, mSelectedVers);
898 int seq_id = ((ShapesDocument*)GetDocument())->CollectionSequenceCount(mSelectedColl, mSelectedVers) - 1;
899 ShapesSequence *seq = ((ShapesDocument*)GetDocument())->GetSequence(mSelectedColl, mSelectedVers, seq_id);
900 ShapesTreeItemData *itemdata = new ShapesTreeItemData(mSelectedColl, mSelectedVers, TREESECTION_SEQUENCES, seq_id);
904 if (seq->Name().Length() > 0)
905 label << wxT(" - ") << seq->Name();
906 colltree->AppendItem(thenode, label, -1, -1, itemdata);
907 ((ShapesDocument*)GetDocument())->Modify(true);
911 void ShapesView::MenuShapesGeneratePatch(wxCommandEvent&)
913 ShapesDocument* document = (ShapesDocument*) GetDocument();
915 if (document == NULL) {
919 // prompt the user for a base for the patch
920 wxFileDialog dlg(mFrame, wxT("Choose a base file (e.g. standard Infinity shapes)"), wxT(""), wxT(""), wxT("Shapes files (*.shpA)|*.shpA|All files (*.*)|*.*"), wxOPEN);
921 if (dlg.ShowModal() != wxID_OK) {
926 if (!base.DoOpenDocument(dlg.GetPath())) {
930 // prompt the user for a patch location
931 wxString path = wxFileSelector(wxT("Export patch file"), wxT(""), wxT("Shapes Patch.ShPa"), wxT(""), wxT("Shapes patch|*.ShPa"), wxSAVE | wxOVERWRITE_PROMPT);
937 #if wxUSE_STD_IOSTREAM
938 wxSTD ofstream stream(path.mb_str(), wxSTD ios_base::out | wxSTD ios_base::binary | wxSTD ios_base::trunc);
940 wxFileOutputStream stream(path);
941 if (!stream.IsOk()) {
945 document->SavePatch(stream, base);
948 void ShapesView::MenuShapesImportPatch(wxCommandEvent&)
950 ShapesDocument* document = (ShapesDocument*) GetDocument();
952 if (document == NULL) {
956 // prompt the user for a patch
957 wxString path = wxFileSelector(wxT("Choose a patch file"), wxT(""), wxT(""), wxT(""), wxT("Patch files (*.ShPa)|*.ShPa|All files (*.*)|*.*"), wxOPEN);
963 #if wxUSE_STD_IOSTREAM
964 wxSTD ifstream stream(path.mb_str(), wxSTD ios_base::in | wxSTD ios_base::binary);
966 wxFileInputStream stream(path);
967 if (!stream.IsOk()) {
972 if (!document->LoadPatch(stream)) {
973 wxMessageBox(wxT("Error loading shapes patch; the patch may be partially applied!"), wxT("Error loading shapes patch"), wxOK | wxICON_ERROR, mFrame);
976 colltree->Unselect();
977 colltree->CollapseAll();
980 mSelectedSequence = -1;
981 mViewColorTable = -1;
982 mainbox->Show(dummy_sizer, true);
983 mainbox->Show(coll_sizer, false);
984 mainbox->Show(chunk_sizer, false);
985 mainbox->Show(b_outer_sizer, false);
986 mainbox->Show(ct_outer_sizer, false);
987 mainbox->Show(f_outer_sizer, false);
988 mainbox->Show(s_outer_sizer, false);
991 // user selected a tree entry
992 void ShapesView::OnTreeSelect(wxTreeEvent &e)
994 ShapesTreeItemData *data = dynamic_cast<ShapesTreeItemData *>(colltree->GetItemData(e.GetItem()));
997 int new_coll = data->CollID(),
998 new_vers = data->Version(),
999 new_section = data->Section();
1001 if (new_coll != mSelectedColl || new_vers != mSelectedVers) {
1002 // user has moved to another collection/version
1004 // first clear the user interface
1005 wxMenu *colortables_submenu;
1006 menubar->FindItem(VIEW_MENU_COLORTABLE_0, &colortables_submenu);
1007 unsigned int ctmenucount = colortables_submenu->GetMenuItemCount();
1009 mViewColorTable = -1;
1011 ct_view->SetColorTable(NULL);
1014 b_view->SetBitmap(NULL);
1017 f_view->SetFrame(NULL);
1018 f_view->SetBitmap(NULL);
1020 for (unsigned int i = 0; i < ctmenucount; i++)
1021 menubar->Enable(VIEW_MENU_COLORTABLE_0 + i, false);
1022 menubar->Enable(SHAPES_MENU_SAVECOLORTABLE, false);
1023 menubar->Enable(SHAPES_MENU_SAVECOLORTABLETOPS, false);
1024 menubar->Enable(SHAPES_MENU_EXPORTBITMAP, false);
1025 menubar->Enable(SHAPES_MENU_EXPORTMASK, false);
1027 // set collection info panel
1028 coll_static_box->SetLabel(wxString::Format(wxT("Global info for collection %d"), new_coll));
1030 wxString collinfo_s;
1031 collinfo_s << wxT("Status: ") << ((ShapesDocument*)GetDocument())->CollectionStatus(new_coll) << wxT("\n");
1032 collinfo_s << wxT("Flags: ") << ((ShapesDocument*)GetDocument())->CollectionFlags(new_coll) << wxT("\n\n");
1033 if (((ShapesDocument*)GetDocument())->CollectionDefined(new_coll, COLL_VERSION_8BIT))
1034 collinfo_s << wxT("8-bit color version present\n");
1036 collinfo_s << wxT("No 8-bit color version\n");
1037 if (((ShapesDocument*)GetDocument())->CollectionDefined(new_coll, COLL_VERSION_TRUECOLOR))
1038 collinfo_s << wxT("True color version present");
1040 collinfo_s << wxT("No true color version");
1041 coll_text->SetLabel(collinfo_s);
1043 if (new_coll != -1 && new_vers != -1) {
1044 if (new_vers == COLL_VERSION_TRUECOLOR)
1045 chunk_static_box->SetLabel(wxT("Shapes for true color and OpenGL display"));
1047 chunk_static_box->SetLabel(wxT("Shapes for 8-bit color display"));
1049 if (((ShapesDocument*)GetDocument())->CollectionDefined(new_coll, new_vers)) {
1050 // a defined collection has been selected
1051 unsigned int ct_count = ((ShapesDocument*)GetDocument())->CollectionColorTableCount(new_coll, new_vers),
1052 bitmap_count = ((ShapesDocument*)GetDocument())->CollectionBitmapCount(new_coll, new_vers),
1053 frame_count = ((ShapesDocument*)GetDocument())->CollectionFrameCount(new_coll, new_vers);
1054 wxString count_string;
1056 wxBeginBusyCursor();
1057 menubar->Enable(SHAPES_MENU_ADDCOLORTABLE, true);
1058 menubar->Enable(SHAPES_MENU_ADDBITMAP, true);
1059 menubar->Enable(SHAPES_MENU_EXPORTBITMAPS, true);
1060 menubar->Enable(SHAPES_MENU_EXPORTMASKS, true);
1061 menubar->Enable(SHAPES_MENU_ADDFRAME, true);
1062 menubar->Enable(SHAPES_MENU_ADDSEQUENCE, true);
1065 chunk_version_field->ChangeValue(INT_TO_WXSTRING(((ShapesDocument*)GetDocument())->CollectionVersion(new_coll, new_vers)));
1066 chunk_type_menu->SetSelection(((ShapesDocument*)GetDocument())->CollectionType(new_coll, new_vers));
1067 chunk_flags_field->ChangeValue(INT_TO_WXSTRING(((ShapesDocument*)GetDocument())->CollectionFlags(new_coll, new_vers)));
1068 chunk_sf_field->ChangeValue(INT_TO_WXSTRING(((ShapesDocument*)GetDocument())->CollectionScaleFactor(new_coll, new_vers)));
1071 mViewColorTable = 0;
1072 for (unsigned int i = 0; i < ct_count; i++)
1073 ctb->AddColorTable(((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, i));
1074 for (unsigned int i = 0; i < ctmenucount; i++)
1075 menubar->Enable(VIEW_MENU_COLORTABLE_0 + i, i < ct_count);
1077 menubar->Check(VIEW_MENU_COLORTABLE_0, true);
1078 count_string << ct_count << wxT(" color table");
1080 count_string << wxT("s");
1082 count_string << wxT(", ") << ((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, 0)->ColorCount() << wxT(" colors per table");
1083 ct_count_label->SetLabel(count_string);
1086 bb->SetColorTable(((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, 0));
1087 b_view->SetColorTable(((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, 0));
1088 for (unsigned int i = 0; i < bitmap_count; i++)
1089 bb->AddBitmap(((ShapesDocument*)GetDocument())->GetBitmap(new_coll, new_vers, i));
1090 count_string.Clear();
1091 count_string << bitmap_count << wxT(" bitmap");
1092 if (bitmap_count != 1)
1093 count_string << wxT("s");
1094 b_count_label->SetLabel(count_string);
1097 fb->SetColorTable(((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, 0));
1098 f_view->SetColorTable(((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, 0));
1099 for (unsigned int i = 0; i < bitmap_count; i++)
1100 fb->AddBitmap(((ShapesDocument*)GetDocument())->GetBitmap(new_coll, new_vers, i));
1101 for (unsigned int i = 0; i < frame_count; i++)
1102 fb->AddFrame(((ShapesDocument*)GetDocument())->GetFrame(new_coll, new_vers, i));
1103 count_string.Clear();
1104 count_string << frame_count << wxT(" frame");
1105 if (frame_count != 1)
1106 count_string << wxT("s");
1107 f_count_label->SetLabel(count_string);
1111 menubar->Enable(SHAPES_MENU_ADDCOLORTABLE, false);
1112 menubar->Enable(SHAPES_MENU_ADDBITMAP, false);
1113 menubar->Enable(SHAPES_MENU_EXPORTBITMAPS, false);
1114 menubar->Enable(SHAPES_MENU_EXPORTMASKS, false);
1115 menubar->Enable(SHAPES_MENU_ADDFRAME, false);
1116 menubar->Enable(SHAPES_MENU_ADDSEQUENCE, false);
1119 menubar->Enable(SHAPES_MENU_ADDCOLORTABLE, false);
1120 menubar->Enable(SHAPES_MENU_ADDBITMAP, false);
1121 menubar->Enable(SHAPES_MENU_EXPORTBITMAPS, false);
1122 menubar->Enable(SHAPES_MENU_EXPORTMASKS, false);
1123 menubar->Enable(SHAPES_MENU_ADDFRAME, false);
1124 menubar->Enable(SHAPES_MENU_ADDSEQUENCE, false);
1126 mSelectedColl = new_coll;
1127 mSelectedVers = new_vers;
1132 // handle sequence selection
1133 mSelectedSequence = data->Sequence();
1134 if (mSelectedSequence > -1) {
1135 ShapesSequence *seq = ((ShapesDocument*)GetDocument())->GetSequence(new_coll, new_vers, mSelectedSequence);
1137 // setup sequence panel controls
1138 s_outer_static_box->SetLabel(wxString::Format(wxT("Sequence %d of %u"),
1139 mSelectedSequence, ((ShapesDocument*)GetDocument())->CollectionSequenceCount(new_coll, new_vers)));
1140 s_name_field->ChangeValue(seq->Name());
1141 switch (seq->NumberOfViews()) {
1142 case UNANIMATED: s_type_menu->SetSelection(0); break;
1143 case ANIMATED_1: s_type_menu->SetSelection(1); break;
1144 case ANIMATED_3TO4: s_type_menu->SetSelection(2); break;
1145 case ANIMATED_4: s_type_menu->SetSelection(2); break;
1146 case ANIMATED_3TO5: s_type_menu->SetSelection(3); break;
1147 case ANIMATED_5: s_type_menu->SetSelection(3); break;
1148 case ANIMATED_2TO8: s_type_menu->SetSelection(4); break;
1149 case ANIMATED_5TO8: s_type_menu->SetSelection(4); break;
1150 case ANIMATED_8: s_type_menu->SetSelection(4); break;
1152 s_type_menu->SetSelection(0);
1153 wxMessageBox(wxString::Format(wxT("This sequence has an unknown type %d, and ShapeFusion can not handle it. Something strange may happen now!"), seq->NumberOfViews()),
1154 wxT("Warning"), wxOK | wxICON_ERROR, mFrame);
1157 s_fpv_field->ChangeValue(INT_TO_WXSTRING(seq->FramesPerView()));
1158 s_tpf_field->ChangeValue(INT_TO_WXSTRING(seq->TicksPerFrame()));
1159 s_lf_field->ChangeValue(INT_TO_WXSTRING(seq->LoopFrame()));
1160 s_kf_field->ChangeValue(INT_TO_WXSTRING(seq->KeyFrame()));
1161 s_xfermode_menu->SetSelection(seq->TransferMode());
1162 s_xferperiod_field->ChangeValue(INT_TO_WXSTRING(seq->TransferModePeriod()));
1163 s_ffs_field->ChangeValue(INT_TO_WXSTRING(seq->FirstFrameSound()));
1164 s_kfs_field->ChangeValue(INT_TO_WXSTRING(seq->KeyFrameSound()));
1165 s_lfs_field->ChangeValue(INT_TO_WXSTRING(seq->LastFrameSound()));
1166 // setup the sequence view
1167 wxBeginBusyCursor();
1170 s_fb->SetColorTable(((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, mViewColorTable));
1171 for (unsigned int i = 0; i < ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers); i++)
1172 s_fb->AddBitmap(((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, i));
1173 for (unsigned int i = 0; i < ((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers); i++)
1174 s_fb->AddFrame(((ShapesDocument*)GetDocument())->GetFrame(mSelectedColl, mSelectedVers, i));
1175 s_fb->SetSeqParameters(seq->NumberOfViews(), seq->FramesPerView(), &seq->mFrameIndexes, this);
1180 menubar->SetLabel(EDIT_MENU_DELETE, _("Delete"));
1181 menubar->Enable(EDIT_MENU_COPY, false);
1182 menubar->Enable(EDIT_MENU_DELETE, false);
1183 menubar->Enable(EDIT_MENU_PASTE, false);
1185 // handle section selection: show/hide editing panels
1186 mainbox->Show(dummy_sizer, false);
1187 mainbox->Show(coll_sizer, false);
1188 mainbox->Show(chunk_sizer, false);
1189 mainbox->Show(b_outer_sizer, false);
1190 mainbox->Show(ct_outer_sizer, false);
1191 mainbox->Show(f_outer_sizer, false);
1192 mainbox->Show(s_outer_sizer, false);
1193 switch (new_section) {
1194 case TREESECTION_COLLECTION:
1195 mainbox->Show(coll_sizer, true);
1197 case TREESECTION_VERSION:
1198 mainbox->Show(chunk_sizer, true);
1199 chunk_inner_box->Show(chunk_undef_label, !((ShapesDocument*)GetDocument())->CollectionDefined(mSelectedColl, mSelectedVers));
1200 chunk_inner_box->Show(chunk_grid, ((ShapesDocument*)GetDocument())->CollectionDefined(mSelectedColl, mSelectedVers));
1202 menubar->Enable(EDIT_MENU_COPY, true);
1203 menubar->Enable(EDIT_MENU_PASTE, true);
1205 case TREESECTION_BITMAPS:
1206 mainbox->Show(b_outer_sizer, true);
1207 b_outer_sizer->Show(b_edit_box, bb->GetSelection() != -1);
1208 b_outer_sizer->Show(b_count_label, bb->GetSelection() == -1);
1210 case TREESECTION_COLORTABLES:
1211 mainbox->Show(ct_outer_sizer, true);
1212 ct_outer_sizer->Show(ct_edit_box, ctb->GetSelection() != -1);
1213 ct_outer_sizer->Show(ct_count_label, ctb->GetSelection() == -1);
1215 case TREESECTION_FRAMES:
1216 mainbox->Show(f_outer_sizer, true);
1217 f_outer_sizer->Show(f_edit_box, fb->GetSelection() != -1);
1218 f_outer_sizer->Show(f_count_label, fb->GetSelection() == -1);
1220 case TREESECTION_SEQUENCES:
1221 menubar->SetLabel(EDIT_MENU_DELETE, _("Delete sequence"));
1222 if (mSelectedSequence > -1) {
1223 mainbox->Show(s_outer_sizer, true);
1224 menubar->Enable(EDIT_MENU_DELETE, true);
1226 mainbox->Show(dummy_sizer, true);
1234 // selection event in the bitmap browser
1235 void ShapesView::OnBitmapSelect(wxCommandEvent &e)
1237 int selection = e.GetInt();
1239 if (selection < 0) {
1241 b_view->SetBitmap(NULL);
1242 b_outer_sizer->Show(b_count_label, true);
1243 b_outer_sizer->Show(b_edit_box, false);
1244 menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete"));
1245 menubar->Enable(EDIT_MENU_COPY, false);
1246 menubar->Enable(EDIT_MENU_DELETE, false);
1247 menubar->Enable(EDIT_MENU_PASTE, false);
1248 menubar->Enable(SHAPES_MENU_EXPORTBITMAP, false);
1249 menubar->Enable(SHAPES_MENU_EXPORTMASK, false);
1251 ShapesBitmap *sel_bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, selection);
1254 wxString info_label = wxString::Format(wxT("%dx%d pixels, "), sel_bitmap->Width(), sel_bitmap->Height());
1256 if (sel_bitmap->BytesPerRow() > 0)
1257 info_label << wxT("plain encoding");
1259 info_label << wxT("RLE");
1260 b_info_label->SetLabel(info_label);
1261 b_edit_static_box->SetLabel(wxString::Format(wxT("Bitmap %d of %d"),
1262 selection, ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers)));
1263 // set flag check boxes
1264 b_order_checkbox->SetValue(sel_bitmap->IsColumnOrdered());
1265 b_transparency_checkbox->SetValue(sel_bitmap->IsTransparent());
1267 b_view->SetBitmap(sel_bitmap);
1268 b_outer_sizer->Show(b_count_label, false);
1269 b_outer_sizer->Show(b_edit_box, true);
1270 menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete bitmap"));
1271 menubar->Enable(EDIT_MENU_COPY, true);
1272 menubar->Enable(EDIT_MENU_DELETE, true);
1273 menubar->Enable(EDIT_MENU_PASTE, true);
1274 menubar->Enable(SHAPES_MENU_EXPORTBITMAP, true);
1275 menubar->Enable(SHAPES_MENU_EXPORTMASK, true);
1277 b_outer_sizer->Layout();
1280 // handle a delete event from the bitmap browser
1281 void ShapesView::BitmapDelete(wxCommandEvent &e)
1283 DoDeleteBitmap(e.GetSelection());
1286 void ShapesView::DoCopyBitmap(int which)
1288 ShapesBitmap* bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, which);
1289 ShapesColorTable* colorTable = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, mViewColorTable);
1291 bitmap->ClipboardCopy(colorTable);
1294 void ShapesView::DoDeleteColorTable(int which)
1297 // first do like a color table deselection
1298 ct_view->SetColorTable(NULL);
1299 ct_outer_sizer->Show(ct_count_label, true);
1300 ct_outer_sizer->Show(ct_edit_box, false);
1301 menubar->Enable(SHAPES_MENU_SAVECOLORTABLE, false);
1302 menubar->Enable(SHAPES_MENU_SAVECOLORTABLETOPS, false);
1303 menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete"));
1304 menubar->Enable(EDIT_MENU_COPY, false);
1305 menubar->Enable(EDIT_MENU_DELETE, false);
1306 menubar->Enable(EDIT_MENU_PASTE, false);
1310 ((ShapesDocument*)GetDocument())->DeleteColorTable(mSelectedColl, mSelectedVers, which);
1311 // update the view color table
1312 if (mViewColorTable == which) {
1313 mViewColorTable = 0;
1314 ShapesColorTable *ctp = ((ShapesDocument*)GetDocument())->GetColorTable(
1315 mSelectedColl, mSelectedVers, mViewColorTable);
1317 wxBeginBusyCursor();
1318 bb->SetColorTable(ctp);
1319 b_view->SetColorTable(ctp);
1320 fb->SetColorTable(ctp);
1321 f_view->SetColorTable(ctp);
1322 s_fb->SetColorTable(ctp);
1324 } else if (mViewColorTable > which) {
1325 mViewColorTable = mViewColorTable - 1;
1326 ShapesColorTable *ctp = ((ShapesDocument*)GetDocument())->GetColorTable(
1327 mSelectedColl, mSelectedVers, mViewColorTable);
1329 wxBeginBusyCursor();
1330 bb->SetColorTable(ctp);
1331 b_view->SetColorTable(ctp);
1332 fb->SetColorTable(ctp);
1333 f_view->SetColorTable(ctp);
1334 s_fb->SetColorTable(ctp);
1337 // reset other gui elements
1338 unsigned int colorTableCount = ((ShapesDocument*)GetDocument())->CollectionColorTableCount(
1339 mSelectedColl, mSelectedVers);
1341 for (unsigned int i = 0; i < colorTableCount; i++)
1342 ctb->AddColorTable(((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, i));
1344 wxMenu *colortables_submenu;
1345 menubar->FindItem(VIEW_MENU_COLORTABLE_0, &colortables_submenu);
1346 for (unsigned int i = 0; i < colortables_submenu->GetMenuItemCount(); i++) {
1347 menubar->Enable(VIEW_MENU_COLORTABLE_0 + i, i < colorTableCount);
1348 menubar->Check(VIEW_MENU_COLORTABLE_0 + mViewColorTable, i == (unsigned int)mViewColorTable);
1350 ((ShapesDocument*)GetDocument())->Modify(true);
1354 void ShapesView::DoDeleteBitmap(int which)
1357 // fist make sure no GUI element references that bitmap anymore
1359 bb->Clear(); // FIXME just remove that bitmap
1361 fb->ClearBitmaps(); // FIXME just remove that bitmap
1362 b_outer_sizer->Show(b_count_label, true);
1363 b_outer_sizer->Show(b_edit_box, false);
1364 b_view->SetBitmap(NULL);
1366 ((ShapesDocument*)GetDocument())->DeleteBitmap(mSelectedColl, mSelectedVers, which);
1368 unsigned int bitmap_count = ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers);
1370 for (unsigned int i = 0; i < bitmap_count; i++) {
1371 ShapesBitmap *bmp = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, i);
1377 fb->RebuildThumbnails(); // FIXME just rebuild dirty frames
1380 wxString count_string;
1382 count_string << bitmap_count << wxT(" bitmap");
1383 if (bitmap_count != 1)
1384 count_string << wxT("s");
1385 b_count_label->SetLabel(count_string);
1387 ((ShapesDocument*)GetDocument())->Modify(true);
1391 void ShapesView::DoDeleteFrame(int which)
1394 // first make sure no GUI element references that frame anymore
1396 fb->Clear(); // FIXME just remove THAT frame
1397 f_outer_sizer->Show(f_count_label, true);
1398 f_outer_sizer->Show(f_edit_box, false);
1399 f_view->SetFrame(NULL);
1401 ((ShapesDocument*)GetDocument())->DeleteFrame(mSelectedColl, mSelectedVers, which);
1403 unsigned int frame_count = ((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers),
1404 bitmap_count = ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers);
1406 for (unsigned int i = 0; i < bitmap_count; i++)
1407 fb->AddBitmap(((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, i));
1408 for (unsigned int i = 0; i < frame_count; i++)
1409 fb->AddFrame(((ShapesDocument*)GetDocument())->GetFrame(mSelectedColl, mSelectedVers, i));
1412 wxString count_string;
1414 count_string << frame_count << wxT(" frame");
1415 if (frame_count != 1)
1416 count_string << wxT("s");
1417 f_count_label->SetLabel(count_string);
1419 ((ShapesDocument*)GetDocument())->Modify(true);
1423 void ShapesView::DoPasteBitmap(int which)
1425 ShapesBitmap* bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, which);
1426 ShapesColorTable* colorTable = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, mViewColorTable);
1428 wxBeginBusyCursor();
1429 bitmap->ClipboardPaste(colorTable);
1431 // automagically initialize bitmap flags
1432 if (((ShapesDocument*)GetDocument())->CollectionType(mSelectedColl, mSelectedVers) == _object_collection ||
1433 ((ShapesDocument*)GetDocument())->CollectionType(mSelectedColl, mSelectedVers) == _scenery_collection) {
1434 // compress weapons, monsters and scenery
1435 bitmap->SetBytesPerRow(-1);
1436 } else if (((ShapesDocument*)GetDocument())->CollectionType(mSelectedColl, mSelectedVers) == _interface_collection) {
1437 // interface elements are row-ordered (not so important with A1 actually)
1438 bitmap->SetColumnOrdered(false);
1441 ((ShapesDocument*)GetDocument())->Modify(true);
1442 bb->RebuildThumbnail(bb->GetSelection());
1444 b_view->SetBitmap(bitmap);
1446 fb->RebuildThumbnails();
1451 void ShapesView::DoCopyChunk(unsigned int coll, unsigned int chunk)
1453 ShapesChunk* c = ((ShapesDocument*)GetDocument())->GetChunk(coll, chunk);
1459 void ShapesView::DoPasteChunk(unsigned int coll, unsigned int chunk)
1461 ShapesChunk* c = ((ShapesDocument*)GetDocument())->GetChunk(coll, chunk);
1463 c->ClipboardPaste();
1464 ((ShapesDocument*)GetDocument())->Modify(true);
1467 mSelectedSequence = -1;
1469 colltree->DeleteAllItems();
1474 void ShapesView::ToggleBitmapCheckboxes(wxCommandEvent &e)
1476 ShapesBitmap *sel_bitmap = b_view->GetBitmap();
1478 if (sel_bitmap != NULL) {
1479 switch (e.GetId()) {
1480 case CB_COLUMN_ORDER:
1481 sel_bitmap->SetColumnOrdered(e.IsChecked());
1482 ((ShapesDocument*)GetDocument())->Modify(true);
1484 case CB_ENABLE_TRANSPARENCY:
1485 sel_bitmap->SetTransparent(e.IsChecked());
1486 bb->RebuildThumbnail(bb->GetSelection());
1488 b_view->SetBitmap(sel_bitmap);
1489 // FIXME also update the FrameBrowser and all that
1490 ((ShapesDocument*)GetDocument())->Modify(true);
1496 // callback for selections in the color table browser
1497 void ShapesView::OnCTSelect(wxCommandEvent &e)
1499 int selection = e.GetInt();
1501 if (selection < 0) {
1503 ct_view->SetColorTable(NULL);
1504 ct_outer_sizer->Show(ct_count_label, true);
1505 ct_outer_sizer->Show(ct_edit_box, false);
1506 menubar->Enable(SHAPES_MENU_SAVECOLORTABLE, false);
1507 menubar->Enable(SHAPES_MENU_SAVECOLORTABLETOPS, false);
1508 menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete"));
1509 menubar->Enable(EDIT_MENU_COPY, false);
1510 menubar->Enable(EDIT_MENU_DELETE, false);
1511 menubar->Enable(EDIT_MENU_PASTE, false);
1514 ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, selection);
1516 ct_view->SetColorTable(ct);
1517 ct_edit_static_box->SetLabel(wxString::Format(wxT("Color table %d of %d, %d colors per table"), selection,
1518 ((ShapesDocument*)GetDocument())->CollectionColorTableCount(mSelectedColl, mSelectedVers),
1520 ct_outer_sizer->Show(ct_count_label, false);
1521 ct_outer_sizer->Show(ct_edit_box, true);
1522 menubar->Enable(SHAPES_MENU_SAVECOLORTABLE, true);
1523 menubar->Enable(SHAPES_MENU_SAVECOLORTABLETOPS, true);
1524 menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete color table"));
1525 // FIXME make sure there is at least one color table for now
1526 if (((ShapesDocument*)GetDocument())->CollectionColorTableCount(mSelectedColl, mSelectedVers) > 1)
1527 menubar->Enable(EDIT_MENU_DELETE, true);
1529 menubar->Enable(EDIT_MENU_DELETE, false);
1530 menubar->Enable(EDIT_MENU_COPY, false);
1531 menubar->Enable(EDIT_MENU_PASTE, false);
1533 ct_self_lumin_checkbox->Disable();
1534 ct_gradient_button->Disable();
1535 ct_outer_sizer->Layout();
1538 // callback for color selections in the color table editor
1539 void ShapesView::CTColorSelect(wxCommandEvent &e)
1541 ct_self_lumin_checkbox->Disable();
1542 ct_gradient_button->Disable();
1543 switch (e.GetInt()) {
1544 default: // more colors selected
1545 ct_gradient_button->Enable();
1546 case 1: // just one color selected
1547 ct_self_lumin_checkbox->Enable();
1548 // set the checkbox value
1550 ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl,
1551 mSelectedVers, ctb->GetSelection());
1552 vector<bool> selection = ct_view->GetSelection();
1553 bool someAreOn = false,
1556 for (unsigned int i = 0; i < selection.size(); i++) {
1558 if (ct->GetColor(i)->Luminescent())
1564 if (someAreOn && someAreOff)
1565 ct_self_lumin_checkbox->Set3StateValue(wxCHK_UNDETERMINED);
1566 else if (someAreOn && !someAreOff)
1567 ct_self_lumin_checkbox->Set3StateValue(wxCHK_CHECKED);
1569 ct_self_lumin_checkbox->Set3StateValue(wxCHK_UNCHECKED);
1571 case 0: // no colors selected
1576 // callback for color alteration in the color table editor
1577 void ShapesView::CTColorChanged(wxCommandEvent &e)
1579 ((ShapesDocument*)GetDocument())->Modify(true);
1581 // refresh thumbnails if needed
1582 if (ctb->GetSelection() == mViewColorTable) {
1584 bb->RebuildThumbnails();
1587 fb->RebuildThumbnails();
1592 // callback for the "self luminescent color" checkbox
1593 void ShapesView::ToggleSelfLuminCheckbox(wxCommandEvent &e)
1595 ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl,
1596 mSelectedVers, ctb->GetSelection());
1597 vector<bool> selection = ct_view->GetSelection();
1599 for (unsigned int i = 0; i < selection.size(); i++) {
1601 ct->GetColor(i)->SetLuminescent(e.IsChecked());
1603 ((ShapesDocument*)GetDocument())->Modify(true);
1606 // TODO invalidate thumbnails if needed
1609 // callback for the "make gradient" button in the color table editor
1610 void ShapesView::MakeCTGradient(wxCommandEvent &e)
1612 vector<bool> selection = ct_view->GetSelection();
1613 int firstIndex = -1, lastIndex = -1;
1615 // find first and last selected items
1616 for (unsigned int i = 0; i < selection.size(); i++) {
1618 if (firstIndex == -1)
1623 if (firstIndex > -1 && firstIndex < lastIndex) {
1624 // linearly interpolate colors in between
1625 ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl,
1626 mSelectedVers, ctb->GetSelection());
1627 int r1 = ct->GetColor(firstIndex)->Red(),
1628 g1 = ct->GetColor(firstIndex)->Green(),
1629 b1 = ct->GetColor(firstIndex)->Blue(),
1630 r2 = ct->GetColor(lastIndex)->Red(),
1631 g2 = ct->GetColor(lastIndex)->Green(),
1632 b2 = ct->GetColor(lastIndex)->Blue(),
1633 delta = lastIndex - firstIndex;
1635 for (int k = firstIndex+1; k < lastIndex; k++) {
1636 ShapesColor *color = ct->GetColor(k);
1638 color->SetRed(r1 + (r2-r1)*(k-firstIndex)/delta);
1639 color->SetGreen(g1 + (g2-g1)*(k-firstIndex)/delta);
1640 color->SetBlue(b1 + (b2-b1)*(k-firstIndex)/delta);
1643 ((ShapesDocument*)GetDocument())->Modify(true);
1646 // refresh thumbnails if needed
1647 if (ctb->GetSelection() == mViewColorTable) {
1649 bb->RebuildThumbnails();
1652 fb->RebuildThumbnails();
1657 // callback for selections in the frame browser
1658 void ShapesView::OnFrameSelect(wxCommandEvent &e)
1660 int selection = e.GetInt();
1662 if (selection < 0) {
1663 f_view->SetFrame(NULL);
1664 f_view->SetBitmap(NULL);
1665 f_outer_sizer->Show(f_count_label, true);
1666 f_outer_sizer->Show(f_edit_box, false);
1667 menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete"));
1668 menubar->Enable(EDIT_MENU_COPY, false);
1669 menubar->Enable(EDIT_MENU_DELETE, false);
1670 menubar->Enable(EDIT_MENU_PASTE, false);
1672 ShapesFrame *sel_frame = ((ShapesDocument*)GetDocument())->GetFrame(mSelectedColl, mSelectedVers, selection);
1673 ShapesBitmap *assoc_bitmap = NULL;
1676 f_edit_static_box->SetLabel(wxString::Format(wxT("Frame %d of %u"),
1677 selection, ((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers)));
1679 f_view->SetFrame(sel_frame);
1680 if (sel_frame->BitmapIndex() >= 0)
1681 assoc_bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, sel_frame->BitmapIndex());
1682 f_view->SetBitmap(assoc_bitmap);
1684 f_bitmap_id->SetRange(-1, ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers) - 1);
1685 f_bitmap_id->SetValue(sel_frame->BitmapIndex());
1686 f_xmirror_checkbox->SetValue(sel_frame->IsXmirrored());
1687 f_ymirror_checkbox->SetValue(sel_frame->IsYmirrored());
1688 f_keypoint_checkbox->SetValue(sel_frame->IsKeypointObscured());
1689 f_origin_x_field->ChangeValue(INT_TO_WXSTRING(sel_frame->OriginX()));
1690 f_origin_y_field->ChangeValue(INT_TO_WXSTRING(sel_frame->OriginY()));
1691 f_key_x_field->ChangeValue(INT_TO_WXSTRING(sel_frame->KeyX()));
1692 f_key_y_field->ChangeValue(INT_TO_WXSTRING(sel_frame->KeyY()));
1693 f_scalefactor_field->ChangeValue(INT_TO_WXSTRING(sel_frame->ScaleFactor()));
1694 f_mli_field->ChangeValue(INT_TO_WXSTRING((int)roundf(sel_frame->MinimumLightIntensity() * 100.0)));
1695 f_outer_sizer->Show(f_count_label, false);
1696 f_outer_sizer->Show(f_edit_box, true);
1697 menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete frame"));
1698 menubar->Enable(EDIT_MENU_DELETE, true);
1699 menubar->Enable(EDIT_MENU_COPY, false);
1700 menubar->Enable(EDIT_MENU_PASTE, false);
1702 f_outer_sizer->Layout();
1705 // handle a delete event from the frame browser
1706 void ShapesView::FrameDelete(wxCommandEvent &e)
1708 DoDeleteFrame(e.GetSelection());
1711 // handle an event from the FrameView: update the values
1712 // in the fields and mark the document as modified
1713 void ShapesView::OnFramePointDrag(wxCommandEvent &e)
1715 ShapesFrame *frame = f_view->GetFrame();
1717 if (frame != NULL) {
1718 f_origin_x_field->ChangeValue(INT_TO_WXSTRING(frame->OriginX()));
1719 f_origin_y_field->ChangeValue(INT_TO_WXSTRING(frame->OriginY()));
1720 f_key_x_field->ChangeValue(INT_TO_WXSTRING(frame->KeyX()));
1721 f_key_y_field->ChangeValue(INT_TO_WXSTRING(frame->KeyY()));
1722 ((ShapesDocument*)GetDocument())->Modify(true);
1726 // bitmap index change in the frame panel
1727 void ShapesView::BitmapIndexSpin(wxSpinEvent &e)
1729 int newid = e.GetPosition();
1730 ShapesFrame *sel_frame = f_view->GetFrame();
1732 if (sel_frame != NULL) {
1733 sel_frame->SetBitmapIndex(newid);
1734 f_view->SetBitmap(((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, newid));
1735 f_view->SetFrame(sel_frame);
1736 fb->RebuildThumbnail(fb->GetSelection());
1738 ((ShapesDocument*)GetDocument())->Modify(true);
1742 // checkbox toggle in the frame panel
1743 void ShapesView::ToggleFrameCheckboxes(wxCommandEvent &e)
1745 ShapesFrame *sel_frame = f_view->GetFrame();
1747 if (sel_frame != NULL) {
1748 switch (e.GetId()) {
1749 case CB_XMIRROR: sel_frame->SetXmirrored(e.IsChecked()); break;
1750 case CB_YMIRROR: sel_frame->SetYmirrored(e.IsChecked()); break;
1751 case CB_KEYPOINT: sel_frame->SetKeypointObscured(e.IsChecked()); break;
1754 if (e.GetId() != CB_KEYPOINT) {
1755 fb->RebuildThumbnail(fb->GetSelection());
1757 f_view->SetFrame(sel_frame);
1759 ((ShapesDocument*)GetDocument())->Modify(true);
1763 // user messed with fields in the frame panel
1764 void ShapesView::EditFrameFields(wxCommandEvent &e)
1766 ShapesFrame *sel_frame = f_view->GetFrame();
1767 wxString s = e.GetString();
1769 if (sel_frame != NULL) {
1773 bool recalculate_world_fields = false;
1775 switch (e.GetId()) {
1776 case FIELD_ORIGIN_X:
1777 sel_frame->SetOriginX(v);
1778 recalculate_world_fields = true;
1780 case FIELD_ORIGIN_Y:
1781 sel_frame->SetOriginY(v);
1782 recalculate_world_fields = true;
1785 sel_frame->SetKeyX(v);
1786 recalculate_world_fields = true;
1789 sel_frame->SetKeyY(v);
1790 recalculate_world_fields = true;
1792 case FIELD_FRAME_SCALEFACTOR:
1793 sel_frame->SetScaleFactor(v);
1794 recalculate_world_fields = true;
1796 case FIELD_MIN_LIGHT_INT:
1799 f_mli_field->ChangeValue(wxT("100"));
1803 f_mli_field->ChangeValue(wxT("0"));
1806 sel_frame->SetMinimumLightIntensity(v / 100.0);
1809 // recalculate world_* fields if needed and possible
1810 if (recalculate_world_fields && sel_frame->BitmapIndex() >= 0
1811 && sel_frame->BitmapIndex() < (int)((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers)) {
1812 ShapesBitmap *assoc_bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, sel_frame->BitmapIndex());
1813 int w = assoc_bitmap->Width(),
1814 h = assoc_bitmap->Height(),
1815 scale_factor = sel_frame->ScaleFactor();
1817 sel_frame->SetWorldLeft(-scale_factor * sel_frame->OriginX());
1818 sel_frame->SetWorldTop(scale_factor * sel_frame->OriginY());
1819 sel_frame->SetWorldRight(scale_factor * (w - sel_frame->OriginX()));
1820 sel_frame->SetWorldBottom(-scale_factor * (h - sel_frame->OriginY()));
1821 sel_frame->SetWorldX0(scale_factor * (sel_frame->KeyX() - sel_frame->OriginX()));
1822 sel_frame->SetWorldY0(-scale_factor * (sel_frame->KeyY() - sel_frame->OriginY()));
1825 ((ShapesDocument*)GetDocument())->Modify(true);
1830 // callback for "delete sequence" button clicks
1831 void ShapesView::DeleteSequence(wxCommandEvent &e)
1833 // first delete the sequence for real
1834 ((ShapesDocument*)GetDocument())->DeleteSequence(mSelectedColl, mSelectedVers, mSelectedSequence);
1836 // for updating the tree control we could just delete the selected
1837 // sequence item, but then ShapesTreeItemData structures associated
1838 // to the following items would be broken and everything would crash.
1839 // We could correct them, but reinserting all items is simpler.
1840 wxTreeItemId seqnode = GetSequencesTreeItem(mSelectedColl, mSelectedVers);
1842 colltree->SelectItem(seqnode);
1843 colltree->DeleteChildren(seqnode);
1844 for (unsigned int k = 0; k < ((ShapesDocument*)GetDocument())->CollectionSequenceCount(mSelectedColl, mSelectedVers); k++) {
1845 ShapesSequence *seq = ((ShapesDocument*)GetDocument())->GetSequence(mSelectedColl, mSelectedVers, k);
1847 ShapesTreeItemData *seqdata = new ShapesTreeItemData(mSelectedColl, mSelectedVers, TREESECTION_SEQUENCES, k);
1850 if (seq->Name().Len() > 0)
1851 label << wxT(" - ") << seq->Name();
1852 colltree->AppendItem(seqnode, label, -1, -1, seqdata);
1855 mSelectedSequence = -1;
1856 ((ShapesDocument*)GetDocument())->Modify(true);
1859 // sequence type menu in the sequence editor
1860 void ShapesView::EditSequenceType(wxCommandEvent &e)
1862 if (mSelectedSequence >= 0) {
1863 ShapesSequence *sel_seq = ((ShapesDocument*)GetDocument())->GetSequence(mSelectedColl, mSelectedVers, mSelectedSequence);
1864 int real_nov, old_nov;
1866 old_nov = ActualNumberOfViews(sel_seq->NumberOfViews());
1867 // always use ANIMATED_4, ANIMATED_5, ANIMATED_8
1868 // and never other values like ANIMATED_3TO4. Apparently
1869 // nobody knows the real meaning of these values
1870 switch (s_type_menu->GetSelection()) {
1871 case 0: sel_seq->SetNumberOfViews(UNANIMATED); break;
1872 case 1: sel_seq->SetNumberOfViews(ANIMATED_1); break;
1873 case 2: sel_seq->SetNumberOfViews(ANIMATED_4); break;
1874 case 3: sel_seq->SetNumberOfViews(ANIMATED_5); break;
1875 case 4: sel_seq->SetNumberOfViews(ANIMATED_8); break;
1877 real_nov = ActualNumberOfViews(sel_seq->NumberOfViews());
1879 // Let's handle sequence frames changes...
1880 if (real_nov > old_nov) {
1881 // We are adding one (or more) view
1882 // We need to add FramesPerView() * (real_nov - old_nov)
1883 // to the END of the frame_index array
1884 for (int i = 0; i < sel_seq->FramesPerView() * (real_nov - old_nov); i++)
1885 sel_seq->mFrameIndexes.push_back(-1);
1886 } else if (real_nov < old_nov) {
1887 // We are removing one (or more) view
1888 // We need to remove FramesPerView() * (old_nov - real_nov)
1889 // from the END of the frame_index array
1890 for (int i = 0; i < sel_seq->FramesPerView() * (old_nov - real_nov); i++)
1891 sel_seq->mFrameIndexes.pop_back();
1893 // Hmm, number of views unchanged, don't bother...
1895 s_fb->SetSeqParameters(sel_seq->NumberOfViews(), sel_seq->FramesPerView(), &sel_seq->mFrameIndexes, this);
1896 ((ShapesDocument*)GetDocument())->Modify(true);
1900 // transfer mode menu in the sequence editor
1901 void ShapesView::EditSequenceXferMode(wxCommandEvent &e)
1903 if (mSelectedSequence >= 0) {
1904 ShapesSequence *sel_seq = ((ShapesDocument*)GetDocument())->GetSequence(mSelectedColl, mSelectedVers, mSelectedSequence);
1906 sel_seq->SetTransferMode(s_xfermode_menu->GetSelection());
1907 ((ShapesDocument*)GetDocument())->Modify(true);
1911 // user messed with fields in the sequence editor
1912 void ShapesView::EditSequenceFields(wxCommandEvent &e)
1914 if (mSelectedSequence >= 0) {
1915 ShapesSequence *sel_seq = ((ShapesDocument*)GetDocument())->GetSequence(mSelectedColl, mSelectedVers, mSelectedSequence);
1916 wxString s = e.GetString();
1918 if (sel_seq != NULL) {
1919 if (e.GetId() == FIELD_SEQ_NAME) {
1920 sel_seq->SetName(s.Left(32));
1921 // update the tree item label
1922 wxTreeItemId seqnode = GetSequencesTreeItem(mSelectedColl, mSelectedVers);
1923 wxTreeItemIdValue cookie;
1924 wxTreeItemId id = colltree->GetFirstChild(seqnode, cookie);
1927 ShapesTreeItemData *itemdata = dynamic_cast<ShapesTreeItemData *>(colltree->GetItemData(id));
1929 if (itemdata->Sequence() == mSelectedSequence) {
1933 blabel << mSelectedSequence;
1934 if (sel_seq->Name().Length() > 0)
1935 blabel << wxT(" - ") << sel_seq->Name();
1936 colltree->SetItemText(id, blabel);
1939 id = colltree->GetNextChild(seqnode, cookie);
1941 ((ShapesDocument*)GetDocument())->Modify(true);
1947 switch (e.GetId()) {
1948 case FIELD_SEQ_FRAMES_PER_VIEW:
1949 // must update the SequenceView too
1950 if (v != sel_seq->FramesPerView()) {
1951 int real_nov = ActualNumberOfViews(sel_seq->NumberOfViews()),
1952 old_fpv = sel_seq->FramesPerView();
1953 short old_indexes[real_nov * old_fpv];
1955 for (int i = 0; i < real_nov * old_fpv; i++)
1956 old_indexes[i] = sel_seq->mFrameIndexes[i];
1957 sel_seq->SetFramesPerView(v);
1958 // try to preserve existing frame
1959 // references as much as possible
1960 sel_seq->mFrameIndexes.clear();
1961 for (int i = 0; i < real_nov; i++) {
1962 for (int j = 0; j < v; j++) {
1964 sel_seq->mFrameIndexes.push_back(old_indexes[i*old_fpv + j]);
1966 sel_seq->mFrameIndexes.push_back(-1);
1969 s_fb->SetSeqParameters(sel_seq->NumberOfViews(), v, &sel_seq->mFrameIndexes, this);
1972 case FIELD_SEQ_TICKS_PER_FRAME:
1973 sel_seq->SetTicksPerFrame(v);
1975 case FIELD_SEQ_LOOP_FRAME:
1976 sel_seq->SetLoopFrame(v);
1978 case FIELD_SEQ_KEY_FRAME:
1979 sel_seq->SetKeyFrame(v);
1981 case FIELD_SEQ_XFER_MODE_PERIOD:
1982 sel_seq->SetTransferModePeriod(v);
1984 case FIELD_SEQ_FIRST_FRAME_SND:
1985 sel_seq->SetFirstFrameSound(v);
1987 case FIELD_SEQ_KEY_FRAME_SND:
1988 sel_seq->SetKeyFrameSound(v);
1990 case FIELD_SEQ_LAST_FRAME_SND:
1991 sel_seq->SetLastFrameSound(v);
1994 ((ShapesDocument*)GetDocument())->Modify(true);