← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/f_for_fullscreen into lp:widelands

 

SirVer has proposed merging lp:~widelands-dev/widelands/f_for_fullscreen into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #682351 in widelands: "wishlist: Fullscreen toogle also in Menu"
  https://bugs.launchpad.net/widelands/+bug/682351

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/f_for_fullscreen/+merge/243227

- Introduce the concept of global hotkeys that are triggered when the UI did not
  handle a key.
- Make f a global hotkey for changing to fullscreen.

Known issue: All fullscreen menus work under the assumption that the resolution does not change in them, this is no longer true if the switch to fullscreen is made. The fix is easy: all menus need to have a layout() virtual method that places all children instead of doing everything in the constructor as it is done now. The base class can listen to graphic resolution changes and call layout() in the handler. This is a lot of manual work that I am not willing to do right now, so I call the current state better than what we had before.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/f_for_fullscreen into lp:widelands.
=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc	2014-11-23 14:34:38 +0000
+++ src/editor/editorinteractive.cc	2014-11-30 10:15:03 +0000
@@ -421,11 +421,6 @@
 			handled = true;
 			break;
 
-		case SDLK_f:
-			g_gr->set_fullscreen(!g_gr->fullscreen());
-			handled = true;
-			break;
-
 		case SDLK_h:
 			toggle_mainmenu();
 			handled = true;

=== modified file 'src/ui_basic/panel.cc'
--- src/ui_basic/panel.cc	2014-11-22 14:17:11 +0000
+++ src/ui_basic/panel.cc	2014-11-30 10:15:03 +0000
@@ -1080,56 +1080,66 @@
  * Input callback function. Pass the mouseclick event to the currently modal
  * panel.
 */
