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