void scrollpane::add_widget(widget* w, int x, int y, int z_order)
{
	if (w == NULL)
		return;

	widget_map::iterator itor = std::find_if(content_.begin(), content_.end(), widget_finder(w));
	if (itor != content_.end())
		return;

	scrollpane_widget spw(w, x, y, z_order);

	w->set_clip_rect(client_area());
	content_.insert(std::pair<int, scrollpane_widget>(z_order, spw));

	position_widget(spw);

	// Recalculates the whole content size
	update_content_size();
}
void scrollpane::update_content_size()
{
	unsigned int maxx = 0;
	unsigned int maxy = 0;

	for(widget_map::iterator itor = content_.begin(); itor != content_.end(); ++itor) {
		if(itor->second.x + itor->second.w->width() > maxx) {
			maxx = itor->second.x + itor->second.w->width();
		}
		if(itor->second.y + itor->second.w->height() > maxy) {
			maxy = itor->second.y + itor->second.w->height();
		}
	}

	content_pos_.w = maxx;
	content_pos_.h = maxy;

	set_full_size(maxy);
	set_shown_size(client_area().h);

	set_dirty();
}
void scrollpane::set_location(SDL_Rect const& rect)
{
	scrollarea::set_location(rect);
	set_shown_size(client_area().h);
	update_widget_positions();
}
void scrollpane::set_inner_location(const SDL_Rect& /*rect*/)
{
	for(widget_map::iterator itor = content_.begin(); itor != content_.end(); ++itor) {
		itor->second.w->set_clip_rect(client_area());
	}
}
void configure::layout_children(const SDL_Rect& rect)
{
	DBG_MP << "laying out the children" << std::endl;

	ui::layout_children(rect);

	const int border_size = 6;
	const int column_border_size = 10;

	SDL_Rect ca = client_area();
	int xpos = ca.x;
	int ypos = ca.y;
	const int first_column_width = (ca.w - ca.x) / 2 - column_border_size;

	// Dialog title
	ypos += title().height() + border_size;

	// Name Entry
	name_entry_label_.set_location(xpos, ypos);
	name_entry_.set_location(xpos + name_entry_label_.width() + border_size, ypos);
	name_entry_.set_width(ca.w - name_entry_label_.width() - border_size);
	ypos += std::max<int>(name_entry_.height(), name_entry_label_.height()) + border_size;

	// Save ypos here (column top)
	int ypos_columntop = ypos;

	const int right_pane_height =
		ca.h - (ypos_columntop - ca.y + launch_game_.height() + border_size);

	// First column: non-gameplay settings
	options_pane_left_.set_location(xpos, ypos);
	options_pane_left_.set_width(first_column_width);
	options_pane_left_.set_height(right_pane_height - entry_points_label_.height());

	int slider_width = options_pane_left_.width() - 40;

	int xpos_left = 0;
	int ypos_left = 0;

	ypos_left += 2 * border_size;
	options_pane_left_.add_widget(&observers_game_, xpos_left, ypos_left);
	options_pane_left_.add_widget(&shuffle_sides_,
		xpos_left + (options_pane_left_.width() - xpos_left) / 2 + border_size, ypos_left);
	ypos_left += shuffle_sides_.height() + border_size;

	options_pane_left_.add_widget(&countdown_game_, xpos_left, ypos_left);

	if(!local_players_only_) {
		options_pane_left_.add_widget(&password_button_,
			(ca.x + first_column_width / 2) - 40, ypos_left);
	} else {
		password_button_.hide(true);
	}

	ypos_left += countdown_game_.height() + border_size;

	options_pane_left_.add_widget(&countdown_init_time_label_, xpos_left, ypos_left	);
	ypos_left += countdown_init_time_label_.height() + border_size;
	countdown_init_time_slider_.set_width(slider_width);
	options_pane_left_.add_widget(&countdown_init_time_slider_, xpos_left, ypos_left);
	ypos_left += countdown_init_time_slider_.height() + border_size;

	options_pane_left_.add_widget(&countdown_turn_bonus_label_, xpos_left, ypos_left);
	ypos_left += countdown_turn_bonus_label_.height() + border_size;
	countdown_turn_bonus_slider_.set_width(slider_width);
	options_pane_left_.add_widget(&countdown_turn_bonus_slider_, xpos_left, ypos_left);
	ypos_left += countdown_turn_bonus_slider_.height() + border_size;

	options_pane_left_.add_widget(&countdown_reservoir_time_label_, xpos_left, ypos_left);
	ypos_left += countdown_reservoir_time_label_.height() + border_size;
	countdown_reservoir_time_slider_.set_width(slider_width);
	options_pane_left_.add_widget(&countdown_reservoir_time_slider_, xpos_left, ypos_left);
	ypos_left += countdown_reservoir_time_slider_.height() + border_size;
	options_pane_left_.add_widget(&countdown_action_bonus_label_, xpos_left, ypos_left);
	ypos_left += countdown_action_bonus_label_.height() + border_size;
	countdown_action_bonus_slider_.set_width(slider_width);
	options_pane_left_.add_widget(&countdown_action_bonus_slider_, xpos_left, ypos_left);
	ypos_left += countdown_action_bonus_slider_.height() + border_size;

	if (show_entry_points_) {
		int x = ca.x;
		int y = ca.y + ca.h - entry_points_combo_.height();
		entry_points_combo_.set_location(x, y);
		y -= entry_points_label_.height() + border_size;
		entry_points_label_.set_location(x, y);
	}

	// Second column: gameplay settings
	xpos += first_column_width + column_border_size;
	ypos = ypos_columntop;

	options_pane_right_.set_location(xpos, ypos);
	options_pane_right_.set_width(ca.w - (xpos - ca.x));
	options_pane_right_.set_height(right_pane_height);

	slider_width = options_pane_right_.width() - 40;

	int xpos_right = 0;
	int ypos_right = 0;
	options_pane_right_.add_widget(&generic_label_, xpos_right, ypos_right);
	ypos_right += generic_label_.height() + border_size;

	options_pane_right_.add_widget(&use_map_settings_, xpos_right, ypos_right);
	options_pane_right_.add_widget(&fog_game_,
		xpos_right + (options_pane_right_.width() - xpos_right)/2 + 5, ypos_right);
	ypos_right += use_map_settings_.height() + border_size;

	options_pane_right_.add_widget(&random_start_time_, xpos_right, ypos_right);
	options_pane_right_.add_widget(&shroud_game_,
		xpos_right + (options_pane_right_.width() - xpos_right)/2 + 5, ypos_right);
	ypos_right += random_start_time_.height() + border_size;

	options_pane_right_.add_widget(&turns_label_, xpos_right, ypos_right);
	ypos_right += turns_label_.height() + border_size;
	turns_slider_.set_width(slider_width);
	options_pane_right_.add_widget(&turns_slider_, xpos_right, ypos_right);
	ypos_right += turns_slider_.height() + border_size;

	options_pane_right_.add_widget(&xp_modifier_label_, xpos_right, ypos_right);
	ypos_right += xp_modifier_label_.height() + border_size;
	xp_modifier_slider_.set_width(slider_width);
	options_pane_right_.add_widget(&xp_modifier_slider_, xpos_right, ypos_right);
	ypos_right += xp_modifier_slider_.height() + border_size;

	options_pane_right_.add_widget(&village_support_label_, xpos_right, ypos_right);
	ypos_right += village_support_label_.height() + border_size;
	village_support_slider_.set_width(slider_width);
	options_pane_right_.add_widget(&village_support_slider_, xpos_right, ypos_right);
	ypos_right += village_support_slider_.height() + border_size;

	options_pane_right_.add_widget(&village_gold_label_, xpos_right, ypos_right);
	ypos_right += village_gold_label_.height() + border_size;
	village_gold_slider_.set_width(slider_width);

	options_pane_right_.add_widget(&village_gold_slider_, xpos_right, ypos_right);
	ypos_right += village_gold_slider_.height() + 3 * border_size;

	options_manager_.layout_widgets(xpos_right, ypos_right);

	// OK / Cancel buttons
	gui::button* left_button = &launch_game_;
	gui::button* right_button = &cancel_game_;

#ifdef OK_BUTTON_ON_RIGHT
	std::swap(left_button,right_button);
#endif

	// Buttons
	right_button->set_location(ca.x + ca.w - right_button->width(),
	                           ca.y + ca.h - right_button->height());
	left_button->set_location(right_button->location().x - left_button->width() -
	                          gui::ButtonHPadding, ca.y + ca.h - left_button->height());
}
Exemplo n.º 6
0
void create::layout_children(const SDL_Rect& rect)
{
    DBG_MP << "laying out the children" << std::endl;

    ui::layout_children(rect);

    const int border_size =  6;
    const int column_border_size = 10;

    SDL_Rect ca = client_area();
    int xpos = ca.x;
    int ypos = ca.y;

    // 222 is two times a button's minimal width plus one time border_size.
    // Instead of binding this value to the actual button widths, I chose this
    // because it makes no difference for most languages, and where it does, I
    // guess we'd prefer having the buttons less neatly aligned to having a
    // potentially giant image.
    const int image_width = ca.h < 500 ? 111 : 222;
    const int menu_width = (ca.w - 3 * column_border_size - image_width) / 3;
    const int eras_menu_height = (ca.h / 2 - era_label_.height() -
                                  2 * border_size - cancel_game_.height());
    //const int mods_menu_height = (ca.h / 2 - mod_label_.height() -
    //	2 * border_size - cancel_game_.height());

    // Dialog title
    ypos += title().height() + border_size;

    // Save ypos here (column top)
    int ypos_columntop = ypos;

    // First column: image & random map options
    image_rect_ = create_rect(xpos, ypos, image_width, image_width);
    ypos += image_width + border_size;

    num_players_label_.set_location(xpos, ypos);
    ypos += num_players_label_.height() + border_size;

    map_size_label_.set_location(xpos, ypos);
    ypos += map_size_label_.height() + 2 * border_size;

    const int ypos1 = ypos;
    const int xpos1 = xpos;
    // The description box is set later

    // Second column: filtering options
    ypos = ypos_columntop;
    xpos += image_width + column_border_size;
    filter_name_label_.set_location(xpos, ypos);
    filter_name_.set_location(xpos + filter_name_label_.width() + border_size, ypos);
    filter_name_.set_measurements(menu_width - border_size - filter_name_label_.width(), filter_name_label_.height());
    ypos += filter_name_.height() + border_size;
    filter_num_players_label_.set_location(xpos, ypos);
    ypos += filter_num_players_label_.height() + border_size;
    filter_num_players_slider_.set_location(xpos, ypos);
    filter_num_players_slider_.set_width(menu_width);
    ypos += filter_num_players_slider_.height() + border_size;
    map_generator_label_.set_location(xpos, ypos);
    ypos += map_generator_label_.height() + border_size;
    regenerate_map_.set_location(xpos, ypos);
    ypos += regenerate_map_.height() + border_size;
    generator_settings_.set_location(xpos, ypos);
    ypos += generator_settings_.height() + border_size;
    load_game_.set_location(xpos, ypos + 4 * border_size);

    // And now the description box
    description_.set_location(xpos1, std::max(ypos,ypos1));
    description_.set_measurements(image_width + border_size + menu_width, ca.h + ca.y - std::max(ypos,ypos1) - border_size);
    description_.set_wrap(true);
    ypos += description_.height() + border_size;

    //Third column: levels menu
    ypos = ypos_columntop;
    xpos += menu_width + column_border_size;
    level_type_label_.set_location(xpos, ypos);
    ypos += level_type_label_.height() + border_size;
    level_type_combo_.set_location(xpos, ypos);
    ypos += level_type_combo_.height() + border_size;

    const int levels_menu_y_offset = (ca.w < 900 || ca.h < 500) ?
                                     ((cancel_game_.height() + border_size) * -1) : 0;
    levels_menu_.set_max_width(menu_width);
    levels_menu_.set_max_height(ca.h + ca.y - ypos + levels_menu_y_offset);
    levels_menu_.set_location(xpos, ypos);
    // Menu dimensions are only updated when items are set. So do this now.
    int levelsel = levels_menu_.selection();
    levels_menu_.set_items(engine_.levels_menu_item_names());
    levels_menu_.move_selection(levelsel);

    // Place game type combo and label in the middle of levels menu
    // by x axis.
    const int level_type_combo_x_offset = (levels_menu_.width() -
                                           level_type_combo_.width()) / 2;
    level_type_combo_.set_location(
        level_type_combo_.location().x + level_type_combo_x_offset,
        level_type_combo_.location().y);
    const int level_type_label_x_offset = (levels_menu_.width() -
                                           level_type_label_.width()) / 2;
    level_type_label_.set_location(
        level_type_label_.location().x + level_type_label_x_offset,
        level_type_label_.location().y);

    //Fourth column: eras & mods menu
    ypos = ypos_columntop;
    xpos += menu_width + column_border_size;
    era_label_.set_location(xpos, ypos);
    ypos += era_label_.height() + border_size;
    eras_menu_.set_max_width(menu_width);
    eras_menu_.set_max_height(eras_menu_height);
    eras_menu_.set_location(xpos, ypos);
    // Menu dimensions are only updated when items are set. So do this now.
    int erasel_save = eras_menu_.selection();
    eras_menu_.set_items(engine_.extras_menu_item_names(create_engine::ERA));
    eras_menu_.move_selection(erasel_save);
    ypos += eras_menu_height;

    //TODO: use when mods_menu_ would be functional.
    /*mod_label_.set_location(xpos, ypos);
    ypos += mod_label_.height() + border_size;
    mods_menu_.set_max_width(menu_width);
    mods_menu_.set_max_height(mods_menu_height);
    mods_menu_.set_location(xpos, ypos);
    // Menu dimensions are only updated when items are set. So do this now.
    int modsel_save = mods_menu_.selection();
    mods_menu_.set_items(engine_.extras_menu_item_names(create_engine::MOD));
    mods_menu_.move_selection(modsel_save);*/
    choose_mods_.set_location(xpos, ypos);

    // OK / Cancel buttons
    gui::button* left_button = &launch_game_;
    gui::button* right_button = &cancel_game_;

#ifdef OK_BUTTON_ON_RIGHT
    std::swap(left_button,right_button);
#endif

    // Buttons
    right_button->set_location(ca.x + ca.w - right_button->width(),
                               ca.y + ca.h - right_button->height());
    left_button->set_location(right_button->location().x - left_button->width() -
                              gui::ButtonHPadding, ca.y + ca.h - left_button->height());

    if (ca.h < 500) {
        load_game_.set_location(left_button->location().x - load_game_.width() -
                                gui::ButtonHPadding, ca.y + ca.h - load_game_.height());
    }
}