/**
 * @brief Deletes an animation.
 *
 * The index of the selection may change, since animations are sorted
 * alphabetically.
 * Emits rowsAboutToBeRemoved(), removes the animation
 * and then emits rowsRemoved(), as required by QAbstractItemModel.
 *
 * Then, emits animation_deleted().
 *
 * Except for the deleted animation, the existing selection is preserved,
 * though the index of many animations can change.
 * The selection is cleared before the operations and restored after,
 * updated with the new index.
 *
 * @param index Index of the animation to delete.
 * @throws EditorException in case of error.
 */
void SpriteModel::delete_animation(const Index &index) {

  // Make some checks first.
  if (!animation_exists(index)) {
      throw EditorException(
            tr("Animation '%1' don't exists").arg(index.animation_name));
  }

  // Save and clear the selection since a lot of indexes may change.
  Index selection = get_selected_index();
  clear_selection();

  int animation_nb = get_animation_nb(index);

  // Delete the animation in the sprite file.
  sprite.remove_animation(index.animation_name.toStdString());

  // Rebuild indexes in the list model (indexes were shifted).
  build_index_map();

  // Call beginRemoveRows() as requested by QAbstractItemModel.
  beginRemoveRows(QModelIndex(), animation_nb, animation_nb);

  // Update our animation model list.
  animations.removeAt(animation_nb);

  // Notify people before restoring the selection, so that they have a
  // chance to know new indexes before receiving selection signals.
  endRemoveRows();
  emit animation_deleted(index);

  // Restore the selection.
  set_selected_index(selection);
}
Esempio n. 2
0
void
gltk_spinner_set_selected_index(GltkSpinner* spinner, int level, int index)
{
    g_return_if_fail(GLTK_IS_SPINNER(spinner));
    USING_PRIVATE(spinner);
    g_return_if_fail(level >= 0 && level < priv->model->levels);
    int len = g_list_length(priv->wheels[level].items);
    if (!len)
        return;
    g_return_if_fail(index >= 0 && index < len);

    set_selected_index(spinner, level, index);
    priv->wheels[level].index = index;

    if (level == priv->model->levels - 1)
    {
        g_object_ref(spinner);
        g_signal_emit(spinner, signals[ITEM_SELECTED], 0);
        g_object_unref(spinner);
    }
    else
    {
        load_items(spinner, level+1, gltk_spinner_model_get_items(priv->model, level, index));
    }
}
void OptionsField::set_by_value(value_t v) {
    size_t new_index { 0 };
    for(const auto& option : options) {
        if( option.second == v ) {
            set_selected_index(new_index);
            break;
        }
        new_index++;
    }
}
/**
 * @brief Moves a direction.
 * @param index Index of the direction to move.
 * @param new_direction_nb The new number of the direction.
 * @throws EditorException in case of error.
 */
void SpriteModel::move_direction(const Index& index, int new_direction_nb) {

  if (new_direction_nb == index.direction_nb) {
    // Nothing to do.
    return;
  }

  // Make some checks first.
  if (!direction_exists(index)) {
      QString nb = std::to_string(index.direction_nb).c_str();
      throw EditorException(
            tr("Direction %1 don't exists in animation '%2'").arg(
              nb, index.animation_name));
  }

  // Save and clear the selection.
  Index selection = get_selected_index();
  clear_selection();

  // Move the direction in the sprite file.
  get_animation(index).move_direction(index.direction_nb, new_direction_nb);

  // Call beginMoveRows() as requested by QAbstractItemModel.
  int above_row = new_direction_nb;
  if (new_direction_nb > index.direction_nb) {
    ++above_row;
  }
  QModelIndex model_index = get_model_index(Index(index.animation_name));
  beginMoveRows(model_index, index.direction_nb, index.direction_nb,
                model_index, above_row);

  // Update our animation model list.
  int animation_nb = get_animation_nb(index);
  animations[animation_nb].directions.move(index.direction_nb, new_direction_nb);

  // Update direction model indexes.
  int num_dir = animations[animation_nb].directions.size();
  for (int nb = 0; nb < num_dir; nb++) {
    animations[animation_nb].directions[nb].index->direction_nb = nb;
  }

  endMoveRows();

  // Notify people before restoring the selection, so that they have a
  // chance to know new indexes before receiving selection signals.
  emit direction_deleted(index);

  // Restore the selection.
  if (selection.direction_nb == index.direction_nb) {
    selection.direction_nb = new_direction_nb;
  }

  set_selected_index(selection);
}
/**
 * @brief Selects an animation at the specified index.
 *
 * If the selection is a direction of the specified animation,
 * the selection remains unchanged.
 *
 * @param index The index of animation to select.
 */
