Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement autoscroll for research tree #2391

Merged
merged 3 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 89 additions & 5 deletions client/views/view_research.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@
#include <QPainter>
#include <QPushButton>
#include <QScrollArea>
#include <QStringLiteral>
#include <QTimer>
#include <QToolButton>
jwrober marked this conversation as resolved.
Show resolved Hide resolved
#include <QToolTip>

// common
#include "fc_types.h"
#include "game.h"
#include "government.h"
#include "icons.h"
#include "research.h"

// client
Expand Down Expand Up @@ -107,6 +111,16 @@ void research_diagram::reset()
resize(width, height);
}

/**
Find the center of a node, identified by tech id, and return true
if the node was found; false otherwise. If a node is found, x and y
are filled with the center of the node.
*/
bool research_diagram::get_tech_position(Tech_type_id id, int *x, int *y)
{
return get_position_on_reqtree(req, id, x, y);
}

/**
Mouse handler for research_diagram
*/
Expand Down Expand Up @@ -274,25 +288,47 @@ science_report::science_report() : QWidget()
researching_combo = new QComboBox();
auto sci_layout = new QGridLayout();
res_diag = new research_diagram();
auto scroll = new QScrollArea();
scroll = new QScrollArea();
refresh_but = new QPushButton();
refresh_but->setText(_("Refresh"));
refresh_but->setToolTip(_("Press to refresh currently researched "
"technology calculation again."));
refresh_but->setDisabled(true);

locate_researching_but = new QToolButton();
locate_researching_but->setIcon(
fcIcons::instance()->getIcon(QStringLiteral("crosshair")));
locate_researching_but->setIconSize(
QSize(locate_researching_but->fontInfo().pixelSize(),
locate_researching_but->fontInfo().pixelSize()));
locate_researching_but->setToolTip(
_("Press to locate currently researched "
"technology in tree."));
locate_researching_but->setDisabled(true);

locate_goal_but = new QToolButton();
locate_goal_but->setIcon(
fcIcons::instance()->getIcon(QStringLiteral("crosshair")));
locate_goal_but->setIconSize(
QSize(locate_researching_but->fontInfo().pixelSize(),
locate_researching_but->fontInfo().pixelSize()));
locate_goal_but->setToolTip(_("Press to locate technology goal in tree."));
locate_goal_but->setDisabled(true);

progress->setTextVisible(true);
progress_label->setSizePolicy(size_fixed_policy);
sci_layout->addWidget(progress_label, 0, 0, 1, 8);
sci_layout->addWidget(progress_label, 0, 0, 1, 9);
sci_layout->addWidget(researching_combo, 1, 0, 1, 3);
sci_layout->addWidget(refresh_but, 1, 3, 1, 1);
researching_combo->setSizePolicy(size_fixed_policy);
sci_layout->addWidget(locate_researching_but, 1, 3, 1, 1);
sci_layout->addWidget(refresh_but, 1, 4, 1, 1);
refresh_but->setSizePolicy(size_fixed_policy);
sci_layout->addWidget(progress, 1, 5, 1, 4);
sci_layout->addWidget(progress, 1, 6, 1, 4);
progress->setSizePolicy(size_fixed_policy);
sci_layout->addWidget(goal_combo, 2, 0, 1, 3);
goal_combo->setSizePolicy(size_fixed_policy);
sci_layout->addWidget(info_label, 2, 5, 1, 4);
sci_layout->addWidget(locate_goal_but, 2, 3, 1, 1);
sci_layout->addWidget(info_label, 2, 6, 1, 4);
info_label->setSizePolicy(size_fixed_policy);

size = res_diag->size();
Expand All @@ -310,6 +346,12 @@ science_report::science_report() : QWidget()
QObject::connect(refresh_but, &QAbstractButton::pressed, this,
&science_report::push_research);

QObject::connect(locate_goal_but, &QAbstractButton::pressed, this,
&science_report::locate_goal);

QObject::connect(locate_researching_but, &QAbstractButton::pressed, this,
&science_report::locate_researching);

QObject::connect(goal_combo,
QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&science_report::goal_tech_changed);
Expand Down Expand Up @@ -518,6 +560,10 @@ void science_report::update_report()
refresh_but->setDisabled(false);
}

// Update locate buttons
locate_researching_but->setDisabled(research->researching == A_UNSET);
locate_goal_but->setDisabled(research->tech_goal == A_UNSET);

update_reqtree();
}

Expand All @@ -526,6 +572,17 @@ void science_report::update_report()
*/
void science_report::update_reqtree() { res_diag->update_reqtree(); }

/**
Scroll the science tree to display the technology identified by tech id.
*/
void science_report::scroll_reqtree_to_tech(Tech_type_id id)
{
int x, y;
if (res_diag->get_tech_position(id, &x, &y)) {
scroll->ensureVisible(x, y, scroll->width() / 2, scroll->height() / 2);
}
}

