2010-09-27 22:18:17 +00:00
|
|
|
// ASE gui library
|
2011-01-18 23:49:53 +00:00
|
|
|
// Copyright (C) 2001-2011 David Capello
|
2010-09-27 22:18:17 +00:00
|
|
|
//
|
|
|
|
// This source file is ditributed under a BSD-like license, please
|
|
|
|
// read LICENSE.txt for more information.
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2009-07-12 20:29:16 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
#include <allegro.h>
|
|
|
|
|
2010-09-25 19:22:32 +00:00
|
|
|
#include "gfx/size.h"
|
2010-09-29 20:14:11 +00:00
|
|
|
#include "gui/jinete.h"
|
|
|
|
#include "gui/preferred_size_event.h"
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-09-25 19:22:32 +00:00
|
|
|
using namespace gfx;
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
struct ComboBox::Item
|
2008-02-04 02:37:26 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
std::string text;
|
2010-01-26 00:38:05 +00:00
|
|
|
void* data;
|
2010-06-25 02:44:59 +00:00
|
|
|
|
|
|
|
Item() : data(NULL) { }
|
2010-01-26 00:38:05 +00:00
|
|
|
};
|
2008-02-04 02:37:26 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
#define IS_VALID_ITEM(combobox, index) \
|
|
|
|
(index >= 0 && index < combobox->getItemCount())
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
static bool combobox_entry_msg_proc(JWidget widget, JMessage msg);
|
2009-11-22 00:26:58 +00:00
|
|
|
static bool combobox_button_msg_proc(JWidget widget, JMessage msg);
|
2007-09-18 23:57:02 +00:00
|
|
|
static bool combobox_listbox_msg_proc(JWidget widget, JMessage msg);
|
2008-02-04 02:37:26 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
ComboBox::ComboBox()
|
|
|
|
: Widget(JI_COMBOBOX)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-12-08 17:28:13 +00:00
|
|
|
m_entry = new Entry(256, "");
|
2010-08-23 20:41:19 +00:00
|
|
|
m_button = new Button("");
|
2010-06-25 02:44:59 +00:00
|
|
|
m_window = NULL;
|
|
|
|
m_selected = 0;
|
|
|
|
m_editable = false;
|
|
|
|
m_clickopen = true;
|
|
|
|
m_casesensitive = true;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
m_entry->user_data[0] = this;
|
|
|
|
m_button->user_data[0] = this;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2011-01-21 20:50:04 +00:00
|
|
|
// TODO this separation should be from the Theme*
|
2010-06-25 02:44:59 +00:00
|
|
|
this->child_spacing = 0;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
jwidget_focusrest(this, true);
|
|
|
|
jwidget_add_hook(m_entry, JI_WIDGET, combobox_entry_msg_proc, NULL);
|
|
|
|
jwidget_add_hook(m_button, JI_WIDGET, combobox_button_msg_proc, NULL);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
jwidget_expansive(m_entry, true);
|
2010-08-23 20:41:19 +00:00
|
|
|
|
|
|
|
// When the "m_button" is clicked ("Click" signal) call onButtonClick() method
|
|
|
|
m_button->Click.connect(&ComboBox::onButtonClick, this);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
jwidget_add_child(this, m_entry);
|
|
|
|
jwidget_add_child(this, m_button);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
setEditable(m_editable);
|
2008-02-04 02:37:26 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
jwidget_init_theme(this);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
ComboBox::~ComboBox()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
removeAllItems();
|
|
|
|
}
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void ComboBox::setEditable(bool state)
|
|
|
|
{
|
|
|
|
m_editable = state;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
if (state) {
|
2010-12-08 17:28:13 +00:00
|
|
|
m_entry->setReadOnly(false);
|
|
|
|
m_entry->showCaret();
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-12-08 17:28:13 +00:00
|
|
|
m_entry->setReadOnly(true);
|
|
|
|
m_entry->hideCaret();
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void ComboBox::setClickOpen(bool state)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
m_clickopen = state;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void ComboBox::setCaseSensitive(bool state)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
m_casesensitive = state;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
bool ComboBox::isEditable()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
return m_editable;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
bool ComboBox::isClickOpen()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
return m_clickopen;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
bool ComboBox::isCaseSensitive()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
return m_casesensitive;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
int ComboBox::addItem(const std::string& text)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
bool sel_first = m_items.empty();
|
|
|
|
Item* item = new Item();
|
|
|
|
item->text = text;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
m_items.push_back(item);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
if (sel_first)
|
2010-06-25 02:44:59 +00:00
|
|
|
setSelectedItem(0);
|
|
|
|
|
|
|
|
return m_items.size()-1;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void ComboBox::insertItem(int itemIndex, const std::string& text)
|
2010-03-08 01:48:01 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
bool sel_first = m_items.empty();
|
|
|
|
Item* item = new Item();
|
|
|
|
item->text = text;
|
2010-03-08 01:48:01 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
m_items.insert(m_items.begin() + itemIndex, item);
|
2010-03-08 01:48:01 +00:00
|
|
|
|
|
|
|
if (sel_first)
|
2010-06-25 02:44:59 +00:00
|
|
|
setSelectedItem(0);
|
2010-03-08 01:48:01 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void ComboBox::removeItem(int itemIndex)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-08-04 02:33:44 +00:00
|
|
|
ASSERT(itemIndex >= 0 && (size_t)itemIndex < m_items.size());
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
Item* item = m_items[itemIndex];
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
m_items.erase(m_items.begin() + itemIndex);
|
|
|
|
delete item;
|
2008-02-04 02:37:26 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void ComboBox::removeAllItems()
|
2008-02-04 02:37:26 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
std::vector<Item*>::iterator it, end = m_items.end();
|
|
|
|
for (it = m_items.begin(); it != end; ++it)
|
|
|
|
delete *it;
|
2008-02-04 02:37:26 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
m_items.clear();
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
int ComboBox::getItemCount()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
return m_items.size();
|
|
|
|
}
|
2008-02-04 02:37:26 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
std::string ComboBox::getItemText(int itemIndex)
|
|
|
|
{
|
|
|
|
if (itemIndex >= 0 && (size_t)itemIndex < m_items.size()) {
|
|
|
|
Item* item = m_items[itemIndex];
|
|
|
|
return item->text;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
2010-06-25 02:44:59 +00:00
|
|
|
else
|
|
|
|
return "";
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void ComboBox::setItemText(int itemIndex, const std::string& text)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-08-04 02:33:44 +00:00
|
|
|
ASSERT(itemIndex >= 0 && (size_t)itemIndex < m_items.size());
|
2010-06-25 02:44:59 +00:00
|
|
|
|
|
|
|
Item* item = m_items[itemIndex];
|
|
|
|
item->text = text;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
int ComboBox::findItemIndex(const std::string& text)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
int itemIndex = 0;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
std::vector<Item*>::iterator it, end = m_items.end();
|
|
|
|
for (it = m_items.begin(); it != end; ++it) {
|
|
|
|
Item* 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)) {
|
|
|
|
return itemIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
itemIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
int ComboBox::getSelectedItem()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
return !m_items.empty() ? m_selected: -1;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void ComboBox::setSelectedItem(int itemIndex)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
if (itemIndex >= 0 && (size_t)itemIndex < m_items.size()) {
|
|
|
|
m_selected = itemIndex;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
std::vector<Item*>::iterator it = m_items.begin() + itemIndex;
|
|
|
|
Item* item = *it;
|
|
|
|
m_entry->setText(item->text.c_str());
|
2008-02-04 02:37:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void* ComboBox::getItemData(int itemIndex)
|
2008-02-04 02:37:26 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
if (itemIndex >= 0 && (size_t)itemIndex < m_items.size()) {
|
|
|
|
Item* item = m_items[itemIndex];
|
2008-02-04 02:37:26 +00:00
|
|
|
return item->data;
|
|
|
|
}
|
2007-09-18 23:57:02 +00:00
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void ComboBox::setItemData(int itemIndex, void* data)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-08-04 02:33:44 +00:00
|
|
|
ASSERT(itemIndex >= 0 && (size_t)itemIndex < m_items.size());
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
Item* item = m_items[itemIndex];
|
|
|
|
item->data = data;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-12-08 17:28:13 +00:00
|
|
|
Entry* ComboBox::getEntryWidget()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
return m_entry;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-08-23 20:41:19 +00:00
|
|
|
Button* ComboBox::getButtonWidget()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
return m_button;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-08-03 00:29:56 +00:00
|
|
|
bool ComboBox::onProcessMessage(JMessage msg)
|
2008-02-04 02:37:26 +00:00
|
|
|
{
|
2007-09-18 23:57:02 +00:00
|
|
|
switch (msg->type) {
|
|
|
|
|
|
|
|
case JM_CLOSE:
|
2010-06-25 02:44:59 +00:00
|
|
|
closeListBox();
|
2008-02-04 02:37:26 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_SETPOS: {
|
|
|
|
JRect cbox = jrect_new_copy(&msg->setpos.rect);
|
2010-06-25 02:44:59 +00:00
|
|
|
jrect_copy(this->rc, cbox);
|
2008-02-04 02:37:26 +00:00
|
|
|
|
2010-08-03 01:57:41 +00:00
|
|
|
// Button
|
|
|
|
Size buttonSize = m_button->getPreferredSize();
|
|
|
|
cbox->x1 = msg->setpos.rect.x2 - buttonSize.w;
|
2010-06-25 02:44:59 +00:00
|
|
|
jwidget_set_rect(m_button, cbox);
|
2008-02-04 02:37:26 +00:00
|
|
|
|
2010-08-03 01:57:41 +00:00
|
|
|
// Entry
|
2008-02-04 02:37:26 +00:00
|
|
|
cbox->x2 = cbox->x1;
|
|
|
|
cbox->x1 = msg->setpos.rect.x1;
|
2010-06-25 02:44:59 +00:00
|
|
|
jwidget_set_rect(m_entry, cbox);
|
2008-02-04 02:37:26 +00:00
|
|
|
|
|
|
|
jrect_free(cbox);
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2008-02-04 02:37:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case JM_WINMOVE:
|
2010-06-25 02:44:59 +00:00
|
|
|
if (m_window) {
|
|
|
|
JRect rc = getListBoxPos();
|
|
|
|
m_window->move_window(rc);
|
2008-02-04 02:37:26 +00:00
|
|
|
jrect_free(rc);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2008-02-04 02:37:26 +00:00
|
|
|
case JM_BUTTONPRESSED:
|
2010-06-25 02:44:59 +00:00
|
|
|
if (m_window != NULL) {
|
|
|
|
if (!jwidget_get_view(m_listbox)->hasMouse()) {
|
|
|
|
closeListBox();
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2008-02-04 02:37:26 +00:00
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-08-03 00:29:56 +00:00
|
|
|
return Widget::onProcessMessage(msg);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-08-03 01:57:41 +00:00
|
|
|
void ComboBox::onPreferredSize(PreferredSizeEvent& ev)
|
|
|
|
{
|
|
|
|
Size reqSize(0, 0);
|
|
|
|
Size entrySize = m_entry->getPreferredSize();
|
|
|
|
|
|
|
|
// Get the text-length of every item and put in 'w' the maximum value
|
|
|
|
std::vector<Item*>::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())+
|
|
|
|
10*jguiscale();
|
|
|
|
|
|
|
|
reqSize.w = MAX(reqSize.w, item_w);
|
|
|
|
}
|
|
|
|
|
|
|
|
reqSize.w += entrySize.w;
|
|
|
|
reqSize.h += entrySize.h;
|
|
|
|
|
|
|
|
Size buttonSize = m_button->getPreferredSize();
|
|
|
|
reqSize.w += buttonSize.w;
|
|
|
|
reqSize.h = MAX(reqSize.h, buttonSize.h);
|
|
|
|
ev.setPreferredSize(reqSize);
|
|
|
|
}
|
|
|
|
|
2007-09-26 19:34:06 +00:00
|
|
|
static bool combobox_entry_msg_proc(JWidget widget, JMessage msg)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
ComboBox* combobox = reinterpret_cast<ComboBox*>(widget->user_data[0]);
|
2007-12-04 21:50:31 +00:00
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
switch (msg->type) {
|
|
|
|
|
2008-02-29 19:29:49 +00:00
|
|
|
case JM_KEYPRESSED:
|
2010-04-25 15:03:25 +00:00
|
|
|
if (widget->hasFocus()) {
|
2010-06-25 02:44:59 +00:00
|
|
|
if (!combobox->isEditable()) {
|
2007-09-18 23:57:02 +00:00
|
|
|
if (msg->key.scancode == KEY_SPACE ||
|
|
|
|
msg->key.scancode == KEY_ENTER ||
|
|
|
|
msg->key.scancode == KEY_ENTER_PAD) {
|
2010-06-25 02:44:59 +00:00
|
|
|
combobox->switchListBox();
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (msg->key.scancode == KEY_ENTER ||
|
|
|
|
msg->key.scancode == KEY_ENTER_PAD) {
|
2010-06-25 02:44:59 +00:00
|
|
|
combobox->switchListBox();
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_BUTTONPRESSED:
|
2010-06-25 02:44:59 +00:00
|
|
|
if (combobox->isClickOpen()) {
|
|
|
|
combobox->switchListBox();
|
2007-12-04 21:50:31 +00:00
|
|
|
}
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
if (combobox->isEditable()) {
|
2007-12-04 21:50:31 +00:00
|
|
|
jmanager_set_focus(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
else
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
break;
|
2009-11-22 00:26:58 +00:00
|
|
|
|
|
|
|
case JM_DRAW:
|
2011-01-21 21:08:25 +00:00
|
|
|
widget->getTheme()->draw_combobox_entry(static_cast<Entry*>(widget),
|
|
|
|
&msg->draw.rect);
|
2009-11-22 00:26:58 +00:00
|
|
|
return true;
|
2010-12-08 17:28:13 +00:00
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2009-08-17 18:00:38 +00:00
|
|
|
return false;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2009-11-22 00:26:58 +00:00
|
|
|
static bool combobox_button_msg_proc(JWidget widget, JMessage msg)
|
|
|
|
{
|
|
|
|
switch (msg->type) {
|
|
|
|
|
|
|
|
case JM_DRAW:
|
2011-01-21 21:08:25 +00:00
|
|
|
widget->getTheme()->draw_combobox_button((ButtonBase*)widget, &msg->draw.rect);
|
2009-11-22 00:26:58 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-09-26 19:34:06 +00:00
|
|
|
static bool combobox_listbox_msg_proc(JWidget widget, JMessage msg)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
ComboBox* combobox = reinterpret_cast<ComboBox*>(widget->user_data[0]);
|
2007-12-04 21:50:31 +00:00
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
switch (msg->type) {
|
|
|
|
|
|
|
|
case JM_SIGNAL:
|
|
|
|
if (msg->signal.num == JI_SIGNAL_LISTBOX_CHANGE) {
|
|
|
|
int index = jlistbox_get_selected_index(widget);
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
if (IS_VALID_ITEM(combobox, index)) {
|
|
|
|
combobox->setSelectedItem(index);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
jwidget_emit_signal(combobox, JI_SIGNAL_COMBOBOX_CHANGE);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_BUTTONRELEASED:
|
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
int index = combobox->getSelectedItem();
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
combobox->closeListBox();
|
2008-02-10 18:52:42 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
if (IS_VALID_ITEM(combobox, index))
|
|
|
|
jwidget_emit_signal(combobox, JI_SIGNAL_COMBOBOX_SELECT);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2007-12-04 21:50:31 +00:00
|
|
|
/* case JM_IDLE: { */
|
|
|
|
/* /\* if the user clicks outside the listbox *\/ */
|
|
|
|
/* if (!jmouse_b(1) && jmouse_b(0) && !jwidget_has_mouse(widget)) { */
|
|
|
|
/* ComboBox *combobox = jwidget_get_data(combo_widget, JI_COMBOBOX); */
|
|
|
|
|
|
|
|
/* if (combobox->entry && !jwidget_has_mouse(combobox->entry) && */
|
|
|
|
/* combobox->button && !jwidget_has_mouse(combobox->button) && */
|
|
|
|
/* combobox->window && !jwidget_has_mouse(combobox->window)) { */
|
|
|
|
/* combobox_close_window(combo_widget); */
|
2009-08-17 18:00:38 +00:00
|
|
|
/* return true; */
|
2007-12-04 21:50:31 +00:00
|
|
|
/* } */
|
|
|
|
/* } */
|
|
|
|
/* break; */
|
|
|
|
/* } */
|
|
|
|
|
2008-02-29 19:29:49 +00:00
|
|
|
case JM_KEYPRESSED:
|
2010-04-25 15:03:25 +00:00
|
|
|
if (widget->hasFocus()) {
|
2007-09-18 23:57:02 +00:00
|
|
|
if (msg->key.scancode == KEY_SPACE ||
|
|
|
|
msg->key.scancode == KEY_ENTER ||
|
|
|
|
msg->key.scancode == KEY_ENTER_PAD) {
|
2010-06-25 02:44:59 +00:00
|
|
|
combobox->closeListBox();
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-08-17 18:00:38 +00:00
|
|
|
return false;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-08-23 20:41:19 +00:00
|
|
|
// When the mouse is clicked we switch the visibility-status of the list-box
|
|
|
|
void ComboBox::onButtonClick(Event& ev)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-08-23 20:41:19 +00:00
|
|
|
switchListBox();
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void ComboBox::openListBox()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
if (!m_window) {
|
|
|
|
m_window = new Frame(false, NULL);
|
|
|
|
Widget* view = jview_new();
|
|
|
|
m_listbox = jlistbox_new();
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
m_listbox->user_data[0] = this;
|
|
|
|
jwidget_add_hook(m_listbox, JI_WIDGET,
|
2008-02-04 02:37:26 +00:00
|
|
|
combobox_listbox_msg_proc, NULL);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
std::vector<Item*>::iterator it, end = m_items.end();
|
|
|
|
for (it = m_items.begin(); it != end; ++it) {
|
|
|
|
Item* item = *it;
|
|
|
|
jwidget_add_child(m_listbox, jlistitem_new(item->text.c_str()));
|
2008-02-04 02:37:26 +00:00
|
|
|
}
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
m_window->set_ontop(true);
|
|
|
|
jwidget_noborders(m_window);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-03-22 01:35:55 +00:00
|
|
|
Widget* viewport = jview_get_viewport(view);
|
2010-06-25 02:44:59 +00:00
|
|
|
int size = getItemCount();
|
2007-12-06 20:05:32 +00:00
|
|
|
jwidget_set_min_size
|
2010-03-22 01:35:55 +00:00
|
|
|
(viewport,
|
2010-06-25 02:44:59 +00:00
|
|
|
m_button->rc->x2 - m_entry->rc->x1 - view->border_width.l - view->border_width.r,
|
2010-03-22 01:35:55 +00:00
|
|
|
+viewport->border_width.t
|
2010-06-25 02:44:59 +00:00
|
|
|
+(2*jguiscale()+jwidget_get_text_height(m_listbox))*MID(1, size, 16)+
|
2010-03-22 01:35:55 +00:00
|
|
|
+viewport->border_width.b);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
jwidget_add_child(m_window, view);
|
|
|
|
jview_attach(view, m_listbox);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
jwidget_signal_off(m_listbox);
|
|
|
|
jlistbox_select_index(m_listbox, m_selected);
|
|
|
|
jwidget_signal_on(m_listbox);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
m_window->remap_window();
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
JRect rc = getListBoxPos();
|
|
|
|
m_window->position_window(rc->x1, rc->y1);
|
2007-09-18 23:57:02 +00:00
|
|
|
jrect_free(rc);
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
jmanager_add_msg_filter(JM_BUTTONPRESSED, this);
|
2008-02-04 02:37:26 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
m_window->open_window_bg();
|
|
|
|
jmanager_set_focus(m_listbox);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void ComboBox::closeListBox()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
if (m_window) {
|
|
|
|
m_window->closeWindow(this);
|
|
|
|
delete m_window; // window, frame
|
|
|
|
m_window = NULL;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
jmanager_remove_msg_filter(JM_BUTTONPRESSED, this);
|
|
|
|
jmanager_set_focus(m_entry);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
void ComboBox::switchListBox()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
if (!m_window)
|
|
|
|
openListBox();
|
2007-09-18 23:57:02 +00:00
|
|
|
else
|
2010-06-25 02:44:59 +00:00
|
|
|
closeListBox();
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:44:59 +00:00
|
|
|
JRect ComboBox::getListBoxPos()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-06-25 02:44:59 +00:00
|
|
|
JRect rc = jrect_new(m_entry->rc->x1,
|
|
|
|
m_entry->rc->y2,
|
|
|
|
m_button->rc->x2,
|
|
|
|
m_entry->rc->y2+jrect_h(m_window->rc));
|
2007-09-18 23:57:02 +00:00
|
|
|
if (rc->y2 > JI_SCREEN_H)
|
2010-06-25 02:44:59 +00:00
|
|
|
jrect_displace(rc, 0, -(jrect_h(rc)+jrect_h(m_entry->rc)));
|
2007-09-18 23:57:02 +00:00
|
|
|
return rc;
|
|
|
|
}
|