← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/bug-1791891-key-modifier-inputqueue into lp:widelands

 

Notabilis has proposed merging lp:~widelands-dev/widelands/bug-1791891-key-modifier-inputqueue into lp:widelands.

Commit message:
Adding support for Ctrl and Shift keys when using the increase/decrease buttons of input queues.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1791891 in widelands: "Ctrl/Shift-Click InputQueue buttons to change capacities faster"
  https://bugs.launchpad.net/widelands/+bug/1791891

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/bug-1791891-key-modifier-inputqueue/+merge/354732

Adding keyboard modifiers for faster adaption of input queue settings (see bug report).

Slight disadvantage of this branch: To allow a "decreasing" shift-click on an input queue that is already at minimum (and vice versa), the code to disable the buttons had to be removed. That means that the increase/decrease buttons will always look the same, even when a "normal" click on them won't change anything.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/bug-1791891-key-modifier-inputqueue into lp:widelands.
=== modified file 'src/wui/inputqueuedisplay.cc'
--- src/wui/inputqueuedisplay.cc	2018-09-10 05:59:47 +0000
+++ src/wui/inputqueuedisplay.cc	2018-09-11 21:08:35 +0000
@@ -285,7 +285,7 @@
 		return;
 	}
 	if (SDL_GetModState() & KMOD_CTRL) {
-		update_siblings(state);
+		update_siblings_priority(state);
 	}
 	igb_.game().send_player_set_ware_priority(building_, type_, index_, priority);
 }
@@ -294,11 +294,11 @@
 	// Already set option has been clicked again
 	// Unimportant for this queue, but update other queues
 	if (SDL_GetModState() & KMOD_CTRL) {
-		update_siblings(priority_radiogroup_->get_state());
+		update_siblings_priority(priority_radiogroup_->get_state());
 	}
 }
 
-void InputQueueDisplay::update_siblings(int32_t state) {
+void InputQueueDisplay::update_siblings_priority(int32_t state) {
 	// "Release" the CTRL key to avoid recursion
 	const SDL_Keymod old_modifiers = SDL_GetModState();
 	SDL_SetModState(KMOD_NONE);
@@ -340,19 +340,63 @@
  * stored here has been clicked
  */
 void InputQueueDisplay::decrease_max_fill_clicked() {
-	assert(cache_max_fill_ > 0);
 	if (!igb_.can_act(building_.owner().player_number())) {
 		return;
 	}
-	igb_.game().send_player_set_input_max_fill(building_, index_, type_, cache_max_fill_ - 1);
+
+	// Update the value of this queue if required
+	if (cache_max_fill_ > 0) {
+		igb_.game().send_player_set_input_max_fill(building_, index_, type_,
+			((SDL_GetModState() & KMOD_CTRL) ? 0 : cache_max_fill_ - 1));
+	}
+
+	// Update other queues of this building
+	if (SDL_GetModState() & KMOD_SHIFT) {
+		// Using int16_t instead of int32_t on purpose to avoid over-/underflows
+		update_siblings_fill(
+			((SDL_GetModState() & KMOD_CTRL) ? std::numeric_limits<int16_t>::min() : -1));
+	}
 }
 
 void InputQueueDisplay::increase_max_fill_clicked() {
-	assert(cache_max_fill_ < queue_.get_max_size());
 	if (!igb_.can_act(building_.owner().player_number())) {
 		return;
 	}
-	igb_.game().send_player_set_input_max_fill(building_, index_, type_, cache_max_fill_ + 1);
+
+	if (cache_max_fill_ < cache_size_) {
+		igb_.game().send_player_set_input_max_fill(building_, index_, type_,
+			((SDL_GetModState() & KMOD_CTRL) ? cache_size_ : cache_max_fill_ + 1));
+	}
+
+	if (SDL_GetModState() & KMOD_SHIFT) {
+		update_siblings_fill(
+			((SDL_GetModState() & KMOD_CTRL) ? std::numeric_limits<int16_t>::max() : 1));
+	}
+}
+
+void InputQueueDisplay::update_siblings_fill(int32_t delta) {
+	Panel* sibling = get_parent()->get_first_child();
+	// Well, at least we should be a child of our parent
+	assert(sibling != nullptr);
+	do {
+		if (sibling == this) {
+			// We already have been set
+			continue;
+		}
+		InputQueueDisplay* display = dynamic_cast<InputQueueDisplay*>(sibling);
+		if (display == nullptr) {
+			// Cast failed. Sibling is no InputQueueDisplay
+			continue;
+		}
+		uint32_t new_fill = std::max(0,
+								std::min<int32_t>(
+									static_cast<int32_t>(display->cache_max_fill_) + delta,
+									display->cache_size_));
+		if (new_fill != display->cache_max_fill_) {
+			igb_.game().send_player_set_input_max_fill(
+											building_, display->index_, display->type_, new_fill);
+		}
+	} while ((sibling = sibling->get_next_sibling()));
 }
 
 void InputQueueDisplay::compute_max_fill_buttons_enabled_state() {
@@ -364,11 +408,5 @@
 			increase_max_fill_->set_enabled(false);
 		if (decrease_max_fill_)
 			decrease_max_fill_->set_enabled(false);
-	} else {
-
-		if (decrease_max_fill_)
-			decrease_max_fill_->set_enabled(cache_max_fill_ > 0);
-		if (increase_max_fill_)
-			increase_max_fill_->set_enabled(cache_max_fill_ < queue_.get_max_size());
 	}
 }

=== modified file 'src/wui/inputqueuedisplay.h'
--- src/wui/inputqueuedisplay.h	2018-09-04 15:48:47 +0000
+++ src/wui/inputqueuedisplay.h	2018-09-11 21:08:35 +0000
@@ -87,7 +87,8 @@
 	void increase_max_fill_clicked();
 	void radiogroup_changed(int32_t);
 	void radiogroup_clicked();
-	void update_siblings(int32_t);
+	void update_siblings_priority(int32_t);
+	void update_siblings_fill(int32_t);
 
 	void compute_max_fill_buttons_enabled_state();
 };


Follow ups