/**
Slot used when combo box with current tech changes
*/
Expand Down Expand Up @@ -570,6 +627,33 @@ void science_report::push_research()
}
}

/**
Locate technology goal in tree and scroll so that it is visible.
*/
void science_report::locate_goal()
{
auto research = research_get(client_player());
if (!research) {
return;
}

scroll_reqtree_to_tech(research->tech_goal);
}

/**
Locate the currently researched technology in tree and scroll so that it
is visible.
*/
void science_report::locate_researching()
{
auto research = research_get(client_player());
if (!research) {
return;
}

scroll_reqtree_to_tech(research->researching);
}

/**
Update the science report.
*/
Expand Down
8 changes: 8 additions & 0 deletions client/views/view_research.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class QPaintEvent;
class QScrollArea;
class progress_bar;
class QPushButton;
class QToolButton;

/****************************************************************************
Custom widget representing research diagram in science_report
Expand All @@ -37,6 +38,7 @@ class research_diagram : public QWidget {
void update_reqtree();
void reset();
QSize size();
bool get_tech_position(Tech_type_id id, int *x, int *y);
private slots:
void show_tooltip();

Expand Down Expand Up @@ -71,9 +73,12 @@ struct qlist_item {
class science_report : public QWidget {
Q_OBJECT

QScrollArea *scroll;
QComboBox *goal_combo;
QComboBox *researching_combo;
QPushButton *refresh_but;
QToolButton *locate_researching_but;
QToolButton *locate_goal_but;
progress_bar *progress;
QLabel *info_label;
QLabel *progress_label;
Expand All @@ -92,11 +97,14 @@ class science_report : public QWidget {
private:
void update_reqtree();
int index{0};
void scroll_reqtree_to_tech(Tech_type_id id);

private slots:
void current_tech_changed(int index);
void goal_tech_changed(int index);
void push_research();
void locate_researching();
void locate_goal();
};

void popdown_science_report();
Expand Down
22 changes: 22 additions & 0 deletions client/views/view_research_reqtree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1183,3 +1183,25 @@ Tech_type_id get_tech_on_reqtree(struct reqtree *tree, int x, int y)
}
return A_NONE;
}

/**
Find the center of a node, identified by tech id in a given reqtree
and return true if the node was found; false otherwise. If a node
is found, x and y are filled with the center of the node in
reqtrees coordinate system.
*/
bool get_position_on_reqtree(struct reqtree *tree, Tech_type_id tech, int *x,
int *y)
{
for (int i = 0; i < tree->num_nodes; i++) {
struct tree_node *node = tree->nodes[i];

if (tech == node->tech) {
*x = node->node_x + node->node_width / 2;
*y = node->node_y + node->node_height / 2;
return true;
}
}

return false;
}
3 changes: 3 additions & 0 deletions client/views/view_research_reqtree.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,6 @@ QList<req_tooltip_help *> *draw_reqtree(struct reqtree *tree,
int w, int h);

Tech_type_id get_tech_on_reqtree(struct reqtree *tree, int x, int y);

bool get_position_on_reqtree(struct reqtree *tree, Tech_type_id tech, int *x,
int *y);
11 changes: 11 additions & 0 deletions data/themes/icons/crosshair.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions data/themes/icons/crosshair.svg.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SPDX-License-Identifier: CC-BY-SA-4.0
SPDX-FileCopyrightText: 2024 Louis Moureaux
7 changes: 6 additions & 1 deletion docs/Manuals/Game/top-bar.rst
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ you instruct your scientists which technologies to research. When you click the


:numref:`Research Tree` below shows a sample of a :guilabel:`Research Tree`. In this picture the player is
researching :advance:`Sanitation`.
researching :advance:`Code of Laws`.

.. _Research Tree:
.. figure:: /_static/images/gui-elements/research-tree.png
Expand All @@ -388,6 +388,11 @@ technology advance you want your scientists to concentrate (:guilabel:`Current R
drop down box is where you can set a future target (:guilabel:`Research Target`). The game will work through
the list of technologies as turns progress in order of dependency.

To the right of the :guilabel:`Current Research` and :guilabel:`Research Target` drop down boxes, you will
find a small button with a crosshair icon.
Pressing one of these buttons will scroll the corresponding technology in the :guilabel:`Research Tree` into
view.

To the right of the :guilabel:`Current Research` drop down box, you will find a :guilabel:`Refresh` button. In
some circumstances a player can find that the current researched bulbs is greater than the bulbs needed to
complete the task. The :guilabel:`Refresh` button will be enabled in this situation and the player can press
Expand Down
Binary file modified docs/_static/images/gui-elements/research-tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading