Skip to content

Commit

Permalink
Merge branch 'hotfix/drag_drop_hotfix'
Browse files Browse the repository at this point in the history
  • Loading branch information
T3sT3ro committed Jan 16, 2018
2 parents 91f4b56 + 155007e commit 9d5add0
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 147 deletions.
22 changes: 13 additions & 9 deletions include/gui/gCircuit.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ namespace Logicon {
const int POSTPONED_CLEAR = 1 << 1;
const int POSTPONED_CONNECT = 1 << 2;
const int POSTPONED_DISCONNECT = 1 << 3;
ID postponedRemoveId; /// ID of gate to be removed, -1 if no postponed removal
Connection postponedConnectFrom; /// Connection info for postponed connect operation...
Connection postponedConnectTo; /// ...
Connection postponedDisconnectFrom; /// Connection info for postponed disconnect operation...
Connection postponedDisconnectTo; /// ...
std::list<ID> postponedRemoveList; /// ID of gate to be removed, -1 if no postponed removal
std::list<std::pair<Connection, Connection>> postponedConnectList; /// Connection info for postponed connect operation
std::list<std::pair<Connection, Connection>> postponedDisconnectList; /// Connection info for postponed disconnect operation

UI::Vec2 hovered_grid_cell;

// @formatter:on
GCircuit(std::shared_ptr<Circuit> circuit);

Expand All @@ -56,6 +57,9 @@ namespace Logicon {
*/
bool close();

const UI::Vec2 &getHovered_grid_cell() const;


/**
* @brief Returns this circuit
*
Expand All @@ -72,7 +76,7 @@ namespace Logicon {
/**
* @breif Returns pointer to GBlock at given position
*
* @param pos position to check for
* @param pos position to check for in grid coordinates
* @return pointer to GBlock or nullptr if block at given pos doesn't exist
*/
std::shared_ptr<GBlock> getGBlockAt(UI::Vec2 &pos);
Expand Down Expand Up @@ -176,16 +180,16 @@ namespace Logicon {
void executePostponed();

/// @brief apllies modification during executePostponed()
void postponedRemove(ID id);
void postponedRemove();

/// @brief apllies modification during executePostponed()
void postponedClear();

/// @brief apllies modification during executePostponed()
void postponedConnect(ID idFrom, Port output, ID idTo, Port input);
void postponedConnect();

/// @brief apllies modification during executePostponed()
void postponedDisconnect(ID idFrom, Port output, ID idTo, Port input);
void postponedDisconnect();
};

} // namespace Logicon
Expand Down
64 changes: 33 additions & 31 deletions include/gui/gUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,39 @@ namespace Logicon {

// TODO: make all extern and init in App.init()
// @formatter:off
const float MARGIN = 16.0; /// Margin between elements
const float MENU_WIDGET_HEIGHT = 64.0;
const float MENU_WIDGET_BUTTON_SIZE = 48.0;
const ImColor MENU_WIDGET_BUTTON_FG_COLOR = ImColor(229, 229, 229); /// Foreground color for buttons
const float BLOCKS_WIDGET_WIDTH = 300.0;
const float FOOTER_WIDGET_HEIGHT = 32.0;

const float CANVAS_GRID_SIZE = 32.0; /// Basic square size on canvas

const int CANVAS_CHANNEL_COUNT = 6; /// Like z-index, that many layers to draw
const int DEFAULT_GBLOCK_CHANNEL = 0;
const int DEFAULT_CONNECTION_CHANNEL = 1;
const int DEFAULT_GPORT_CHANNEL = 2;
const int ACTIVE_GBLOCK_CHANNEL = 3;
const int ACTIVE_GPORT_CHANNEL = 4;
const int ACTIVE_CONNECTION_CHANNEL = 5;

const float GPORT_PADDING = CANVAS_GRID_SIZE / 8.0;
const float GPORT_SIZE = CANVAS_GRID_SIZE - 2*GPORT_PADDING; /// Dimensions for GPort button
const float BEZIER_CONTROL_DISTANCE = UI::CANVAS_GRID_SIZE * 2.0; /// How far in canvas coordinates is control point away from gPort
const float BEZIER_THICKNESS = 4.0; /// Thickness of bezier lines
const int BEZIER_SEGMENTS = 20; /// Higher = smoother bezier

const ImColor ON_STATE_COLOR = ImColor(255, 195, 17);
const ImColor OFF_STATE_COLOR = ImColor(68, 74, 119);
const ImColor DEFAULT_GBLOCK_COLOR = ImColor(255, 255, 255, 200); /// Default
const ImColor DIMMED_GBLOCK_COLOR = ImColor(100, 100, 100, 200);
const ImColor DEFAULT_GPORT_COLOR = ImColor(68, 75, 119);
const ImColor DIMMED_GPORT_COLOR = ImColor(34, 40, 61, 200);

const std::string GPORT_NONE_HOVERED = "-"; /// value for GPORT_CURRENTLY_HOVERED flag while non is hovered
const float MARGIN = 16.0; /// Margin between elements
const float MENU_WIDGET_HEIGHT = 64.0;
const float MENU_WIDGET_BUTTON_SIZE = 48.0;
const ImColor MENU_WIDGET_BUTTON_NORMAL_COLOR = ImColor(229, 229, 229); /// Foreground color for normal buttons
const ImColor MENU_WIDGET_BUTTON_PLAY_PUSHED_COLOR = ImColor(0, 145, 0); /// Foreground color for pushed in play button
const ImColor MENU_WIDGET_BUTTON_PAUSE_PUSHED_COLOR = ImColor(125, 0, 0); /// Foreground color for pushed in pause button
const float BLOCKS_WIDGET_WIDTH = 300.0;
const float FOOTER_WIDGET_HEIGHT = 32.0;

const float CANVAS_GRID_SIZE = 32.0; /// Basic square size on canvas

const int CANVAS_CHANNEL_COUNT = 6; /// Like z-index, that many layers to draw
const int DEFAULT_GBLOCK_CHANNEL = 0;
const int DEFAULT_CONNECTION_CHANNEL = 1;
const int DEFAULT_GPORT_CHANNEL = 2;
const int ACTIVE_GBLOCK_CHANNEL = 3;
const int ACTIVE_GPORT_CHANNEL = 4;
const int ACTIVE_CONNECTION_CHANNEL = 5;

const float GPORT_PADDING = CANVAS_GRID_SIZE / 8.0;
const float GPORT_SIZE = CANVAS_GRID_SIZE - 2*GPORT_PADDING; /// Dimensions for GPort button
const float BEZIER_CONTROL_DISTANCE = UI::CANVAS_GRID_SIZE * 2.0; /// How far in canvas coordinates is control point away from gPort
const float BEZIER_THICKNESS = 4.0; /// Thickness of bezier lines
const int BEZIER_SEGMENTS = 20; /// Higher = smoother bezier

const ImColor ON_STATE_COLOR = ImColor(255, 195, 17);
const ImColor OFF_STATE_COLOR = ImColor(68, 74, 119);
const ImColor DEFAULT_GBLOCK_COLOR = ImColor(255, 255, 255, 200); /// Default
const ImColor DIMMED_GBLOCK_COLOR = ImColor(100, 100, 100, 200);
const ImColor DEFAULT_GPORT_COLOR = ImColor(68, 75, 119);
const ImColor DIMMED_GPORT_COLOR = ImColor(34, 40, 61, 200);

const std::string GPORT_NONE_HOVERED = "-"; /// value for GPORT_CURRENTLY_HOVERED flag while non is hovered

const int KEY_DELETE = 261;
// @formatter:on
Expand Down
54 changes: 32 additions & 22 deletions src/gui/gBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,30 @@ namespace Logicon {
ImGui::SetItemAllowOverlap();

/// FLAGS SETUP

printf("CUR_HOV: %d CUR_DRAG: %d BEG: %d\n", GBLOCK_CURRENTLY_HOVERED, GBLOCK_CURRENTLY_DRAGGED,
GBLOCK_CLICK_BEGIN_ON_GBLOCK);

// Set HOVERED flag
if (GBLOCK_DRAGGED_FLAG // if the block is dragged or
|| (ImGui::IsItemHovered() // is hovered...
&& GBLOCK_CURRENTLY_DRAGGED == -1 // and none other is dragged...
&& GPort::getHovered() == UI::GPORT_NONE_HOVERED)) { // and no port is hovered...
GBLOCK_HOVERED_FLAG = true;
GBLOCK_CURRENTLY_HOVERED = gate->id;
}

// set GBLOCK_CLICK_BEGIN_ON_GBLOCK
if (ImGui::IsMouseDown(0)) {
if (GBLOCK_CLICK_BEGIN_ON_GBLOCK == -1)
GBLOCK_CLICK_BEGIN_ON_GBLOCK = GBLOCK_CURRENTLY_HOVERED != -1 ? 1 : 0;
if(GBLOCK_CLICK_BEGIN_ON_GBLOCK == -1) {
auto hoveredGridCell = parentGCircuit.lock()->getHovered_grid_cell();
if(hoveredGridCell != UI::Vec2(-1,-1)) {
if(parentGCircuit.lock()->getGBlockAt(hoveredGridCell) != nullptr)
GBLOCK_CLICK_BEGIN_ON_GBLOCK = GBLOCK_CURRENTLY_HOVERED;
else
GBLOCK_CLICK_BEGIN_ON_GBLOCK = -2;
}
}
}

// unset GBLOCK_CLICK_BEGIN_ON_GBLOCK
Expand All @@ -102,25 +122,15 @@ namespace Logicon {
}

// Set DRAGGED flag
if (ImGui::IsItemHovered() // if item is hovered...
&& GBLOCK_CURRENTLY_DRAGGED == -1 // and if currently dragged is nothing...
if (GBLOCK_CURRENTLY_DRAGGED == -1 // and if currently dragged is nothing...
&& GPort::getHovered() == UI::GPORT_NONE_HOVERED // and no port is hovered...
&& GPort::getDragged() == UI::GPORT_NONE_HOVERED // and no port is dragged...
&& ImGui::IsMouseDragging(0, 4.0) // and is dragging with minimal threshold of 4 pixels
&& GBLOCK_CLICK_BEGIN_ON_GBLOCK) {
&& GBLOCK_CLICK_BEGIN_ON_GBLOCK == gate->getId()) {
GBLOCK_DRAGGED_FLAG = true;
GBLOCK_CURRENTLY_DRAGGED = gate->id;
}

// Set HOVERED flag
if (GBLOCK_DRAGGED_FLAG // if the block is dragged or
|| (ImGui::IsItemHovered() // is hovered...
&& GBLOCK_CURRENTLY_DRAGGED == -1 // and none other is dragged...
&& GPort::getHovered() == UI::GPORT_NONE_HOVERED)) { // and no port is hovered...
GBLOCK_HOVERED_FLAG = true;
GBLOCK_CURRENTLY_HOVERED = gate->id;
}

// unset HOVERED flag
if (!ImGui::IsItemHovered() // if no longer hovered or
|| GPort::getHovered() != UI::GPORT_NONE_HOVERED) { // if any GPort hovered
Expand All @@ -136,23 +146,23 @@ namespace Logicon {
GATE_TYPE gt = gate->getGateType();
if (gt == Logicon::DELAY) {
auto gDelay = std::static_pointer_cast<Delay, Gate>(gate);
if(ImGui::Button("options"))
if (ImGui::Button("options"))
ImGui::OpenPopup("delay_opt");
if(ImGui::BeginPopup("delay_opt")) {
if (ImGui::BeginPopup("delay_opt")) {
int delay_opt = gDelay->getDelay();
ImGui::PushItemWidth(100.0);
ImGui::InputInt("delay", &delay_opt);
ImGui::PopItemWidth();
if(delay_opt < 0) delay_opt = 0;
if (delay_opt < 0) delay_opt = 0;
gDelay->setDelay(delay_opt);
ImGui::EndPopup();
}
}
if (gt == Logicon::CLOCK) {
auto gClock = std::static_pointer_cast<Clock, Gate>(gate);
if(ImGui::Button("options"))
if (ImGui::Button("options"))
ImGui::OpenPopup("clock_opt");
if(ImGui::BeginPopup("clock_opt")) {
if (ImGui::BeginPopup("clock_opt")) {
int onPeriod_opt = gClock->getOnPeriod();
int offPeriod_opt = gClock->getOffPeriod();
int phase_opt = gClock->getPhase();
Expand All @@ -161,9 +171,9 @@ namespace Logicon {
ImGui::InputInt("OFF period", &offPeriod_opt);
ImGui::InputInt("phase", &phase_opt);
ImGui::PopItemWidth();
if(onPeriod_opt < 0) onPeriod_opt = 0;
if(offPeriod_opt < 0) offPeriod_opt = 0;
if(phase_opt < 0) phase_opt = 0;
if (onPeriod_opt < 0) onPeriod_opt = 0;
if (offPeriod_opt < 0) offPeriod_opt = 0;
if (phase_opt < 0) phase_opt = 0;
gClock->changeSettings(onPeriod_opt, offPeriod_opt, phase_opt);
ImGui::EndPopup();
}
Expand Down
65 changes: 35 additions & 30 deletions src/gui/gCircuit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,7 @@
namespace Logicon {

GCircuit::GCircuit(std::shared_ptr<Circuit> circuit) : circuit(circuit),
POSTPONED_OPERATIONS(0),
postponedRemoveId(0),
postponedConnectFrom(0, 0),
postponedConnectTo(0, 0),
postponedDisconnectFrom(0, 0),
postponedDisconnectTo(0, 0) {}
POSTPONED_OPERATIONS(0) {}

bool GCircuit::init() {
assert(circuit != nullptr);
Expand All @@ -50,10 +45,9 @@ namespace Logicon {
};

std::shared_ptr<GBlock> GCircuit::getGBlockAt(UI::Vec2 &pos) {
UI::Vec2 gridPos = UI::toGridCoordinates(pos);
auto found = std::find_if(
gBlocks.begin(), gBlocks.end(),
[gridPos](const std::shared_ptr<GBlock> &gBlock) { return gBlock->getRect().contains(gridPos); }
[pos](const std::shared_ptr<GBlock> &gBlock) { return gBlock->getRect().contains(pos); }
);

if (found == gBlocks.end())
Expand All @@ -78,7 +72,7 @@ namespace Logicon {

void GCircuit::remove(ID id) {
POSTPONED_OPERATIONS |= POSTPONED_REMOVE;
postponedRemoveId = id;
postponedRemoveList.push_back(id);
}

void GCircuit::clear() {
Expand All @@ -87,14 +81,12 @@ namespace Logicon {

void GCircuit::connect(ID idFrom, Port output, ID idTo, Port input) {
POSTPONED_OPERATIONS |= POSTPONED_CONNECT;
postponedConnectFrom = {idFrom, output};
postponedConnectTo = {idTo, input};
postponedConnectList.push_back(std::make_pair(Connection(idFrom, output), Connection(idTo, input)));
}

void GCircuit::disconnect(ID idFrom, Port output, ID idTo, Port input) {
POSTPONED_OPERATIONS |= POSTPONED_DISCONNECT;
postponedDisconnectFrom = {idFrom, output};
postponedDisconnectTo = {idTo, input};
postponedDisconnectList.push_back(std::make_pair(Connection(idFrom, output), Connection(idTo, input)));
}

bool GCircuit::isOccupied(ID id, UI::Rect rect) {
Expand Down Expand Up @@ -136,8 +128,8 @@ namespace Logicon {
const UI::Vec2 dl_origin = ImGui::GetWindowPos() + ImGui::GetWindowContentRegionMin();

{
UI::Vec2 hovered_grid_cell =
UI::toGridCoordinates(ImGui::GetMousePos() - dl_origin);
hovered_grid_cell = ImGui::IsWindowHovered() ? UI::toGridCoordinates(ImGui::GetMousePos() - dl_origin)
: UI::Vec2(-1, -1);

std::string status_x = ImGui::IsWindowHovered() ? std::to_string((int) hovered_grid_cell.x) : "-";
std::string status_y = ImGui::IsWindowHovered() ? std::to_string((int) hovered_grid_cell.y) : "-";
Expand Down Expand Up @@ -329,39 +321,52 @@ namespace Logicon {
void GCircuit::executePostponed() {
// @formatter:off
if (POSTPONED_OPERATIONS & POSTPONED_CONNECT)
postponedConnect(postponedConnectFrom.id, postponedConnectFrom.port, postponedConnectTo.id, postponedConnectTo.port);
postponedConnect();
if (POSTPONED_OPERATIONS & POSTPONED_DISCONNECT)
postponedDisconnect(postponedConnectFrom.id, postponedConnectFrom.port, postponedConnectTo.id, postponedConnectTo.port);
postponedDisconnect();
if (POSTPONED_OPERATIONS & POSTPONED_REMOVE)
postponedRemove(postponedRemoveId);
postponedRemove();
if (POSTPONED_OPERATIONS & POSTPONED_CLEAR)
postponedClear();

POSTPONED_OPERATIONS = 0;
// @formatter:on
}

void GCircuit::postponedRemove(ID id) {
// remove from graphical model
auto found = std::find_if(gBlocks.begin(), gBlocks.end(),
[id](const std::shared_ptr<GBlock> &gBlock) { return gBlock->getId() == id; });
if (found != gBlocks.end())
gBlocks.erase(found);
// remove from model
circuit->remove(id);
void GCircuit::postponedRemove() {
for (auto id : postponedRemoveList) {
// remove from graphical model
auto found = std::find_if(gBlocks.begin(), gBlocks.end(),
[id](const std::shared_ptr<GBlock> &gBlock) { return gBlock->getId() == id; });
if (found != gBlocks.end())
gBlocks.erase(found);
// remove from model
circuit->remove(id);
}
postponedRemoveList.clear();
}

void GCircuit::postponedClear() {
gBlocks.clear();
circuit->clear();
}

void GCircuit::postponedConnect(ID idFrom, Port output, ID idTo, Port input) {
circuit->connect(idFrom, output, idTo, input);
void GCircuit::postponedConnect() {
for (auto connectionPair : postponedConnectList)
circuit->connect(connectionPair.first.id, connectionPair.first.port,
connectionPair.second.id, connectionPair.second.port);
postponedConnectList.clear();
}

void GCircuit::postponedDisconnect() {
for (auto connectionPair : postponedDisconnectList)
circuit->disconnect(connectionPair.first.id, connectionPair.first.port,
connectionPair.second.id, connectionPair.second.port);
postponedDisconnectList.clear();
}

void GCircuit::postponedDisconnect(ID idFrom, Port output, ID idTo, Port input) {
circuit->disconnect(idFrom, output, idTo, input);
const UI::Vec2 &GCircuit::getHovered_grid_cell() const {
return hovered_grid_cell;
}


Expand Down
Loading

0 comments on commit 9d5add0

Please sign in to comment.