Chapter 4. Word-wrapping labels

Index

Preserving window positions
Hello World!

This example follows up on the hello world program. It uses a create_label() overload to create a label that word-wraps its text to the given width.

See the section called “Building example programs” for more information on building this example:

/*
** Copyright 2017 Double Precision, Inc.
** See COPYING for distribution information.
*/

#include "config.h"
#include "close_flag.H"

#include <x/exception.H>
#include <x/destroy_callback.H>
#include <x/config.H>

#include <x/w/main_window.H>
#include <x/w/gridlayoutmanager.H>
#include <x/w/gridfactory.H>
#include <x/w/label.H>
#include <x/w/text_param_literals.H>
#include <x/w/font_literals.H>
#include <string>
#include <iostream>

// This is the creator lambda, that gets passed to create_mainwindow() below,
// factored out for readability.

void create_mainwindow(const x::w::main_window &main_window)
{
	x::w::rgb light_yellow{
		x::w::rgb::maximum,
		x::w::rgb::maximum,
		(x::w::rgb_component_t)(x::w::rgb::maximum * .75)},

		blue{0, 0, x::w::rgb::maximum},

		black{};

	main_window->set_background_color(light_yellow);

	x::w::gridlayoutmanager
		layout=main_window->get_layoutmanager();

	x::w::gridfactory factory=layout->append_row();

	factory->create_label({
		 blue,
		"underline"_decoration,
		"serif; point_size=24; weight=bold"_font,

	        "Lorem ipsum\n",

		"no"_decoration,
		"sans serif; point_size=12"_font,
		black,

		"dolor sit amet, consectetur adipisicing elit, "
		"sed do eiusmod tempor incididunt ut labore et dolore mana "
		"aliqua. Ut enim ad minim veniam, quis nostrud exercitation "
		"ullamco laboris nisi ut aliquip ex ea commodo consequat. "
		"Duis aute irure dolor in reprehenderit in voluptate velit "
		"esse cillum dolore eu fugiat nulla pariatur. "
		"Excepteur sint occaecat cupidatat non proident, "
		"sunt in culpa qui officia deserunt mollit anim id est "
		"laborum."
	  },
		100.0, // Initial text width is 100 millimeters


		// Optional parameter, alignment:
		x::w::halign::center);
}

void wordwrap()
{
	x::destroy_callback::base::guard guard;

	auto close_flag=close_flag_ref::create();

	// Configuration filename where we save the window's position.

	std::string configfile=
		x::configdir("wordwraplabel@examples.w.libcxx.com")
		+ "/windows";

	// Load the saved window position.
	//
	// x::w::screen_positions_t is a container, a std::unordered_map.
	// The key is a std::string, the value is an x::w::screen_position.
	// An overloaded main_window create() takes additional parameters
	// specifying the container, and the name of the key for the saved
	// window position. This allows the container to hold multiple
	// windows' saved positions. Window names are arbitrary labels.
	//
	// load_screen_positions() returns an empty container if the
	// configuration file does not exist. It is not an error if the
	// named window's position does not exist in the container, the
	// main_window gets created normally, but without the restored
	// position.

	x::w::screen_positions_t pos=
		x::w::load_screen_positions(configfile);

	auto main_window=
		x::w::main_window::create(pos, "main", create_mainwindow);

	main_window->on_disconnect([]
				   {
					   _exit(1);
				   });

	guard(main_window->connection_mcguffin());

	main_window->set_window_title("Hello world!");
	main_window->set_window_class("main", "wordwraplabel@examples.w.libcxx.com");
	main_window->on_delete
		([close_flag]
		 (THREAD_CALLBACK,
		  const x::w::busy &ignore)
		 {
			 close_flag->close();
		 });

	main_window->show_all();

	close_flag->wait();

	// And save the window's final position, so that it get be used the
	// next time this program runs.

	pos.clear();
	pos.emplace("main", main_window->get_screen_position());

	x::w::save_screen_positions(configfile, pos);
}

int main(int argc, char **argv)
{
	try {
		wordwrap();
	} catch (const x::exception &e)
	{
		e->caught();
		exit(1);
	}
	return 0;
}

Notes:

wordwraplabel.C also demonstrates several other formatting options for the text parameter:

Preserving window positions

Running wordwraplabel.C again should open its window in the same position where it was previously, This stickiness needs some additional coding, and the actual behavior may vary depending upon the display screen's window manager, the ultimate judge where windows open and how big they are.

#include <x/config.H>

std::string configfile=
   x::configdir("wordwraplabel@examples.w.libcxx.com")
		+ "/windows";

x::w::screen_positions_t pos;

pos.emplace("main", main_window->get_screen_position());
x::w::save_screen_positions(configfile, pos);

x::w::main_window's get_screen_position() gets called before the program ends. This returns the window's last known position on the screen. The position gets saved in an x::w::screen_positions_t, which is a container whose key is the window's identifier, a string assigned by the application. The application may put more than one window's position in the container, using a unique identifier for each window. x::w::save_screen_positions() saves the contents of the x::w::screen_positions_t in a file. This example program uses LibCXX's base library's x::configdir function to initialize a configuration directory for wordwraplabel's use, where the window's position get saved.

x::w::screen_positions_t pos=
   x::w::load_screen_positions(configfile);

auto main_window=
    x::w::main_window::create(pos, "main",
                              [&]
                              (const x::w::main_window)
                              {
                                 // ...

x::w::load_screen_positions() loads the previously-saved positions into the x::w::screen_positions_t container, if the file exists. The resulting container, and the application-assigned label for the main window gets passed to the overloaded main window create()or. If the named window's position got saved the last time wordwraplabel ran, the same position and size gets set for the new window.

Note

It's possible that application windows will open in their last known position even without explicitly saving them this way. Some window managers try to remember application windows, and open them in the same location. It's also possible that an application's requested window position gets ignored by the window manager, and the application window still opens in some other location on the screen.