-void Panel::ui_mousepress(const uint8_t button, int32_t x, int32_t y) {
-	if (!_g_allow_user_input)
-		return;
+bool Panel::ui_mousepress(const uint8_t button, int32_t x, int32_t y) {
+	if (!_g_allow_user_input) {
+		return true;
+	}
 
-	if (Panel * const p = ui_trackmouse(x, y))
-		p->do_mousepress(button, x, y);
+	Panel * const p = ui_trackmouse(x, y);
+	if (p == nullptr) {
+		return false;
+	}
+	return p->do_mousepress(button, x, y);
 }
-void Panel::ui_mouserelease(const uint8_t button, int32_t x, int32_t y) {
-	if (!_g_allow_user_input)
-		return;
-
-	if (Panel * const p = ui_trackmouse(x, y))
-		p->do_mouserelease(button, x, y);
+
+bool Panel::ui_mouserelease(const uint8_t button, int32_t x, int32_t y) {
+	if (!_g_allow_user_input) {
+		return true;
+	}
+
+	Panel * const p = ui_trackmouse(x, y);
+	if (p == nullptr) {
+		return false;
+	}
+	return p->do_mouserelease(button, x, y);
 }
 
 /**
  * Input callback function. Pass the mousemove event to the currently modal
  * panel.
 */
-void Panel::ui_mousemove
+bool Panel::ui_mousemove
 	(uint8_t const state,
 	 int32_t x, int32_t y, int32_t const xdiff, int32_t const ydiff)
 {
-	if (!_g_allow_user_input)
-		return;
+	if (!_g_allow_user_input) {
+		return true;
+	}
 
-	if (!xdiff && !ydiff)
-		return;
+	if (!xdiff && !ydiff) {
+		return true;
+	}
 
 	Panel * p;
-
 	g_gr->update();
 
 	p = ui_trackmouse(x, y);
 	if (!p)
-		return;
+		return false;
 
-	p->do_mousemove(state, x, y, xdiff, ydiff);
+	return p->do_mousemove(state, x, y, xdiff, ydiff);
 }
 
 /**
  * Input callback function. Pass the mousewheel event to the currently modal
  * panel.
 */
-void Panel::ui_mousewheel(uint32_t which, int32_t x, int32_t y) {
+bool Panel::ui_mousewheel(uint32_t which, int32_t x, int32_t y) {
 	if (!_g_allow_user_input) {
-		return;
+		return true;
 	}
 	if (!x && !y) {
-		return;
+		return true;
 	}
 	Panel* p = nullptr;
 	if (_g_mousein) {
@@ -1137,32 +1147,34 @@
 	} else {
 		p = _g_mousegrab ? _g_mousegrab : _modal;
 	}
-	if (p) {
-		p->do_mousewheel(which, x, y);
+	if (!p) {
+		return false;
 	}
+	return p->do_mousewheel(which, x, y);
 }
 
 
 /**
  * Input callback function. Pass the key event to the currently modal panel
  */
-void Panel::ui_key(bool const down, SDL_Keysym const code)
+bool Panel::ui_key(bool const down, SDL_Keysym const code)
 {
-	if (!_g_allow_user_input)
-		return;
+	if (!_g_allow_user_input) {
+		return true;
+	}
 
-	_modal->do_key(down, code);
+	return _modal->do_key(down, code);
 }
 
 
 /**
  * Input callback function. Pass the textinput event to the currently modal panel
  */
-void Panel::ui_textinput(const std::string& text) {
+bool Panel::ui_textinput(const std::string& text) {
 	if (!_g_allow_user_input) {
-		return;
+		return true;
 	}
-	_modal->do_textinput(text);
+	return _modal->do_textinput(text);
 }
 
 /**

=== modified file 'src/ui_basic/panel.h'
--- src/ui_basic/panel.h	2014-11-22 13:59:44 +0000
+++ src/ui_basic/panel.h	2014-11-30 10:15:03 +0000
@@ -282,13 +282,13 @@
 	bool do_tooltip();
 
 	static Panel * ui_trackmouse(int32_t & x, int32_t & y);
-	static void ui_mousepress  (const uint8_t button, int32_t x, int32_t y);
-	static void ui_mouserelease(const uint8_t button, int32_t x, int32_t y);
-	static void ui_mousemove
+	static bool ui_mousepress  (const uint8_t button, int32_t x, int32_t y);
+	static bool ui_mouserelease(const uint8_t button, int32_t x, int32_t y);
+	static bool ui_mousemove
 		(const uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff);
-	static void ui_mousewheel(uint32_t which, int32_t x, int32_t y);
-	static void ui_key(bool down, SDL_Keysym code);
-	static void ui_textinput(const std::string& text);
+	static bool ui_mousewheel(uint32_t which, int32_t x, int32_t y);
+	static bool ui_key(bool down, SDL_Keysym code);
+	static bool ui_textinput(const std::string& text);
 
 	Panel * _parent;
 	Panel * _next, * _prev;

=== modified file 'src/ui_fsmenu/base.cc'
--- src/ui_fsmenu/base.cc	2014-09-18 18:52:34 +0000
+++ src/ui_fsmenu/base.cc	2014-11-30 10:15:03 +0000
@@ -42,30 +42,22 @@
 ==============================================================================
 */
 
-struct FullscreenMenuBase::Data {
-	const Image* res_background;
-	UI::TextStyle textstyle_small;
-	UI::TextStyle textstyle_big;
-};
-
 /**
  * Initialize a pre-game menu
  *
  * Args: bgpic  name of the background picture
  */
-FullscreenMenuBase::FullscreenMenuBase(char const * const bgpic)
-	: UI::Panel(nullptr, 0, 0, gr_x(), gr_y()),
-	d(new Data)
-{
+FullscreenMenuBase::FullscreenMenuBase(char const* const bgpic)
+   : UI::Panel(nullptr, 0, 0, g_gr->get_xres(), g_gr->get_yres()) {
 	// Load background graphics
 	const std::string bgpicpath = (boost::format("pics/%s") % bgpic).str();
-	d->res_background = ImageTransformations::resize(g_gr->images().get(bgpicpath), get_w(), get_h());
-
-	d->textstyle_small = UI::TextStyle::ui_small();
-	d->textstyle_small.font = UI::Font::get(ui_fn(), fs_small());
-
-	d->textstyle_big = UI::TextStyle::ui_big();
-	d->textstyle_big.font = UI::Font::get(ui_fn(), fs_big());
+	background_ = ImageTransformations::resize(g_gr->images().get(bgpicpath), get_w(), get_h());
+
+	textstyle_small_ = UI::TextStyle::ui_small();
+	textstyle_small_.font = UI::Font::get(ui_fn(), fs_small());
+
+	textstyle_big_ = UI::TextStyle::ui_big();
+	textstyle_big_.font = UI::Font::get(ui_fn(), fs_big());
 }
 
 FullscreenMenuBase::~FullscreenMenuBase()
@@ -77,18 +69,8 @@
  * Draw the background / splash screen
 */
 void FullscreenMenuBase::draw(RenderTarget & dst) {
-	dst.blit(Point(0, 0), d->res_background);
-}
-
-
-uint32_t FullscreenMenuBase::gr_x() {
-	return g_gr->get_xres();
-}
-
-uint32_t FullscreenMenuBase::gr_y() {
-	return g_gr->get_yres();
-}
-
+	dst.blit(Point(0, 0), background_);
+}
 
 uint32_t FullscreenMenuBase::fs_small() {
 	return UI_FONT_SIZE_SMALL * get_h() / 600;
@@ -100,20 +82,20 @@
 
 UI::TextStyle & FullscreenMenuBase::ts_small()
 {
-	return d->textstyle_small;
+	return textstyle_small_;
 }
 
 UI::TextStyle & FullscreenMenuBase::ts_big()
 {
-	return d->textstyle_big;
+	return textstyle_big_;
 }
 
 UI::Font * FullscreenMenuBase::font_small()
 {
-	return d->textstyle_small.font;
+	return textstyle_small_.font;
 }
 
 UI::Font * FullscreenMenuBase::font_big()
 {
-	return d->textstyle_big.font;
+	return textstyle_big_.font;
 }

=== modified file 'src/ui_fsmenu/base.h'
--- src/ui_fsmenu/base.h	2014-09-10 14:08:25 +0000
+++ src/ui_fsmenu/base.h	2014-11-30 10:15:03 +0000
@@ -23,12 +23,10 @@
 #include <string>
 #include <memory>
 
+#include "graphic/font.h"
 #include "ui_basic/panel.h"
 
-namespace UI {
-struct Font;
-struct TextStyle;
-}
+class Image;
 
 /**
  * This class is the base class for a fullscreen menu.
@@ -37,7 +35,7 @@
  */
 struct FullscreenMenuBase : public UI::Panel {
 	FullscreenMenuBase(char const * bgpic);
-	~FullscreenMenuBase();
+	virtual ~FullscreenMenuBase();
 
 	void draw(RenderTarget &) override;
 
@@ -53,14 +51,9 @@
 	UI::Font * font_big();
 
 private:
-	/**
-	 * Query the configured screen resolution.
-	 */
-	uint32_t gr_x();
-	uint32_t gr_y();
-
-	struct Data;
-	std::unique_ptr<Data> d;
+	UI::TextStyle textstyle_big_;
+	UI::TextStyle textstyle_small_;
+	const Image* background_;
 };
 
 

=== modified file 'src/ui_fsmenu/intro.cc'
--- src/ui_fsmenu/intro.cc	2014-10-14 07:55:05 +0000
+++ src/ui_fsmenu/intro.cc	2014-11-30 10:15:03 +0000
@@ -50,5 +50,5 @@
 	if (down && code.sym == SDLK_ESCAPE)
 		end_modal(0);
 
-	return true;
+	return false;
 }

=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc	2014-11-23 14:34:38 +0000
+++ src/wlapplication.cc	2014-11-30 10:15:03 +0000
@@ -483,48 +483,64 @@
 	return true;
 }
 
-/**
- * Pump the event queue, get packets from the network, etc...
- */
+bool WLApplication::handle_key(const SDL_Keycode& keycode, int modifiers) {
+	const bool ctrl = (modifiers & KMOD_LCTRL) || (modifiers & KMOD_RCTRL);
+	switch (keycode) {
+	case SDLK_F10:
+		// exits the game.
+		if (ctrl) {
+			m_should_die = true;
+		}
+		return true;
+
+	case SDLK_F11:
+		// Takes a screenshot.
+		if (ctrl) {
+			if (g_fs->disk_space() < MINIMUM_DISK_SPACE) {
+				log("Omitting screenshot because diskspace is lower than %luMB\n",
+				    MINIMUM_DISK_SPACE / (1000 * 1000));
+				break;
+			}
+			g_fs->ensure_directory_exists(SCREENSHOT_DIR);
+			for (uint32_t nr = 0; nr < 10000; ++nr) {
+				const std::string filename = (boost::format(SCREENSHOT_DIR "/shot%04u.png") % nr).str();
+				if (g_fs->file_exists(filename)) {
+					continue;
+				}
+				g_gr->screenshot(filename);
+				break;
+			}
+		}
+		return true;
+
+	case SDLK_f: {
+		// toggle fullscreen
+		bool value = !g_gr->fullscreen();
+		g_gr->set_fullscreen(value);
+		g_options.pull_section("global").set_bool("fullscreen", value);
+		return true;
+	}
+
+	default:
+		break;
+	}
+	return false;
+}
+
 void WLApplication::handle_input(InputCallback const * cb)
 {
 	SDL_Event ev;
 	while (poll_event(ev)) {
 		switch (ev.type) {
-		case SDL_KEYDOWN:
-		case SDL_KEYUP:
-			if (ev.key.keysym.sym == SDLK_F10 &&
-			    (get_key_state(SDL_SCANCODE_LCTRL) || get_key_state(SDL_SCANCODE_RCTRL))) {
-				//  get out of here quick
-				if (ev.type == SDL_KEYDOWN)
-					m_should_die = true;
-				break;
-			}
-			if (ev.key.keysym.sym == SDLK_F11) { //  take screenshot
-				if (ev.type == SDL_KEYDOWN)
-				{
-					if (g_fs->disk_space() < MINIMUM_DISK_SPACE) {
-						log
-							("Omitting screenshot because diskspace is lower than %luMB\n",
-							 MINIMUM_DISK_SPACE / (1000 * 1000));
-						break;
-					}
-					g_fs->ensure_directory_exists(SCREENSHOT_DIR);
-					for (uint32_t nr = 0; nr < 10000; ++nr) {
-						const std::string filename = (boost::format(SCREENSHOT_DIR "/shot%04u.png")
-																% nr).str();
-						if (g_fs->file_exists(filename))
-							continue;
-						g_gr->screenshot(filename);
-						break;
-					}
-				}
-				break;
-			}
+		case SDL_KEYDOWN: {
+			bool handled = false;
 			if (cb && cb->key) {
-				cb->key(ev.type == SDL_KEYDOWN, ev.key.keysym);
-			}
-			break;
+				handled = cb->key(ev.type == SDL_KEYDOWN, ev.key.keysym);
+			}
+			if (!handled) {
+				handle_key(ev.key.keysym.sym, ev.key.keysym.mod);
+			}
+		} break;
 
 		case SDL_TEXTINPUT:
 			if (cb && cb->textinput) {

=== modified file 'src/wlapplication.h'
--- src/wlapplication.h	2014-11-23 14:34:38 +0000
+++ src/wlapplication.h	2014-11-30 10:15:03 +0000
@@ -48,19 +48,19 @@
 	{}
 };
 
-// input
+// Callbacks input events to the UI. All functions return true when the event
+// was handled, false otherwise.
 struct InputCallback {
-	void (*mouse_press)
-	(const uint8_t button, // Button number as #defined in SDL_mouse.h.
-	 int32_t x, int32_t y);      // The coordinates of the mouse at press time.
-	void (*mouse_release)
-	(const uint8_t button, // Button number as #defined in SDL_mouse.h.
-	 int32_t x, int32_t y);      // The coordinates of the mouse at release time.
-	void (*mouse_move)
-	(const uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff);
-	void (*key)        (bool down, SDL_Keysym code);
-	void (*textinput) (const std::string& text);
-	void (*mouse_wheel) (uint32_t which, int32_t x, int32_t y);
+	bool (*mouse_press)(const uint8_t button,  // Button number as #defined in SDL_mouse.h.
+	                    int32_t x,
+	                    int32_t y);              // The coordinates of the mouse at press time.
+	bool (*mouse_release)(const uint8_t button,  // Button number as #defined in SDL_mouse.h.
+	                      int32_t x,
+	                      int32_t y);  // The coordinates of the mouse at release time.
+	bool (*mouse_move)(const uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff);
+	bool (*key)(bool down, SDL_Keysym code);
+	bool (*textinput)(const std::string& text);
+	bool (*mouse_wheel)(uint32_t which, int32_t x, int32_t y);
 };
 
 /// You know main functions, of course. This is the main struct.
@@ -168,6 +168,7 @@
 	// Refresh the graphics settings with the latest options.
 	void refresh_graphics();
 
+	 // Pump SDL events and dispatch them.
 	void handle_input(InputCallback const *);
 
 	void mainmenu();
@@ -204,6 +205,10 @@
 
 	bool redirect_output(std::string path = "");
 
+	// Handle the given pressed key. Returns true when key was
+	// handled.
+	bool handle_key(const SDL_Keycode& keycode, int modifiers);
+
 	/**
 	 * The commandline, conveniently repackaged.
 	 */

=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc	2014-11-27 11:15:34 +0000
+++ src/wui/interactive_base.cc	2014-11-30 10:15:03 +0000
@@ -446,7 +446,10 @@
 			((fps_format %
 			  (1000.0 / m_frametime) % (1000.0 / (m_avg_usframetime / 1000)))
 			 .str(), UI_FONT_SIZE_SMALL);
-		dst.blit(Point(5, (is_game) ? 25 : 5), UI::g_fh1->render(fps_text), BlendMode::UseAlpha, UI::Align_Left);
+		dst.blit(Point(5, (is_game) ? 25 : 5),
+		         UI::g_fh1->render(fps_text),
+		         BlendMode::UseAlpha,
+		         UI::Align_Left);
 	}
 }
 

=== modified file 'src/wui/interactive_player.cc'
--- src/wui/interactive_player.cc	2014-11-23 14:34:38 +0000
+++ src/wui/interactive_player.cc	2014-11-30 10:15:03 +0000
@@ -401,10 +401,6 @@
 					(dfShowStatistics, !get_display_flag(dfShowStatistics));
 			return true;
 
-		case SDLK_f:
-			g_gr->set_fullscreen(!g_gr->fullscreen());
-			return true;
-
 		case SDLK_KP_7:
 			if (code.mod & KMOD_NUM)
 				break;

=== modified file 'src/wui/interactive_spectator.cc'
--- src/wui/interactive_spectator.cc	2014-11-23 14:34:38 +0000
+++ src/wui/interactive_spectator.cc	2014-11-30 10:15:03 +0000
@@ -263,10 +263,6 @@
 					(dfShowStatistics, !get_display_flag(dfShowStatistics));
 			return true;
 
-		case SDLK_f:
-			g_gr->set_fullscreen(!g_gr->fullscreen());
-			return true;
-
 		case SDLK_RETURN:
 		case SDLK_KP_ENTER:
 			if (!m_chatProvider | !m_chatenabled)


Follow ups