void SpriteModel::set_selected_animation(const Index& index) {

  if (!index.is_valid()) {
    selection_model.clear();
    return;
  }

  QString selected_name = get_selected_index().animation_name;
  if (index.is_direction_index() && index.animation_name == selected_name) {
    return;
  }

  // select the animation
  set_selected_index(index.animation_name);
}
/**
 * @brief Inserts a direction in an animation of this sprite.
 * @param index Index of the direction to insert.
 * @param data The direction data to insert.
 * @return Index of the inserted direction.
 * @throws EditorException in case of error.
 */
int SpriteModel::insert_direction(
    const Index& index, const SpriteAnimationDirectionData& data) {

  // Make some checks first.
  if (!animation_exists(index)) {
    throw EditorException(
            tr("Animation '%1' don't exists").arg(index.animation_name));
  }

  // Save and clear the selection.
  Index selection = get_selected_index();
  clear_selection();

  // Insert the direction to the sprite file.
  SpriteAnimationData& animation_data = get_animation(index);

  animation_data.add_direction(data);

  int last_dir = animation_data.get_num_directions() - 1;
  animation_data.move_direction(last_dir, index.direction_nb);

  int direction_nb = std::min(index.direction_nb, last_dir);

  // Call beginInsertRows() as requested by QAbstractItemModel.
  QModelIndex model_index = get_model_index(Index(index.animation_name));
  beginInsertRows(model_index, direction_nb, direction_nb);

  // Update our animation model list.
  int animation_nb = get_animation_nb(index);
  auto& directions = animations[animation_nb].directions;
  directions.insert(
        direction_nb, DirectionModel(index.animation_name, direction_nb));

  // Update direction model indexes.
  for (int nb = direction_nb + 1; nb < directions.size(); nb++) {
    directions[nb].index->direction_nb = nb;
  }

  // Notify people before restoring the selection, so that they have a
  // chance to know new indexes before receiving selection signals.
  endInsertRows();
  emit direction_added(Index(index.animation_name, direction_nb));

  // Restore the selection.
  set_selected_index(selection);

  return direction_nb;
}
/**
 * @brief Deletes a direction.
 * @param index Index of the direction to delete.
 * @throws EditorException in case of error.
 */
void SpriteModel::delete_direction(const Index &index) {

  // Make some checks first.
  if (!direction_exists(index)) {
      QString nb = std::to_string(index.direction_nb).c_str();
      throw EditorException(
            tr("Direction %1 don't exists in animation '%2'").arg(
              nb, index.animation_name));
  }

  // Save and clear the selection.
  Index selection = get_selected_index();
  if (selection.animation_name == index.animation_name &&
      selection.direction_nb == index.direction_nb) {
    selection.direction_nb = -1;
  }
  clear_selection();

  // Delete the direction in the sprite file.
  get_animation(index).remove_direction(index.direction_nb);

  // Call beginRemoveRows() as requested by QAbstractItemModel.
  QModelIndex model_index = get_model_index(Index(index.animation_name));
  beginRemoveRows(model_index, index.direction_nb, index.direction_nb);

  // Update our direction model list.
  int animation_nb = get_animation_nb(index);
  auto& directions = animations[animation_nb].directions;
  directions.removeAt(index.direction_nb);

  // Update direction model indexes.
  for (int nb = index.direction_nb; nb < directions.size(); nb++) {
    directions[nb].index->direction_nb = nb;
  }

  // Notify people before restoring the selection, so that they have a
  // chance to know new indexes before receiving selection signals.
  endRemoveRows();
  emit direction_deleted(index);

  // Restore the selection.
  set_selected_index(selection);
}
/**
 * @brief Inserts an animation in this sprite.
 *
 * The index of the selection may change, since animations are sorted
 * alphabetically.
 * Emits rowsAboutToBeInserted(), inserts the animation
 * and then emits rowsInserted(), as required by QAbstractItemModel.
 *
 * Then, emits animation_created().
 *
 * The newly created animation is not initially selected.
 * The existing selection is preserved, though the index of many
 * animations can change.
 * The selection is cleared before the operations and restored after,
 * updated with the new index.
 *
 * @param index Index of the animation to insert.
 * @param data Data of the animation.
 * @throws EditorException in case of error.
 */
