summaryrefslogtreecommitdiff
path: root/libs/gtkmm2ext/gtkmm2ext/pane.h
blob: 9612da08d28dd5771a14e2e60e0f4873ab9b9800 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
    Copyright (C) 2016 Paul Davis

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifndef __libgtkmm2ext_pane_h__
#define __libgtkmm2ext_pane_h__

#include <vector>
#include <algorithm>

#include <stdint.h>

#include <gdkmm/cursor.h>
#include <gtkmm/container.h>
#include <gtkmm/eventbox.h>

#include "gtkmm2ext/visibility.h"

namespace Gtk {
	class Widget;
}

namespace Gtkmm2ext {

class LIBGTKMM2EXT_API Pane : public Gtk::Container
{
  private:
	class Divider;


  public:
	struct Child
	{
		Pane* pane;
		Gtk::Widget* w;
		int32_t minsize;

		Child (Pane* p, Gtk::Widget* widget, uint32_t ms) : pane (p), w (widget), minsize (ms) {}
	};

	typedef std::list<Child> Children;

	Pane (bool horizontal);
	~Pane();

	void set_divider (std::vector<float>::size_type divider, float fract);
	float get_divider (std::vector<float>::size_type divider = 0);
	void set_child_minsize (Gtk::Widget const &, int32_t);

	GType child_type_vfunc() const;
	void set_drag_cursor (Gdk::Cursor);

	void set_check_divider_position (bool);

  protected:
	bool horizontal;

	void on_add (Gtk::Widget*);
	void on_remove (Gtk::Widget*);
	void on_size_request (GtkRequisition*);
	void on_size_allocate (Gtk::Allocation&);
	bool on_expose_event (GdkEventExpose*);

	bool handle_press_event (GdkEventButton*, Divider*);
	bool handle_release_event (GdkEventButton*, Divider*);
	bool handle_motion_event (GdkEventMotion*, Divider*);
	bool handle_enter_event (GdkEventCrossing*, Divider*);
	bool handle_leave_event (GdkEventCrossing*, Divider*);

	void forall_vfunc (gboolean include_internals, GtkCallback callback, gpointer callback_data);

  private:
	Gdk::Cursor drag_cursor;
	bool did_move;

	void reallocate (Gtk::Allocation const &);

	Children children;

	struct Divider : public Gtk::EventBox {
		Divider ();

		float fract;
		bool dragging;

		bool on_expose_event (GdkEventExpose* ev);
	};

	typedef std::list<Divider*> Dividers;
	Dividers dividers;
	int divider_width;
	bool check_fract;

	void add_divider ();
	void handle_child_visibility ();
	bool fract_is_ok (Dividers::size_type, float fract);

	static void* notify_child_destroyed (void*);
	void* child_destroyed (Gtk::Widget*);
};

class LIBGTKMM2EXT_API HPane : public Pane
{
  public:
	HPane () : Pane (true) {}
};

class LIBGTKMM2EXT_API VPane : public Pane
{
  public:
	VPane () : Pane (false) {}
};

} /* namespace */

#endif /* __libgtkmm2ext_pane_h__ */