initial commit, lordsawar source, slightly modified
[lordsawar] / src / gui / decorated.cpp
1 //  Copyright (C) 2008 Ben Asselstine
2 //
3 //  This program is free software; you can redistribute it and/or modify
4 //  it under the terms of the GNU General Public License as published by
5 //  the Free Software Foundation; either version 3 of the License, or
6 //  (at your option) any later version.
7 //
8 //  This program is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 //  GNU Library General Public License for more details.
12 //
13 //  You should have received a copy of the GNU General Public License
14 //  along with this program; if not, write to the Free Software
15 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
16 //  02110-1301, USA.
17
18 #include "decorated.h"
19 #include <sigc++/functors/mem_fun.h>
20 #include <gtkmm.h>
21
22 #include "defs.h"
23 #include "File.h"
24 #include "Configuration.h"
25 using namespace Gtk;
26 using namespace Gdk;
27 using namespace Glib;
28 Decorated::Decorated()
29 {
30 }
31
32 Decorated::~Decorated()
33 {
34   maximized = false;
35 }
36
37 void Decorated::decorate(Gtk::Window *d, std::string filename, int alpha)
38 {
39   window = d;
40   if (Configuration::s_decorated == false)
41     return;
42   Glib::RefPtr<Gtk::Style> copy;
43   RefPtr<Pixbuf> back;
44   RefPtr<Pixmap> pixmap;
45   RefPtr<Bitmap> bitmap;
46   window->set_decorated(true);
47   Gtk::Widget *focus = window->get_focus();
48   Gtk::Widget *child = window->get_child();
49   window->remove();
50   Gtk::Frame *windowdecoration =manage(new Gtk::Frame());
51   window->add(*windowdecoration);
52
53   windowdecoration->property_shadow_type() = Gtk::SHADOW_ETCHED_OUT;
54   Gtk::HBox *titlebox= new Gtk::HBox();
55   Gtk::EventBox *eventbox = manage(new Gtk::EventBox());
56
57   title = manage(new Gtk::Label(window->get_title()));
58   Gtk::Alignment *align= manage(new Gtk::Alignment());
59   align->set_padding(0, 0, 10, 10);
60   title->unset_bg(Gtk::STATE_NORMAL);
61   //align->add(*title);
62
63   eventbox->add(*align);
64   titlebox->pack_start(*eventbox, true, true, 5);
65   Gtk::Button *minimize_button = manage(new Gtk::Button());
66   minimize_button->set_label("_");
67   minimize_button->set_tooltip_text(_("Minimize"));
68   minimize_button->property_relief() = Gtk::RELIEF_NONE;
69   minimize_button->property_can_focus() = false;
70   minimize_button->signal_clicked().connect(sigc::mem_fun(window, &Gtk::Window::iconify));
71   if (window->get_type_hint() == Gdk::WINDOW_TYPE_HINT_NORMAL)
72     {
73       maximize_button = manage(new Gtk::Button());
74       maximize_button->set_label("^");
75       maximize_button->set_tooltip_text(_("Maximize"));
76       maximize_button->property_relief() = Gtk::RELIEF_NONE;
77       maximize_button->property_can_focus() = false;
78       maximize_button->signal_clicked().connect(sigc::mem_fun(this, &Decorated::on_maximize));
79     }
80   Gtk::Button *close_button = manage(new Gtk::Button());
81   close_button->set_label("x");
82   close_button->set_tooltip_text(_("Close"));
83   close_button->property_relief() = Gtk::RELIEF_NONE;
84   close_button->property_can_focus() = false;
85   close_button->signal_clicked().connect(sigc::mem_fun(this, &Decorated::on_hide));
86   //titlebox->pack_end(*close_button, false, false, 0);
87   //if (window->get_type_hint() == Gdk::WINDOW_TYPE_HINT_NORMAL)
88     //titlebox->pack_end(*maximize_button, false, false, 0);
89   //titlebox->pack_end(*minimize_button, false, false, 0);
90   //windowdecoration->set_label_align(Gtk::ALIGN_RIGHT);
91   //windowdecoration->set_label_widget(*titlebox);
92
93
94   windowdecoration->add(*manage(child));
95   titlebox->add_events(Gdk::POINTER_MOTION_MASK);
96   titlebox->signal_motion_notify_event().connect
97     (sigc::mem_fun(*this, &Decorated::on_mouse_motion_event));
98   copy = windowdecoration->get_style()->copy();
99
100   if (filename == "")
101     filename = File::getMiscFile("various/background.png");
102   back = Pixbuf::create_from_file(filename);
103   pixmap = Pixmap::create(window->get_window(), back->get_width(), back->get_height());
104   copy->set_bg(Gtk::STATE_NORMAL, Gdk::Color("black"));
105   window->set_style(copy);
106   back->composite_color(back, 0, 0, back->get_width(), back->get_height(), 0.0, 0.0, 1.0, 1.0, Gdk::INTERP_NEAREST, alpha, 0, 0, 64, 0, 0);
107   back->render_pixmap_and_mask(pixmap, bitmap, 10);
108   copy->set_bg_pixmap(Gtk::STATE_NORMAL, pixmap);
109   windowdecoration->show_all();
110   window->set_style(copy);
111   if (focus)
112     window->set_focus(*focus);
113 }
114
115 void Decorated::on_maximize()
116 {
117   maximized = !maximized;
118   if (maximized)
119     {
120       window->maximize();
121       maximize_button->set_label("#");
122       maximize_button->set_tooltip_text(_("Restore"));
123     }
124   else
125     {
126       window->unmaximize();
127       maximize_button->set_label("^");
128       maximize_button->set_tooltip_text(_("Maximize"));
129     }
130 }
131
132 bool Decorated::on_mouse_motion_event(GdkEventMotion *e)
133 {
134   int x, y;
135   window->get_position(x, y);
136   window->move(x + int(e->x), y + int(e->y));
137   return true;
138 }
139
140
141 void Decorated::set_title(std::string text)
142 {
143   if (Configuration::s_decorated)
144     {
145       title->set_text(text);
146       window->set_title(text);
147     }
148   else
149     window->set_title(text);
150 }
151
152 void Decorated::on_hide()
153 {
154   window_closed.emit();
155 }
156
157 void Decorated::decorate_border(Gtk::Viewport *container, int alpha)
158 {
159   if (Configuration::s_decorated == false)
160     return;
161   Glib::RefPtr<Gtk::Style> copy;
162   Glib::RefPtr<Gdk::Pixbuf> back;
163   Glib::RefPtr<Gdk::Pixmap> pixmap;
164   Glib::RefPtr<Gdk::Bitmap> bitmap;
165   copy = container->get_style()->copy();
166   back = Gdk::Pixbuf::create_from_file
167     (File::getMiscFile("various/back.bmp"));
168   pixmap = Gdk::Pixmap::create
169     (window->get_window(), back->get_width(), back->get_height());
170   back->composite_color(back, 0, 0, 
171                         back->get_width(), back->get_height(), 
172                         0.0, 0.0, 1.0, 1.0, Gdk::INTERP_NEAREST, alpha, 
173                         0, 0, 64, 0, 0);
174   back->render_pixmap_and_mask(pixmap, bitmap, 10);
175   copy->set_bg_pixmap(Gtk::STATE_NORMAL, pixmap);
176   container->set_style(copy);
177 }