Implements PXEGeek's http://wiki.synfig.com/Wish_list entry: "Optionally display...
[synfig.git] / synfig-studio / trunk / src / gtkmm / dockmanager.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file dockmanager.cpp
3 **      \brief Template File
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === H E A D E R S ======================================================= */
24
25 #ifdef USING_PCH
26 #       include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 #       include <config.h>
30 #endif
31
32 #include "dockmanager.h"
33 #include <stdexcept>
34 #include "dockable.h"
35 #include "dockdialog.h"
36 #include <synfigapp/settings.h>
37 #include <synfigapp/main.h>
38 #include <gdkmm/general.h>
39
40 #endif
41
42 /* === U S I N G =========================================================== */
43
44 using namespace std;
45 using namespace etl;
46 using namespace synfig;
47 using namespace studio;
48
49 /* === M A C R O S ========================================================= */
50
51 /* === P R O C E D U R E S ================================================= */
52
53 class studio::DockSettings : public synfigapp::Settings
54 {
55         DockManager* dock_manager;
56
57 public:
58         DockSettings(DockManager* dock_manager):dock_manager(dock_manager)
59         {
60                 synfigapp::Main::settings().add_domain(this,"dock");
61         }
62
63         virtual ~DockSettings()
64         {
65                 synfigapp::Main::settings().remove_domain("dock");
66         }
67 #define SCALE_FACTOR    (1280)
68         virtual bool get_value(const synfig::String& key_, synfig::String& value)const
69         {
70                 int screen_w(Gdk::screen_width());
71                 int screen_h(Gdk::screen_height());
72
73                 if(key_.size()>6 && String(key_.begin(),key_.begin()+6)=="dialog")try
74                 {
75                         synfig::String key(key_.begin()+7,key_.end());
76                         synfig::String::size_type separator=key.find_first_of('.');
77                         int id(atoi(synfig::String(key.begin(),key.begin()+separator).c_str()));
78                         key=synfig::String(key.begin()+separator+1,key.end());
79
80                         DockDialog& dock_dialog(dock_manager->find_dock_dialog(id));
81
82                         if(key=="contents_size")
83                         {
84                                 dock_dialog.rebuild_sizes();
85                                 vector<int>::const_iterator iter(dock_dialog.get_dock_book_sizes().begin());
86                                 vector<int>::const_iterator end(dock_dialog.get_dock_book_sizes().end());
87                                 value.clear();
88                                 for(;iter!=end;++iter)
89                                         value+=strprintf("%d ",(*iter)*SCALE_FACTOR/screen_h);
90                                 return true;
91                         }
92                         if(key=="pos")
93                         {
94                                 int x,y; dock_dialog.get_position(x,y);
95                                 value=strprintf("%d %d",x*SCALE_FACTOR/screen_w,y*SCALE_FACTOR/screen_h);
96                                 return true;
97                         }
98                         if(key=="size")
99                         {
100                                 int x,y; dock_dialog.get_size(x,y);
101                                 value=strprintf("%d %d",x*SCALE_FACTOR/screen_w,y*SCALE_FACTOR/screen_h);
102                                 return true;
103                         }
104                         if(key=="contents")
105                         {
106                                 value=dock_dialog.get_contents();
107                                 return true;
108                         }
109                         if(key=="comp_selector")
110                         {
111                                 value=dock_dialog.get_composition_selector()?"1":"0";
112                                 return true;
113                         }
114                 }catch (...) { return false; }
115                 return synfigapp::Settings::get_value(key_,value);
116         }
117
118         virtual bool set_value(const synfig::String& key_,const synfig::String& value)
119         {
120                 int screen_w(Gdk::screen_width());
121                 int screen_h(Gdk::screen_height());
122
123                 if(key_.size()>6 && String(key_.begin(),key_.begin()+6)=="dialog")
124                 {
125                         synfig::String key(key_.begin()+7,key_.end());
126                         synfig::String::size_type separator=key.find_first_of('.');
127                         int id(atoi(synfig::String(key.begin(),key.begin()+separator).c_str()));
128                         key=synfig::String(key.begin()+separator+1,key.end());
129
130                         DockDialog& dock_dialog(dock_manager->find_dock_dialog(id));
131
132                         if(key=="contents_size")
133                         {
134                                 try {
135
136                                 vector<int> data;
137                                 String::size_type n=0;
138                                 String value_(value);
139                                 while(value_.size() && (signed)value_.size()>n && n>=0){
140                                         value_=String(value_.begin()+n,value_.end());
141                                         int size;
142                                         if(!strscanf(value_,"%d",&size))
143                                                 break;
144                                         size=size*screen_h/SCALE_FACTOR;
145                                         data.push_back(size);
146
147                                         n=value_.find(" ");
148                                         if(n!=String::npos)
149                                                 n++;
150
151                                 }
152                                 dock_dialog.set_dock_book_sizes(data);
153                                 }
154                                 catch(...)
155                                 {
156                                         synfig::error("Exception caught!!!");
157                                         return false;
158                                 }
159                                 return true;
160                         }
161                         if(key=="pos")
162                         {
163                                 int x,y;
164                                 if(!strscanf(value,"%d %d",&x, &y))
165                                         return false;
166                                 x=x*screen_w/SCALE_FACTOR;
167                                 y=y*screen_h/SCALE_FACTOR;
168                                 dock_dialog.move(x,y);
169                                 return true;
170                         }
171                         if(key=="size")
172                         {
173                                 int x,y;
174                                 if(!strscanf(value,"%d %d",&x, &y))
175                                         return false;
176                                 x=x*screen_w/SCALE_FACTOR;
177                                 y=y*screen_h/SCALE_FACTOR;
178                                 dock_dialog.set_default_size(x,y);
179                                 dock_dialog.resize(x,y);
180                                 return true;
181                         }
182                         if(key=="contents")
183                         {
184                                 dock_dialog.set_contents(value);
185                                 return true;
186                         }
187                         if(key=="comp_selector")
188                         {
189                                 if(value.empty() || value[0]=='0')
190                                         dock_dialog.set_composition_selector(false);
191                                 else
192                                         dock_dialog.set_composition_selector(true);
193                                 return true;
194                         }
195                 }
196                 return synfigapp::Settings::set_value(key_,value);
197         }
198
199         virtual KeyList get_key_list()const
200         {
201                 synfigapp::Settings::KeyList ret(synfigapp::Settings::get_key_list());
202
203                 std::list<DockDialog*>::const_iterator iter;
204                 for(iter=dock_manager->dock_dialog_list_.begin();iter!=dock_manager->dock_dialog_list_.end();++iter)
205                 {
206                         ret.push_back(strprintf("dialog.%d.contents",(*iter)->get_id()));
207                         ret.push_back(strprintf("dialog.%d.comp_selector",(*iter)->get_id()));
208                         ret.push_back(strprintf("dialog.%d.pos",(*iter)->get_id()));
209                         ret.push_back(strprintf("dialog.%d.size",(*iter)->get_id()));
210                         ret.push_back(strprintf("dialog.%d.contents_size",(*iter)->get_id()));
211                 }
212                 return ret;
213         }
214 };
215
216 /* === M E T H O D S ======================================================= */
217
218 DockManager::DockManager():
219         dock_settings(new DockSettings(this))
220 {
221 }
222
223 DockManager::~DockManager()
224 {
225         while(!dock_dialog_list_.empty())
226         {
227                 dock_dialog_list_.back()->close();
228         }
229         while(!dockable_list_.empty())
230         {
231                 Dockable* dockable(dockable_list_.back());
232                 synfig::info("DockManager::~DockManager(): Deleting dockable \"%s\"",dockable->get_name().c_str());
233                 dockable_list_.pop_back();
234                 delete dockable;
235         }
236 }
237
238 void
239 DockManager::register_dockable(Dockable& x)
240 {
241         dockable_list_.push_back(&x);
242         synfig::info("DockManager::register_dockable(): Registered dockable \"%s\"",dockable_list_.back()->get_name().c_str());
243         signal_dockable_registered()(&x);
244 }
245
246 bool
247 DockManager::unregister_dockable(Dockable& x)
248 {
249         std::list<Dockable*>::iterator iter;
250         for(iter=dockable_list_.begin();iter!=dockable_list_.end();++iter)
251         {
252                 if(&x==*iter)
253                 {
254                         x.detach();
255                         dockable_list_.erase(iter);
256                         synfig::info("DockManager::unregister_dockable(): \"%s\" has been Unregistered",x.get_name().c_str());
257                         return true;
258                 }
259         }
260         return false;
261 }
262
263 Dockable&
264 DockManager::find_dockable(const synfig::String& x)
265 {
266         std::list<Dockable*>::iterator iter;
267         for(iter=dockable_list_.begin();iter!=dockable_list_.end();++iter)
268                 if((*iter)->get_name()==x)
269                         return **iter;
270
271         throw std::runtime_error("DockManager::find_dockable(): not found");
272 }
273
274 void
275 DockManager::present(synfig::String x)
276 {
277         try
278         {
279                 find_dockable(x).present();
280         }
281         catch(...)
282         {
283         }
284 }
285
286 DockDialog&
287 DockManager::find_dock_dialog(int id)
288 {
289         std::list<DockDialog*>::iterator iter;
290         for(iter=dock_dialog_list_.begin();iter!=dock_dialog_list_.end();++iter)
291                 if((*iter)->get_id()==id)
292                         return **iter;
293
294         DockDialog* dock_dialog(new DockDialog());
295         dock_dialog->set_id(id);
296         dock_dialog->show();
297         return *dock_dialog;
298 }
299
300 const DockDialog&
301 DockManager::find_dock_dialog(int id)const
302 {
303         std::list<DockDialog*>::const_iterator iter;
304         for(iter=dock_dialog_list_.begin();iter!=dock_dialog_list_.end();++iter)
305                 if((*iter)->get_id()==id)
306                         return **iter;
307
308         throw std::runtime_error("DockManager::find_dock_dialog(int id)const: not found");
309 }