1 /*
2  * Copyright (C) 2016 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef _WIDGETS_PANE_H_
21 #define _WIDGETS_PANE_H_
22 
23 #include <vector>
24 #include <algorithm>
25 #include <boost/shared_ptr.hpp>
26 
27 #include <stdint.h>
28 
29 #include <gdkmm/cursor.h>
30 #include <gtkmm/container.h>
31 #include <gtkmm/eventbox.h>
32 
33 #include "widgets/visibility.h"
34 
35 namespace Gtk {
36 	class Widget;
37 }
38 
39 namespace ArdourWidgets {
40 
41 class LIBWIDGETS_API Pane : public Gtk::Container
42 {
43 private:
44 	class Divider;
45 
46 public:
47 	struct Child
48 	{
49 		Pane* pane;
50 		Gtk::Widget* w;
51 		int32_t minsize;
52 		sigc::connection show_con;
53 		sigc::connection hide_con;
54 
ChildChild55 		Child (Pane* p, Gtk::Widget* widget, uint32_t ms) : pane (p), w (widget), minsize (ms) {}
56 	};
57 
58 	typedef std::vector<boost::shared_ptr<Child> > Children;
59 
60 	Pane (bool horizontal);
61 	~Pane();
62 
63 	void set_divider (std::vector<float>::size_type divider, float fract);
64 	float get_divider (std::vector<float>::size_type divider = 0);
65 	void set_child_minsize (Gtk::Widget const &, int32_t);
66 
67 	GType child_type_vfunc() const;
68 	void set_drag_cursor (Gdk::Cursor);
69 
70 	void set_check_divider_position (bool);
71 
72 protected:
73 	bool horizontal;
74 
75 	void on_add (Gtk::Widget*);
76 	void on_remove (Gtk::Widget*);
77 	void on_size_request (GtkRequisition*);
78 	void on_size_allocate (Gtk::Allocation&);
79 	bool on_expose_event (GdkEventExpose*);
80 
81 	bool handle_press_event (GdkEventButton*, Divider*);
82 	bool handle_release_event (GdkEventButton*, Divider*);
83 	bool handle_motion_event (GdkEventMotion*, Divider*);
84 	bool handle_enter_event (GdkEventCrossing*, Divider*);
85 	bool handle_leave_event (GdkEventCrossing*, Divider*);
86 
87 	void forall_vfunc (gboolean include_internals, GtkCallback callback, gpointer callback_data);
88 
89 private:
90 	Gdk::Cursor drag_cursor;
91 	bool did_move;
92 
93 	void reallocate (Gtk::Allocation const &);
94 
95 	Children children;
96 
97 	struct Divider : public Gtk::EventBox {
98 		Divider ();
99 
100 		float fract;
101 		bool dragging;
102 
103 		bool on_expose_event (GdkEventExpose* ev);
104 	};
105 
106 	typedef std::list<Divider*> Dividers;
107 	Dividers dividers;
108 	int divider_width;
109 	bool check_fract;
110 
111 	void add_divider ();
112 	void handle_child_visibility ();
113 	float constrain_fract (Dividers::size_type, float fract);
114 
115 	static void* notify_child_destroyed (void*);
116 	void* child_destroyed (Gtk::Widget*);
117 };
118 
119 class LIBWIDGETS_API HPane : public Pane
120 {
121   public:
HPane()122 	HPane () : Pane (true) {}
123 };
124 
125 class LIBWIDGETS_API VPane : public Pane
126 {
127   public:
VPane()128 	VPane () : Pane (false) {}
129 };
130 
131 } /* namespace */
132 
133 #endif
134