void SpriteModel::insert_animation(
    const Index& index, const Solarus::SpriteAnimationData& data) {

  // Make some checks first.
  if (index.animation_name.length() <= 0) {
      throw EditorException(tr("Animation name cannot be empty"));
  }

  if (animation_exists(index)) {
      throw EditorException(
            tr("Animation '%1' already exists").arg(index.animation_name));
  }

  // Save and clear the selection since a lot of indexes may change.
  Index selection = get_selected_index();
  clear_selection();

  // Add the animation to the sprite file.
  sprite.add_animation(index.animation_name.toStdString(), data);

  // Rebuild indexes in the list model (indexes were shifted).
  build_index_map();

  // Call beginInsertRows() as requested by QAbstractItemModel.
  int animation_nb = get_animation_nb(index.animation_name);
  beginInsertRows(QModelIndex(), animation_nb, animation_nb);

  // Update our animation model list.
  animations.insert(animation_nb, AnimationModel(index.animation_name));
  int num_directions = data.get_num_directions();
  for (int nb = 0; nb < num_directions; nb++) {
    animations[animation_nb].directions.append(
          DirectionModel(index.animation_name, nb));
  }

  // Notify people before restoring the selection, so that they have a
  // chance to know new indexes before receiving selection signals.
  endInsertRows();
  emit animation_created(index);

  // Restore the selection.
  set_selected_index(selection);
}
/**
 * @brief Adds a direction in an animation of this sprite.
 * @param index Index of the animation to add the direction.
 * @param frame The first frame of the direction to create.
 * @return Index of the created direction.
 * @throws EditorException in case of error.
 */
int SpriteModel::add_direction(const Index& index, const QRect& frame) {

  // Make some checks first.
  if (!animation_exists(index)) {
    throw EditorException(
            tr("Animation '%1' don't exists").arg(index.animation_name));
  }

  // Save and clear the selection.
  Index selection = get_selected_index();
  clear_selection();

  // Add the direction to the sprite file.
  SpriteAnimationData& animation_data = get_animation(index);
  SpriteAnimationDirectionData direction(
        Point::to_solarus_point(frame.topLeft()),
        Size::to_solarus_size(frame.size()));

  animation_data.add_direction(direction);

  // Rebuild indexes in the list model (indexes were shifted).
  int direction_nb = animation_data.get_num_directions() - 1;

  // Call beginInsertRows() as requested by QAbstractItemModel.
  QModelIndex model_index = get_model_index(Index(index.animation_name));
  beginInsertRows(model_index, direction_nb, direction_nb);

  // Update our animation model list.
  int animation_nb = get_animation_nb(index);
  animations[animation_nb].directions.append(
        DirectionModel(index.animation_name, direction_nb));

  // Notify people before restoring the selection, so that they have a
  // chance to know new indexes before receiving selection signals.
  endInsertRows();
  emit direction_added(Index(index.animation_name, direction_nb));

  // Restore the selection.
  set_selected_index(selection);

  return direction_nb;
}
Esempio n. 10
0
void GuiListbox::select_from_mouse(int x, int y, bool from_mousemove) {
    int fh = gui.get_font()->get_font_height();
    int height = get_height() - 2 - (title_bar_visible ? fh : 0);
    y -= get_client_y() + 1 + (title_bar_visible ? fh : 0);
    int index = y / fh;
    int visible_entries = height / fh;

    /* title bar column click? */
    if (title_bar_visible && y >= -fh && y < 0 && !from_mousemove) {
        GuiListboxEntry::Columns& columns = title_bar->get_columns();
        int width = get_width() - 2 - sb->get_width() + 1;
        int index = columns.size() - 1;
        int col_right = width + (get_client_x() + 1);
        for (GuiListboxEntry::Columns::reverse_iterator it = columns.rbegin();
            it != columns.rend(); it++)
        {
            GuiListboxEntry::Column& column = *it;
            if (x >= col_right - column.width && x <= (col_right + GuiListboxEntry::Spc)) {
                if (on_title_clicked) {
                    on_title_clicked(this, on_title_clicked_data, index);
                }
                return;
            }
            col_right -= (column.width + GuiListboxEntry::Spc);
            index--;
        }
        index = 0;
        if (on_title_clicked) {
            on_title_clicked(this, on_title_clicked_data, index);
        }
        return;
    }

    /* item click? */
    if (index < 0 || index > visible_entries - 1) {
        return;
    }
    set_selected_index(index + start_index);
}
Esempio n. 11
0
bool OptionsField::on_encoder(const EncoderEvent delta) {
    set_selected_index(selected_index() + delta);
    return true;
}
Esempio n. 12
0
static void
load_items(GltkSpinner* spinner, int level, GList* items)
{
    USING_PRIVATE(spinner);

    Wheel* wheel = priv->wheels + level;

    //clean up an old mess
    if (wheel->items)
    {
        gltk_spinner_model_free_items(priv->model, wheel->items);

        g_object_unref(wheel->vbox);
        wheel->vbox = gltk_vbox_new(0);
        g_object_ref(wheel->vbox);
        gltk_scrollable_set_widget(GLTK_SCROLLABLE(wheel->scrollable), wheel->vbox);
    }

    //make a new one
    wheel->items = items;

    int itemHeight = priv->itemHeight;

    GList* pItems = wheel->items;
    while (pItems)
    {
        GltkSpinnerModelItem* item = (GltkSpinnerModelItem*)pItems->data;

        GltkWidget* label = gltk_label_new(item->text);
        GLTK_LABEL(label)->color.r = 0.0f;
        GLTK_LABEL(label)->color.g = 0.0f;
        GLTK_LABEL(label)->color.b = 0.0f;
        gltk_box_append_widget(GLTK_BOX(wheel->vbox), label, FALSE, FALSE);

        GltkSize size;
        gltk_widget_size_request(label, &size);
        if (size.height > itemHeight)
            itemHeight = size.height;

        size.width = -1;
        size.height = priv->itemHeight;
        gltk_widget_set_size_request(label, size);

        pItems = pItems->next;
    }

    //if our max height changed, relayout and resize
    if (itemHeight > priv->itemHeight)
    {
        priv->itemHeight = itemHeight;

        priv->heightChanged = TRUE;
        gltk_widget_layout(GLTK_WIDGET(spinner));
    }

    //select a specific item
    int len = g_list_length(wheel->items);
    if (wheel->index >= len - 1)
        wheel->index = len-1;
    if (wheel->index < 0)
        wheel->index = 0;
    set_selected_index(spinner, level, wheel->index);

    //set allowable amount to scroll past the vbox
    set_padding(spinner, wheel);

    //either signal that an item was selected or recurse until we do
    if (level == priv->model->levels-1)
    {
        g_object_ref(spinner);
        g_signal_emit(spinner, signals[ITEM_SELECTED], 0);
        g_object_unref(spinner);
    }
    else
    {
        load_items(spinner, level+1, gltk_spinner_model_get_items(priv->model, level, wheel->index));
    }
}
/**
 * @brief Changes the name of an animation.
 *
 * The index of the selection may change, since animations are sorted
 * alphabetically.
 * In this case, emits rowsAboutToBeMoved(), changes the index
 * and then emits rowsMoved(), as required by QAbstractItemModel.
 *
 * Then, emits animation_name_changed(), no matter if the index has also changed.
 *
 * The selection is preserved, though the index of many animations can change.
 * The selection is cleared before the operations and restored after,
 * updated with the new index.
 *
 * @param index Index of an existing animation.
 * @param new_name The new name to set.
 * @throws EditorException in case of error.
 */
