diff --git a/src/commands/cmd_export_sprite_sheet.cpp b/src/commands/cmd_export_sprite_sheet.cpp index a21a3105d..4dbbf724b 100644 --- a/src/commands/cmd_export_sprite_sheet.cpp +++ b/src/commands/cmd_export_sprite_sheet.cpp @@ -108,7 +108,7 @@ protected: void onSheetTypeChange() { bool state = false; - switch (m_sheetType.getSelectedItem()) { + switch (m_sheetType.getSelectedItemIndex()) { case Matrix: state = true; break; @@ -130,7 +130,7 @@ protected: FrameNumber nframes = sprite->getTotalFrames(); int columns; - switch (m_sheetType.getSelectedItem()) { + switch (m_sheetType.getSelectedItemIndex()) { case HorizontalStrip: columns = nframes; break; @@ -219,7 +219,7 @@ protected: bool undo = false; // Do the "Export Action" - switch (m_exportAction.getSelectedItem()) { + switch (m_exportAction.getSelectedItemIndex()) { case SaveCopyAs: { diff --git a/src/commands/cmd_options.cpp b/src/commands/cmd_options.cpp index 0cb1735df..134e10c1e 100644 --- a/src/commands/cmd_options.cpp +++ b/src/commands/cmd_options.cpp @@ -117,7 +117,7 @@ void OptionsCommand::onExecute(Context* context) m_checked_bg->addItem("8x8"); m_checked_bg->addItem("4x4"); m_checked_bg->addItem("2x2"); - m_checked_bg->setSelectedItem((int)RenderEngine::getCheckedBgType()); + m_checked_bg->setSelectedItemIndex((int)RenderEngine::getCheckedBgType()); // Zoom checked background if (RenderEngine::getCheckedBgZoom()) @@ -154,7 +154,7 @@ void OptionsCommand::onExecute(Context* context) set_config_bool("Options", "MoveClick2", move_click2->isSelected()); set_config_bool("Options", "DrawClick2", draw_click2->isSelected()); - RenderEngine::setCheckedBgType((RenderEngine::CheckedBgType)m_checked_bg->getSelectedItem()); + RenderEngine::setCheckedBgType((RenderEngine::CheckedBgType)m_checked_bg->getSelectedItemIndex()); RenderEngine::setCheckedBgZoom(m_checked_bg_zoom->isSelected()); RenderEngine::setCheckedBgColor1(m_checked_bg_color1->getColor()); RenderEngine::setCheckedBgColor2(m_checked_bg_color2->getColor()); diff --git a/src/commands/cmd_sprite_size.cpp b/src/commands/cmd_sprite_size.cpp index 2c93a5637..5ddea76df 100644 --- a/src/commands/cmd_sprite_size.cpp +++ b/src/commands/cmd_sprite_size.cpp @@ -221,7 +221,7 @@ void SpriteSizeCommand::onExecute(Context* context) method->addItem("Nearest-neighbor"); method->addItem("Bilinear"); - method->setSelectedItem(get_config_int("SpriteSize", "Method", RESIZE_METHOD_NEAREST_NEIGHBOR)); + method->setSelectedItemIndex(get_config_int("SpriteSize", "Method", RESIZE_METHOD_NEAREST_NEIGHBOR)); window->remapWindow(); window->centerWindow(); @@ -235,7 +235,7 @@ void SpriteSizeCommand::onExecute(Context* context) int new_width = m_widthPx->getTextInt(); int new_height = m_heightPx->getTextInt(); ResizeMethod resize_method = - (ResizeMethod)method->getSelectedItem(); + (ResizeMethod)method->getSelectedItemIndex(); set_config_int("SpriteSize", "Method", resize_method); diff --git a/src/ui/combobox.cpp b/src/ui/combobox.cpp index 79fb3ae88..935089fa5 100644 --- a/src/ui/combobox.cpp +++ b/src/ui/combobox.cpp @@ -9,8 +9,6 @@ #include "base/compiler_specific.h" #include "gfx/size.h" #include "ui/gui.h" -#include "ui/listitem.h" -#include "ui/preferred_size_event.h" #include @@ -49,7 +47,22 @@ class ComboBoxListBox : public ListBox { public: ComboBoxListBox(ComboBox* comboBox) - : m_comboBox(comboBox) { + : m_comboBox(comboBox) + { + for (ComboBox::ListItems::iterator + it = comboBox->begin(), end = comboBox->end(); it != end; ++it) + addChild(*it); + } + + void clean() + { + // Remove all added items so ~Widget() don't delete them. + while (getLastChild()) + removeChild(getLastChild()); + + ASSERT(getChildren().empty()); + + selectChild(NULL); } protected: @@ -64,14 +77,6 @@ private: ComboBox* m_comboBox; }; -struct ComboBox::Item -{ - std::string text; - void* data; - - Item() : data(NULL) { } -}; - ComboBox::ComboBox() : Widget(JI_COMBOBOX) { @@ -144,37 +149,55 @@ bool ComboBox::isCaseSensitive() return m_casesensitive; } -int ComboBox::addItem(const std::string& text) +int ComboBox::addItem(ListItem* item) { bool sel_first = m_items.empty(); - Item* item = new Item(); - item->text = text; m_items.push_back(item); if (sel_first) - setSelectedItem(0); + setSelectedItemIndex(0); return m_items.size()-1; } -void ComboBox::insertItem(int itemIndex, const std::string& text) +int ComboBox::addItem(const char* text) +{ + return addItem(new ListItem(text)); +} + +void ComboBox::insertItem(int itemIndex, ListItem* item) { bool sel_first = m_items.empty(); - Item* item = new Item(); - item->text = text; m_items.insert(m_items.begin() + itemIndex, item); if (sel_first) - setSelectedItem(0); + setSelectedItemIndex(0); +} + +void ComboBox::insertItem(int itemIndex, const char* text) +{ + insertItem(itemIndex, new ListItem(text)); +} + +void ComboBox::removeItem(ListItem* item) +{ + ListItems::iterator it = std::find(m_items.begin(), m_items.end(), item); + + ASSERT(it != m_items.end()); + + if (it != m_items.end()) + m_items.erase(it); + + // Do not delete the given "item" } void ComboBox::removeItem(int itemIndex) { ASSERT(itemIndex >= 0 && (size_t)itemIndex < m_items.size()); - Item* item = m_items[itemIndex]; + ListItem* item = m_items[itemIndex]; m_items.erase(m_items.begin() + itemIndex); delete item; @@ -182,46 +205,55 @@ void ComboBox::removeItem(int itemIndex) void ComboBox::removeAllItems() { - std::vector::iterator it, end = m_items.end(); + ListItems::iterator it, end = m_items.end(); for (it = m_items.begin(); it != end; ++it) delete *it; m_items.clear(); } -int ComboBox::getItemCount() +int ComboBox::getItemCount() const { return m_items.size(); } -std::string ComboBox::getItemText(int itemIndex) +ListItem* ComboBox::getItem(int itemIndex) { if (itemIndex >= 0 && (size_t)itemIndex < m_items.size()) { - Item* item = m_items[itemIndex]; - return item->text; + return m_items[itemIndex]; + } + else + return NULL; +} + +const char* ComboBox::getItemText(int itemIndex) const +{ + if (itemIndex >= 0 && (size_t)itemIndex < m_items.size()) { + ListItem* item = m_items[itemIndex]; + return item->getText(); } else return ""; } -void ComboBox::setItemText(int itemIndex, const std::string& text) +void ComboBox::setItemText(int itemIndex, const char* text) { ASSERT(itemIndex >= 0 && (size_t)itemIndex < m_items.size()); - Item* item = m_items[itemIndex]; - item->text = text; + ListItem* item = m_items[itemIndex]; + item->setText(text); } -int ComboBox::findItemIndex(const std::string& text) +int ComboBox::findItemIndex(const char* text) { int itemIndex = 0; - std::vector::iterator it, end = m_items.end(); + ListItems::iterator it, end = m_items.end(); for (it = m_items.begin(); it != end; ++it) { - Item* item = *it; + ListItem* item = *it; - if ((m_casesensitive && ustrcmp(item->text.c_str(), text.c_str()) == 0) || - (!m_casesensitive && ustricmp(item->text.c_str(), text.c_str()) == 0)) { + if ((m_casesensitive && ustrcmp(item->getText(), text) == 0) || + (!m_casesensitive && ustricmp(item->getText(), text) == 0)) { return itemIndex; } @@ -231,40 +263,37 @@ int ComboBox::findItemIndex(const std::string& text) return -1; } -int ComboBox::getSelectedItem() +ListItem* ComboBox::getSelectedItem() const { - return !m_items.empty() ? m_selected: -1; + return (!m_items.empty() ? m_items[m_selected]: NULL); } -void ComboBox::setSelectedItem(int itemIndex) +void ComboBox::setSelectedItem(ListItem* item) +{ + ListItems::iterator it = std::find(m_items.begin(), m_items.end(), item); + + ASSERT(it != m_items.end()); + + if (it != m_items.end()) + setSelectedItemIndex(std::distance(m_items.begin(), it)); +} + +int ComboBox::getSelectedItemIndex() const +{ + return (!m_items.empty() ? m_selected: -1); +} + +void ComboBox::setSelectedItemIndex(int itemIndex) { if (itemIndex >= 0 && (size_t)itemIndex < m_items.size()) { m_selected = itemIndex; - std::vector::iterator it = m_items.begin() + itemIndex; - Item* item = *it; - m_entry->setText(item->text.c_str()); + ListItems::iterator it = m_items.begin() + itemIndex; + ListItem* item = *it; + m_entry->setText(item->getText()); } } -void* ComboBox::getItemData(int itemIndex) -{ - if (itemIndex >= 0 && (size_t)itemIndex < m_items.size()) { - Item* item = m_items[itemIndex]; - return item->data; - } - else - return NULL; -} - -void ComboBox::setItemData(int itemIndex, void* data) -{ - ASSERT(itemIndex >= 0 && (size_t)itemIndex < m_items.size()); - - Item* item = m_items[itemIndex]; - item->data = data; -} - Entry* ComboBox::getEntryWidget() { return m_entry; @@ -329,11 +358,11 @@ void ComboBox::onPreferredSize(PreferredSizeEvent& ev) Size entrySize = m_entry->getPreferredSize(); // Get the text-length of every item and put in 'w' the maximum value - std::vector::iterator it, end = m_items.end(); + ListItems::iterator it, end = m_items.end(); for (it = m_items.begin(); it != end; ++it) { int item_w = 2*jguiscale()+ - text_length(this->getFont(), (*it)->text.c_str())+ + text_length(this->getFont(), (*it)->getText())+ 10*jguiscale(); reqSize.w = MAX(reqSize.w, item_w); @@ -399,7 +428,7 @@ bool ComboBoxListBox::onProcessMessage(Message* msg) case JM_BUTTONRELEASED: { - int index = m_comboBox->getSelectedItem(); + int index = m_comboBox->getSelectedItemIndex(); if (isValidItem(index)) m_comboBox->onChange(); @@ -428,7 +457,7 @@ void ComboBoxListBox::onChangeSelectedItem() int index = getSelectedIndex(); if (isValidItem(index)) - m_comboBox->setSelectedItem(index); + m_comboBox->setSelectedItemIndex(index); } // When the mouse is clicked we switch the visibility-status of the list-box @@ -443,13 +472,6 @@ void ComboBox::openListBox() m_window = new Window(false, NULL); View* view = new View(); m_listbox = new ComboBoxListBox(this); - - std::vector::iterator it, end = m_items.end(); - for (it = m_items.begin(); it != end; ++it) { - Item* item = *it; - m_listbox->addChild(new ListItem(item->text.c_str())); - } - m_window->setOnTop(true); jwidget_noborders(m_window); @@ -483,6 +505,8 @@ void ComboBox::openListBox() void ComboBox::closeListBox() { if (m_window) { + m_listbox->clean(); + m_window->closeWindow(this); delete m_window; // window, frame m_window = NULL; diff --git a/src/ui/combobox.h b/src/ui/combobox.h index 677600934..223e62e2b 100644 --- a/src/ui/combobox.h +++ b/src/ui/combobox.h @@ -19,6 +19,7 @@ namespace ui { class Button; class Entry; class ListBox; + class ListItem; class Window; class ComboBoxListBox; @@ -28,9 +29,14 @@ namespace ui { friend class ComboBoxListBox; public: + typedef std::vector ListItems; + ComboBox(); ~ComboBox(); + ListItems::iterator begin() { return m_items.begin(); } + ListItems::iterator end() { return m_items.end(); } + void setEditable(bool state); void setClickOpen(bool state); void setCaseSensitive(bool state); @@ -39,22 +45,31 @@ namespace ui { bool isClickOpen(); bool isCaseSensitive(); - int addItem(const std::string& text); - void insertItem(int itemIndex, const std::string& text); + int addItem(ListItem* item); + int addItem(const char* text); + void insertItem(int itemIndex, ListItem* item); + void insertItem(int itemIndex, const char* text); + + // Removes the given item (you must delete it). + void removeItem(ListItem* item); + + // Removes and deletes the given item. void removeItem(int itemIndex); + void removeAllItems(); - int getItemCount(); + int getItemCount() const; - std::string getItemText(int itemIndex); - void setItemText(int itemIndex, const std::string& text); - int findItemIndex(const std::string& text); + ListItem* getItem(int itemIndex); + const char* getItemText(int itemIndex) const; + void setItemText(int itemIndex, const char* text); + int findItemIndex(const char* text); - int getSelectedItem(); - void setSelectedItem(int itemIndex); + ListItem* getSelectedItem() const; + void setSelectedItem(ListItem* item); - void* getItemData(int itemIndex); - void setItemData(int itemIndex, void* data); + int getSelectedItemIndex() const; + void setSelectedItemIndex(int itemIndex); Entry* getEntryWidget(); Button* getButtonWidget(); @@ -75,13 +90,11 @@ namespace ui { private: void onButtonClick(Event& ev); - struct Item; - Entry* m_entry; Button* m_button; Window* m_window; - ListBox* m_listbox; - std::vector m_items; + ComboBoxListBox* m_listbox; + ListItems m_items; int m_selected; bool m_editable : 1; bool m_clickopen : 1; diff --git a/src/ui/widget.h b/src/ui/widget.h index 6b3ee153c..d55dcec87 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -194,10 +194,13 @@ namespace ui { // Returns a list of children. const WidgetsList& getChildren() const { return m_children; } - // Returns the first child or NULL if it doesn't exist. + // Returns the first/last child or NULL if it doesn't exist. Widget* getFirstChild() { return (!m_children.empty() ? m_children.front(): NULL); } + Widget* getLastChild() { + return (!m_children.empty() ? m_children.back(): NULL); + } // Returns the next or previous siblings. Widget* getNextSibling(); diff --git a/src/widgets/context_bar.cpp b/src/widgets/context_bar.cpp index 1f1001f70..85aff3d8f 100644 --- a/src/widgets/context_bar.cpp +++ b/src/widgets/context_bar.cpp @@ -258,7 +258,7 @@ public: } void setInkType(InkType inkType) { - setSelectedItem((int)inkType); + setSelectedItemIndex((int)inkType); } protected: @@ -268,7 +268,7 @@ protected: ISettings* settings = UIContext::instance()->getSettings(); Tool* currentTool = settings->getCurrentTool(); settings->getToolSettings(currentTool) - ->setInkType((InkType)getSelectedItem()); + ->setInkType((InkType)getSelectedItemIndex()); } }; diff --git a/src/widgets/file_selector.cpp b/src/widgets/file_selector.cpp index 4b1dd3a5c..5ce9b3eb8 100644 --- a/src/widgets/file_selector.cpp +++ b/src/widgets/file_selector.cpp @@ -166,6 +166,30 @@ public: } }; +class CustomFileNameItem : public ListItem +{ +public: + CustomFileNameItem(const char* text, IFileItem* fileItem) + : ListItem(text) + , m_fileItem(fileItem) + { + } + + IFileItem* getFileItem() { return m_fileItem; } + +private: + IFileItem* m_fileItem; +}; + +class CustomFolderNameItem : public ListItem +{ +public: + CustomFolderNameItem(const char* text) + : ListItem(text) + { + } +}; + FileSelector::FileSelector() : Window(false, "") { @@ -422,7 +446,7 @@ again: // selected in the filetype combo-box if (base::get_file_extension(buf).empty()) { buf += '.'; - buf += m_fileType->getItemText(m_fileType->getSelectedItem()); + buf += m_fileType->getItemText(m_fileType->getSelectedItemIndex()); } // duplicate the buffer to return a new string @@ -470,8 +494,7 @@ void FileSelector::updateLocation() buf += fileItem->getDisplayName(); // Add the new location to the combo-box - newItem = m_location->addItem(buf.c_str()); - m_location->setItemData(newItem, fileItem); + m_location->addItem(new CustomFileNameItem(buf.c_str(), fileItem)); if (fileItem == currentFolder) selected_index = level; @@ -487,12 +510,12 @@ void FileSelector::updateLocation() RecentFiles::const_iterator it = App::instance()->getRecentFiles()->paths_begin(); RecentFiles::const_iterator end = App::instance()->getRecentFiles()->paths_end(); for (; it != end; ++it) - m_location->addItem(*it); + m_location->addItem(new CustomFolderNameItem(it->c_str())); } // Select the location { - m_location->setSelectedItem(selected_index); + m_location->setSelectedItemIndex(selected_index); m_location->getEntryWidget()->setText(currentFolder->getDisplayName().c_str()); m_location->getEntryWidget()->deselectText(); } @@ -549,7 +572,7 @@ void FileSelector::selectFileTypeFromFileName() if (p && *p != 0) { ustrcpy(buf, get_extension(filename)); ustrlwr(buf); - m_fileType->setSelectedItem(m_fileType->findItemIndex(buf)); + m_fileType->setSelectedItemIndex(m_fileType->findItemIndex(buf)); } } @@ -595,14 +618,19 @@ void FileSelector::onLocationChange() { // When the user change the location we have to set the // current-folder in the 'fileview' widget - int itemIndex = m_location->getSelectedItem(); - IFileItem* fileItem = reinterpret_cast(m_location->getItemData(itemIndex)); + int itemIndex = m_location->getSelectedItemIndex(); + CustomFileNameItem* comboFileItem = dynamic_cast(m_location->getSelectedItem()); + IFileItem* fileItem = (comboFileItem != NULL ? comboFileItem->getFileItem(): NULL); // Maybe the user selected a recent file path if (fileItem == NULL) { - base::string path = m_location->getItemText(itemIndex); - if (!path.empty()) + CustomFolderNameItem* comboFolderItem = + dynamic_cast(m_location->getSelectedItem()); + + if (comboFolderItem != NULL) { + base::string path = comboFolderItem->getText(); fileItem = FileSystemModule::instance()->getFileItemFromPath(path); + } } if (fileItem != NULL) { @@ -618,7 +646,7 @@ void FileSelector::onLocationChange() // change the file-extension in the 'filename' entry widget void FileSelector::onFileTypeChange() { - std::string newExtension = m_fileType->getItemText(m_fileType->getSelectedItem()); + std::string newExtension = m_fileType->getItemText(m_fileType->getSelectedItemIndex()); std::string fileName = m_fileName->getText(); std::string currentExtension = base::get_file_extension(fileName);