2
* This file is part of the apvlv package
4
* Copyright (C) 2008 Alf.
6
* Contact: Alf <naihe2010@gmail.com>
8
* This program is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU General Public License
10
* as published by the Free Software Foundation; either version 2.0 of
11
* the License, or (at your option) any later version.
13
* This program is distributed in the hope that it will be useful, but
14
* WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* General Public License for more details.
18
* You should have received a copy of the GNU General Public
19
* License along with this program; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
/* @CPPFILE ApvlvWindow.cpp
25
* Author: Alf <naihe2010@gmail.com>
27
/* @date Created: 2008/09/30 00:00:00 Alf */
29
#include "ApvlvView.hpp"
30
#include "ApvlvUtil.hpp"
31
#include "ApvlvParams.hpp"
32
#include "ApvlvDir.hpp"
33
#include "ApvlvWindow.hpp"
41
ApvlvWindow *ApvlvWindow::m_curWindow = NULL;
43
ApvlvWindow::ApvlvWindow (ApvlvCore *doc)
50
mCore = new ApvlvDoc (0, 0, gParams->values ("zoom"));
56
m_son = m_daughter = m_parent = NULL;
59
ApvlvWindow::~ApvlvWindow ()
66
debug ("delete window: %p", this);
72
if (m_parent->m_son == this)
74
m_parent->m_son = NULL;
76
else if (m_parent->m_daughter == this)
78
m_parent->m_daughter = NULL;
82
if (type == AW_SP || type == AW_VSP)
86
ApvlvWindow *win = m_son;
90
if (m_daughter != NULL)
92
ApvlvWindow *win = m_daughter;
97
g_object_unref (mPaned);
102
ApvlvWindow::widget ()
106
return mCore->widget ();
108
else if (type == AW_SP || type == AW_VSP)
114
errp ("type error: %d", type);
120
ApvlvWindow::setcurrentWindow (ApvlvWindow *pre, ApvlvWindow *win)
122
if (pre) asst (pre->type == AW_CORE);
123
asst (win->type == AW_CORE);
124
if (pre != NULL && pre->type == AW_CORE)
126
pre->mCore->setactive (false);
129
if (win->type == AW_CORE)
131
win->mCore->setactive (true);
138
ApvlvWindow::delcurrentWindow ()
140
asst (currentWindow ()->istop () == false);
142
ApvlvWindow *crwin = currentWindow ();
144
ApvlvWindow *pwin = crwin->m_parent;
145
ApvlvWindow *child = crwin == pwin->m_son? pwin->m_daughter: pwin->m_son;
146
ApvlvWindow *cwin = pwin->unbirth (crwin, child);
147
setcurrentWindow (NULL, cwin);
151
ApvlvWindow::currentWindow ()
157
ApvlvWindow::process (int ct, guint key)
160
debug ("input [%d]", key);
169
nwin = getneighbor (ct, key);
172
setcurrentWindow (this, nwin);
191
ApvlvWindow::getneighbor (int ct, guint key)
198
return getkj (1, false);
200
return getkj (1, true);
202
return gethl (1, false);
204
return gethl (1, true);
213
ApvlvWindow::getkj (int num, bool down)
215
ApvlvWindow *cw, *w, *nw, *fw;
218
asst (this && type == AW_CORE);
219
for (cw = fw = NULL, w = this; w != NULL; cw = w, w = w->m_parent)
221
if (w->type == AW_SP)
223
if ((cw == w->m_daughter && down == true)
224
|| (cw == w->m_son && down == false))
230
fw = down? w->m_daughter: w->m_son;
234
else if (w->type == AW_VSP)
236
if (cw != NULL && cw == w->m_daughter)
247
for ( nw = w = fw; w != NULL; )
249
if (w->type == AW_CORE)
254
else if (w->type == AW_SP)
256
w = down? w->m_son: w->m_daughter;
258
else if (w->type == AW_VSP)
260
w = right? w->m_daughter: w->m_son;
264
debug ("error type: %d", w->type);
273
ApvlvWindow::gethl (int num, bool right)
275
ApvlvWindow *cw, *w, *nw, *fw;
278
asst (this && type == AW_CORE);
279
for (cw = fw = NULL, w = this; w != NULL; cw = w, w = w->m_parent)
281
if (w->type == AW_VSP)
283
if ((cw == w->m_daughter && right == true)
284
|| (cw == w->m_son && right == false))
290
fw = right? w->m_daughter: w->m_son;
294
else if (w->type == AW_SP)
296
if (cw != NULL && cw == w->m_daughter)
307
for ( nw = w = fw; w != NULL; )
309
if (w->type == AW_CORE)
314
else if (w->type == AW_VSP)
316
w = right? w->m_son: w->m_daughter;
318
else if (w->type == AW_SP)
320
w = down? w->m_daughter: w->m_son;
324
debug ("error type: %d", w->type);
333
ApvlvWindow::getnext (int num)
335
ApvlvWindow *n = getkj (num, true);
338
n = gethl (num, true);
341
n = gethl (num, false);
343
n = getkj (num, false);
349
// birth a new AW_CORE window, and the new window beyond the input doc
350
// this made a AW_CORE window to AW_SP|AW_VSP
352
ApvlvWindow::birth (bool vsp, ApvlvCore *doc)
354
asst (type == AW_CORE);
358
debug ("can't birth with orign doc, copy it");
364
doc = mCore->copy ();
365
gView->regloaded (doc);
368
ApvlvWindow *nwindow = new ApvlvWindow (doc);
369
nwindow->m_parent = this;
372
ApvlvWindow *nwindow2 = new ApvlvWindow (mCore);
373
nwindow2->m_parent = this;
374
m_daughter = nwindow2;
376
mPaned = vsp == false? gtk_vpaned_new (): gtk_hpaned_new ();
377
g_object_ref (mPaned);
378
g_signal_connect (G_OBJECT (mPaned), "button-release-event", G_CALLBACK (apvlv_window_paned_resized_cb), this);
382
void (*panedcb) (GtkPaned *, GtkWidget *);
383
GtkWidget *parent = m_parent->mPaned;
384
if (gtk_paned_get_child1 (GTK_PANED (parent)) == widget ())
386
panedcb = gtk_paned_add1;
390
panedcb = gtk_paned_add2;
393
gtk_container_remove (GTK_CONTAINER (parent), widget ());
394
panedcb (GTK_PANED (parent), mPaned);
398
replace_widget (widget (), mPaned);
401
gtk_paned_pack1 (GTK_PANED (mPaned), nwindow->widget (), TRUE, TRUE);
402
gtk_paned_pack2 (GTK_PANED (mPaned), nwindow2->widget (), TRUE, TRUE);
404
type = vsp == false? AW_SP: AW_VSP;
407
nwindow->setsize (mWidth, mHeight / 2);
408
nwindow2->setsize (mWidth, mHeight / 2);
410
else if (type == AW_VSP)
412
nwindow->setsize (mWidth / 2, mHeight);
413
nwindow2->setsize (mWidth / 2, mHeight);
416
gtk_widget_show_all (mPaned);
418
setcurrentWindow (nwindow2, nwindow);
423
// @param 1, be delete
424
// @param 2, be unbirth, that is up to the parent
425
// return the new child
427
ApvlvWindow::unbirth (ApvlvWindow *dead, ApvlvWindow *child)
429
asst (type == AW_SP || type == AW_VSP);
433
void (*panedcb) (GtkPaned *, GtkWidget *);
434
GtkWidget *parent = m_parent->mPaned;
435
if (gtk_paned_get_child1 (GTK_PANED (parent)) == mPaned)
437
panedcb = gtk_paned_add1;
441
panedcb = gtk_paned_add2;
444
gtk_container_remove (GTK_CONTAINER (mPaned), child->widget ());
445
gtk_container_remove (GTK_CONTAINER (parent), mPaned);
446
panedcb (GTK_PANED (parent), child->widget ());
450
gtk_container_remove (GTK_CONTAINER (mPaned), child->widget ());
451
replace_widget (mPaned, child->widget ());
454
if (child->type == AW_CORE)
456
ApvlvCore *doc = child->getCore ();
460
else if (child->type == AW_SP || child->type == AW_VSP)
463
mPaned = child->mPaned;
464
m_son = child->m_son;
465
m_son->m_parent = this;
466
m_daughter = child->m_daughter;
467
m_daughter->m_parent = this;
468
child->type = AW_NONE;
471
gtk_widget_show_all (widget ());
479
for (win = this; win->type != AW_CORE; win = win->m_son);
485
ApvlvWindow::istop ()
487
return m_parent == NULL? true: false;
491
ApvlvWindow::getsize (int *width, int *height)
504
ApvlvWindow::setsize (int width, int height)
508
debug ("mWidth: %d, mHeight: %d", mWidth, mHeight);
512
mCore->setsize (mWidth, mHeight);
514
else if (type == AW_SP
517
g_timeout_add (50, apvlv_window_resize_children_cb, this);
522
ApvlvWindow::setCore (ApvlvCore *doc)
524
debug ("widget (): %p, doc->widget (): %p", widget (), doc->widget ());
527
mCore->inuse (false);
529
replace_widget (widget (), doc->widget ());
536
ApvlvWindow::getCore ()
538
asst (type == AW_CORE);
539
ApvlvCore *rdoc = mCore;
544
ApvlvWindow::smaller (int times)
546
if (m_parent == NULL) return;
548
int val = gtk_paned_get_position (GTK_PANED (m_parent->mPaned));
549
int len = 20 * times;
550
m_parent->m_son == this? val -= len: val += len;
551
gtk_paned_set_position (GTK_PANED (m_parent->mPaned), val);
553
m_parent->resize_children ();
557
ApvlvWindow::bigger (int times)
559
if (m_parent == NULL) return;
561
int val = gtk_paned_get_position (GTK_PANED (m_parent->mPaned));
562
int len = 20 * times;
563
m_parent->m_son == this? val += len: val -= len;
564
gtk_paned_set_position (GTK_PANED (m_parent->mPaned), val);
566
m_parent->resize_children ();
570
ApvlvWindow::apvlv_window_paned_resized_cb (GtkWidget *wid,
574
win->resize_children ();
579
ApvlvWindow::resize_children ()
581
int mw1 = mWidth, mw2 = mWidth, mh1 = mHeight, mh2 = mHeight;
582
int mi = GTK_PANED (mPaned)->min_position;
583
int ma = GTK_PANED (mPaned)->max_position;
584
int mv = gtk_paned_get_position (GTK_PANED (mPaned));
591
mh1 = (mHeight * (mv - mi)) / ms;
594
else if (type == AW_VSP)
596
mw1 = (mWidth * (mv - mi)) / ms;
600
m_son->setsize (mw1, mh1);
601
m_daughter->setsize (mw2, mh2);
612
ApvlvWindow::apvlv_window_resize_children_cb (gpointer data)
614
ApvlvWindow *win = (ApvlvWindow *) data;
615
return win->resize_children () == TRUE? FALSE: FALSE;