void WidgetChatBubble::add_filerecv(Toxmm::EventFileRecv file) { auto msg_time = Glib::DateTime::create_now_utc(); // remove seconds msg_time = Glib::DateTime::create_utc(msg_time.get_year(), msg_time.get_month(), msg_time.get_day_of_month(), msg_time.get_hour(), msg_time.get_minute(), 0); bool display_time = true; if (m_last_timestamp != 0) { auto old_time = Glib::DateTime::create_now_utc(m_last_timestamp); // remove seconds old_time = Glib::DateTime::create_utc(old_time.get_year(), old_time.get_month(), old_time.get_day_of_month(), old_time.get_hour(), old_time.get_minute(), 0); // check display_time = !(msg_time.compare(old_time) == 0); } // create a new row auto msg = Gtk::manage(WidgetChatFileRecv::create(observable(), file)); auto time = Gtk::manage(new Gtk::Label()); m_last_timestamp = msg_time.to_unix(); // get local time msg_time = Glib::DateTime::create_now_local(m_last_timestamp); time->set_text(msg_time.format("%R")); // add to grid if (m_side == RIGHT) { rows.emplace_back(m_grid, m_row_count, *msg, *time); } else { rows.emplace_back(m_grid, m_row_count, *time, *msg); } m_row_count += 1; // styling time->set_halign(Gtk::ALIGN_CENTER); time->set_valign(Gtk::ALIGN_START); time->get_style_context()->add_class("bubble_chat_line_time"); msg->set_halign(Gtk::ALIGN_START); msg->set_valign(Gtk::ALIGN_CENTER); msg->show_all(); time->show_all(); time->set_no_show_all(); if (!display_time) { time->hide(); } }
ship_selection_button::ship_selection_button(ui_container* parent) : ui_button(parent) { set_width(16.f); set_height(16.f); set_halign(horizontal_alignment::left); set_valign(vertical_alignment::top); set_margin(10.f); selection_state = ship_selection_button_state::unknown; }
ImageView::ImageView(const string& filename) { try{ myImage = Gdk::Pixbuf::create_from_file(filename); }catch(...) { std::cerr<<"An error occured while loading the image file."<<std::endl; } if(myImage) set_size_request(myImage->get_width(), myImage->get_height()); set_halign(Gtk::ALIGN_CENTER); set_valign(Gtk::ALIGN_CENTER); }
WidgetChatBubble::WidgetChatBubble(gToxObservable* instance, Toxmm::FriendNr nr, Side left_side) : Glib::ObjectBase("WidgetChatLine"), m_side(left_side), m_row_count(0), m_avatar(instance, nr) { set_observable(instance); set_halign((m_side == LEFT) ? Gtk::Align::ALIGN_START : Gtk::Align::ALIGN_END); get_style_context()->add_class((m_side == LEFT) ? "gtox-left" : "gtox-right"); auto hbox = Gtk::manage(new Gtk::HBox()); auto frame = Gtk::manage(new Gtk::Frame()); add(*hbox); if (m_side == LEFT) { hbox->pack_start(m_avatar); m_avatar.set_valign(Gtk::ALIGN_START); m_avatar.set_halign(Gtk::ALIGN_END); } hbox->add(*frame); if (m_side == RIGHT) { hbox->pack_end(m_avatar); m_avatar.set_valign(Gtk::ALIGN_END); m_avatar.set_halign(Gtk::ALIGN_START); } frame->add(m_grid); m_avatar.set_name("Avatar"); m_avatar.set_size_request(0, 0); //TODO: replace this, it's deprecated m_avatar.property_xalign() = (m_side == LEFT) ? 1 : 0; m_avatar.property_yalign() = (m_side == LEFT) ? 1 : 0; // m_avatar.set_tooltip_text("TODO Display name here.."); m_avatar.get_style_context()->add_class("frame"); frame->get_style_context()->add_class("gtox-bubble"); show_all(); m_last_timestamp = 0; m_grid.show_all(); }
void show_server_info_dialog(Gtk::Window& w, Glib::ustring game_v, Glib::ustring host_v, Server data, std::function<void()> cb_launch) { PlayerListModelColumns player_list_columns; RuleListModelColumns rule_list_columns; // Set models auto game = Gtk::manage(new Gtk::Label(game_v)); game->set_halign(Gtk::Align::ALIGN_START); auto host = Gtk::manage(new Gtk::Label(host_v)); host->set_halign(Gtk::Align::ALIGN_START); auto name = Gtk::manage(new Gtk::Label); name->set_halign(Gtk::Align::ALIGN_START); auto terrain = Gtk::manage(new Gtk::Label); terrain->set_halign(Gtk::Align::ALIGN_START); auto ping = Gtk::manage(new Gtk::Label); ping->set_halign(Gtk::Align::ALIGN_START); auto players = Gtk::manage(new Gtk::Label); players->set_halign(Gtk::Align::ALIGN_START); set_label_from_optional(name, data.name); set_label_from_optional(terrain, data.terrain); set_label_from_optional(ping, data.ping); try { players->set_text(Glib::ustring::compose("%1 / %2", data.player_count.value(), data.player_limit.value())); } catch (const std::experimental::bad_optional_access&) {} auto player_list = Gtk::ListStore::create(player_list_columns); for (auto v : data.players) { auto& row = *player_list->append(); row[player_list_columns.name] = v.name; try { row[player_list_columns.ping] = std::stoi(v.info.at("ping")); } catch (...) {} try { row[player_list_columns.score] = std::stoi(v.info.at("score")); } catch (...) {} } auto rule_list = Gtk::ListStore::create(rule_list_columns); for (auto v : data.rules) { auto& row = *rule_list->append(); row[rule_list_columns.key] = v.first; row[rule_list_columns.value] = v.second; } // Create presentation auto server_info_data_grid = Gtk::manage(new Gtk::Grid); server_info_data_grid->set_row_spacing(5); server_info_data_grid->set_column_spacing(5); { auto i = -1; auto name_label = Gtk::manage(new Gtk::Label); name_label->set_markup("<b>Name:</b>"); name_label->set_halign(Gtk::Align::ALIGN_END); server_info_data_grid->attach(*name_label, 0, i++, 1, 1); server_info_data_grid->attach_next_to(*name, *name_label, Gtk::PositionType::POS_RIGHT, 1, 1); auto host_label = Gtk::manage(new Gtk::Label); host_label->set_markup("<b>Host:</b>"); host_label->set_halign(Gtk::Align::ALIGN_END); server_info_data_grid->attach(*host_label, 0, i++, 1, 1); server_info_data_grid->attach_next_to(*host, *host_label, Gtk::PositionType::POS_RIGHT, 1, 1); auto game_label = Gtk::manage(new Gtk::Label); game_label->set_markup("<b>Game:</b>"); game_label->set_halign(Gtk::Align::ALIGN_END); server_info_data_grid->attach(*game_label, 0, i++, 1, 1); server_info_data_grid->attach_next_to(*game, *game_label, Gtk::PositionType::POS_RIGHT, 1, 1); auto terrain_label = Gtk::manage(new Gtk::Label); terrain_label->set_markup("<b>Terrain:</b>"); terrain_label->set_halign(Gtk::Align::ALIGN_END); server_info_data_grid->attach(*terrain_label, 0, i++, 1, 1); server_info_data_grid->attach_next_to(*terrain, *terrain_label, Gtk::PositionType::POS_RIGHT, 1, 1); auto players_label = Gtk::manage(new Gtk::Label); players_label->set_markup("<b>Players:</b>"); players_label->set_halign(Gtk::Align::ALIGN_END); server_info_data_grid->attach(*players_label, 0, i++, 1, 1); server_info_data_grid->attach_next_to(*players, *players_label, Gtk::PositionType::POS_RIGHT, 1, 1); auto ping_label = Gtk::manage(new Gtk::Label); ping_label->set_markup("<b>Ping:</b>"); ping_label->set_halign(Gtk::Align::ALIGN_END); server_info_data_grid->attach(*ping_label, 0, i++, 1, 1); server_info_data_grid->attach_next_to(*ping, *ping_label, Gtk::PositionType::POS_RIGHT, 1, 1); } auto player_list_view = Gtk::manage(new Gtk::TreeView(player_list)); { auto col = Gtk::manage(new Gtk::TreeViewColumn("Name")); col->pack_start(player_list_columns.name); player_list_view->append_column(*col); } { auto col = Gtk::manage(new Gtk::TreeViewColumn("Score")); col->pack_start(player_list_columns.score); player_list_view->append_column(*col); } { auto col = Gtk::manage(new Gtk::TreeViewColumn("Ping")); col->pack_start(player_list_columns.ping); player_list_view->append_column(*col); } auto player_list_sw = Gtk::manage(new Gtk::ScrolledWindow); player_list_sw->set_hexpand(true); player_list_sw->set_vexpand(true); player_list_sw->add(*player_list_view); auto server_info_grid = Gtk::manage(new Gtk::Grid); server_info_grid->set_row_spacing(10); { auto i = -1; server_info_grid->attach(*server_info_data_grid, 0, i++, 1, 1); server_info_grid->attach(*player_list_sw, 0, i++, 1, 1); } // Server rules auto rule_list_view = Gtk::manage(new Gtk::TreeView(rule_list)); { auto col = Gtk::manage(new Gtk::TreeViewColumn("Key")); col->pack_start(rule_list_columns.key); rule_list_view->append_column(*col); } { auto col = Gtk::manage(new Gtk::TreeViewColumn("Value")); col->pack_start(rule_list_columns.value); rule_list_view->append_column(*col); } auto server_rules_sw = Gtk::manage(new Gtk::ScrolledWindow); server_rules_sw->add(*rule_list_view); // The stack auto stack = Gtk::manage(new Gtk::Stack); stack->property_margin().set_value(10); stack->add(*server_info_grid, "info", "Information"); stack->add(*server_rules_sw, "rules", "Rules"); auto stack_switcher = Gtk::manage(new Gtk::StackSwitcher); stack_switcher->set_stack(*stack); stack_switcher->set_halign(Gtk::Align::ALIGN_CENTER); // The dialog Gtk::Dialog dialog_window("Server info", w); auto content = dialog_window.get_content_area(); content->pack_start(*stack_switcher, Gtk::PackOptions::PACK_SHRINK); content->pack_start(*stack); auto connect_button = dialog_window.add_button("Connect", 0); auto close_button = dialog_window.add_button("Close", 0); connect_button->signal_clicked().connect([&dialog_window, cb_launch]() { try { cb_launch(); } catch (const std::bad_function_call&) {} }); dialog_window.show_all(); dialog_window.run(); }
void AwesomeBar::build_widgets() { set_margin_left(20); set_margin_right(20); set_margin_top(20); set_margin_bottom(20); set_no_show_all(); set_valign(Gtk::ALIGN_START); set_halign(Gtk::ALIGN_CENTER); entry_.set_width_chars(50); pack_start(entry_, false, false); entry_.signal_changed().connect([&]() { populate(entry_.get_text().c_str()); }); entry_.signal_activate().connect(sigc::mem_fun(this, &AwesomeBar::execute)); entry_.signal_focus_out_event().connect([=](GdkEventFocus* evt) -> bool { // Horrible hack on old Gtk+ auto minor_version = gtk_get_minor_version(); if(about_to_focus && minor_version < 12) { about_to_focus = false; entry_.grab_focus(); entry_.set_position(-1); return true; } entry_.hide(); entry_.set_text(""); return false; }); entry_.signal_key_press_event().connect([=](GdkEventKey* evt) -> bool { if(evt->keyval == GDK_KEY_Down || evt->keyval == GDK_KEY_Up) { /* * If we key up or down, change the selection in the list but * return false so that we don't lose focus on the box */ auto row = list_.get_selected_row(); if(!row) { return false; } auto idx = row->get_index(); idx += (evt->keyval == GDK_KEY_Down) ? 1 : -1; idx = std::max(idx, 0); idx = std::min(idx, (int32_t) displayed_files_.size()); about_to_focus = true; list_.select_row(*list_.get_row_at_index(idx)); return true; } return false; }); Pango::FontDescription desc("sans-serif 16"); entry_.override_font(desc); pack_start(list_revealer_, false, true, 0); list_window_.set_size_request(-1, 650); list_.set_activate_on_single_click(true); list_window_.add(list_); list_revealer_.add(list_window_); list_.set_hexpand(false); list_.signal_row_activated().connect([this](Gtk::ListBoxRow* row){ auto idx = row->get_index(); auto file = displayed_files_.at(idx); window_.open_document(file); hide(); }); }
void WidgetChatBubble::add_message(Line new_line) { auto msg_time = Glib::DateTime::create_now_utc(new_line.timestamp); // remove seconds msg_time = Glib::DateTime::create_utc(msg_time.get_year(), msg_time.get_month(), msg_time.get_day_of_month(), msg_time.get_hour(), msg_time.get_minute(), 0); bool display_time = true; if (m_last_timestamp != 0) { auto old_time = Glib::DateTime::create_now_utc(m_last_timestamp); // remove seconds old_time = Glib::DateTime::create_utc(old_time.get_year(), old_time.get_month(), old_time.get_day_of_month(), old_time.get_hour(), old_time.get_minute(), 0); // check display_time = !(msg_time.compare(old_time) == 0); } // create a new row auto msg = Gtk::manage(new WidgetChatLabel()); auto time = Gtk::manage(new Gtk::Label()); m_last_timestamp = new_line.timestamp; // get local time msg_time = Glib::DateTime::create_now_local(m_last_timestamp); time->set_text(msg_time.format("%R")); msg->set_text(new_line.message); // add to grid if (m_side == RIGHT) { rows.emplace_back(m_grid, m_row_count, *msg, *time); } else { rows.emplace_back(m_grid, m_row_count, *time, *msg); } if (new_line.wait_for_receipt) { rows.back().set_class("message_pending"); //callback ! auto nr = new_line.nr; auto receipt = new_line.receipt; auto index = rows.size() - 1; rows.back().tox_callback = observer_add([this, index, nr, receipt](const ToxEvent &ev) { //wait for receipt if (ev.type() == typeid(Toxmm::EventReadReceipt)) { auto& row = rows[index]; auto data = ev.get<Toxmm::EventReadReceipt>(); if (data.nr == nr) { if (data.receipt > receipt) { //message failed ! row.set_class("message_failed"); row.tox_callback.reset(); } else if (data.receipt == receipt) { //message got ! row.set_class("message_receipt"); row.tox_callback.reset(); } } } }); } if (new_line.error) { rows.back().set_class("message_failed"); } for(size_t i = 0; i < rows.size(); ++i) { rows[i].set_class(i == 0, i == rows.size()-1); } m_row_count += 1; // styling time->set_halign(Gtk::ALIGN_CENTER); time->set_valign(Gtk::ALIGN_START); time->get_style_context()->add_class("bubble_chat_line_time"); msg->set_halign(Gtk::ALIGN_START); msg->set_valign(Gtk::ALIGN_CENTER); msg->show_all(); time->show_all(); time->set_no_show_all(); if (!display_time) { time->hide(); } }