void SpriteModel::set_animation_name(const Index& index, const QString& new_name) {

  if (new_name == index.animation_name) {
    // Nothing to do.
    return;
  }

  // Make some checks first.
  if (!animation_exists(index)) {
    throw EditorException(
            tr("Animation '%1' don't exists").arg(index.animation_name));
  }

  if (new_name.length() <= 0) {
      throw EditorException(tr("Animation name cannot be empty"));
  }

  if (animation_exists(new_name)) {
      throw EditorException(tr("Animation '%1' already exists").arg(new_name));
  }

  // Save and clear the selection since a lot of indexes may change.
  Index selection = get_selected_index();
  clear_selection();

  int animation_nb = get_animation_nb(index);

  // Change the name in the sprite file.
  sprite.set_animation_name(
        index.animation_name.toStdString(), new_name.toStdString());

  // Change the index in the list model (if the order has changed).
  build_index_map();
  int new_animation_nb = get_animation_nb(new_name);

  // Call beginMoveRows() if the index changes, as requested by
  // QAbstractItemModel.
  if (new_animation_nb != animation_nb) {
    int above_row = new_animation_nb;
    if (new_animation_nb > animation_nb) {
      ++above_row;
    }
    beginMoveRows(QModelIndex(), animation_nb, animation_nb,
                  QModelIndex(), above_row);

    // Update our animation model list.
    animations.move(animation_nb, new_animation_nb);
  }

  animations[new_animation_nb].set_animation_name(new_name);

  // Notify people before restoring the selection, so that they have a
  // chance to know new indexes before receiving selection signals.
  if (new_animation_nb != animation_nb) {
    endMoveRows();
  }
  emit animation_name_changed(index, Index(new_name));

  // Restore the selection.
  if (selection.animation_name == index.animation_name) {
    selection.animation_name = new_name;
  }

  set_selected_index(selection);
}