📄 render_frames.cpp
字号:
/** * This file is part of the KDE project. * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 2000 Simon Hausmann <hausmann@kde.org> * (C) 2000 Stefan Schimanski (1Stein@gmx.de) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * $Id: render_frames.cpp,v 1.93.2.3 2001/11/09 00:31:55 mueller Exp $ */#define DEBUG_LAYOUT#include "render_frames.h"#include "html_baseimpl.h"#include "html_objectimpl.h"#include "misc/htmlattrs.h"#include "dom2_eventsimpl.h"#include "htmltags.h"#include "khtmlview.h"#include "khtml_part.h"#include <kapp.h>#include <kdebug.h>#include <qlabel.h>#include <qstringlist.h>#include <assert.h>#include <kdebug.h>using namespace khtml;using namespace DOM;RenderFrameSet::RenderFrameSet( HTMLFrameSetElementImpl *frameSet, KHTMLView *view, QList<khtml::Length> *rows, QList<khtml::Length> *cols ) : RenderBox(){ // init RenderObject attributes setInline(false); m_frameset = frameSet; m_rows = rows; m_cols = cols; // another one for bad html // handle <frameset cols="*" rows="100, ..."> if ( m_rows && m_cols ) { // lets see if one of them is relative if ( m_rows->count() == 1 && m_rows->at( 0 )->isRelative() ) m_rows = 0; if ( m_cols->count() == 1 && m_cols->at( 0 )->isRelative() ) m_cols = 0; } m_rowHeight = 0; m_colWidth = 0; m_resizing = false; m_hSplit = -1; m_vSplit = -1; m_hSplitVar = 0; m_vSplitVar = 0; m_view = view;}RenderFrameSet::~RenderFrameSet(){ if ( m_rowHeight ) { delete [] m_rowHeight; m_rowHeight = 0; } if ( m_colWidth ) { delete [] m_colWidth; m_colWidth = 0; } delete [] m_hSplitVar; delete [] m_vSplitVar;}void RenderFrameSet::close(){ RenderBox::close(); if(m_frameset->verifyLayout()) setLayouted(false);}void RenderFrameSet::layout( ){ if ( strcmp( parent()->renderName(), "RenderFrameSet" ) != 0 ) { m_width = m_view->visibleWidth(); m_height = m_view->visibleHeight(); }#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << renderName() << "(FrameSet)::layout( ) width=" << width() << ", height=" << height() << endl;#endif int remainingWidth = m_width - (m_frameset->totalCols()-1)*m_frameset->border(); if(remainingWidth<0) remainingWidth=0; int remainingHeight = m_height - (m_frameset->totalRows()-1)*m_frameset->border(); if(remainingHeight<0) remainingHeight=0; int widthAvailable = remainingWidth; int heightAvailable = remainingHeight; if(m_rowHeight) delete [] m_rowHeight; if(m_colWidth) delete [] m_colWidth; m_rowHeight = new int[m_frameset->totalRows()]; m_colWidth = new int[m_frameset->totalCols()]; int i; int totalRelative = 0; int colsRelative = 0; int rowsRelative = 0; int rowsPercent = 0; int colsPercent = 0; int remainingRelativeWidth = 0; if(m_rows) { // another one for bad html. If all rows have a fixed width, convert the numbers to percentages. bool allFixed = true; int totalFixed = 0; for(i = 0; i< m_frameset->totalRows(); i++) { if(m_rows->at(i)->type != Fixed) allFixed = false; else totalFixed += m_rows->at(i)->value; } if ( allFixed && totalFixed ) { for(i = 0; i< m_frameset->totalRows(); i++) { m_rows->at(i)->type = Percent; m_rows->at(i)->value = m_rows->at(i)->value *100 / totalFixed; } } // first distribute the available width for fixed rows, then handle the // percentage ones, to fix html like <framesrc rows="123,100%,123"> and // finally relative for(i = 0; i< m_frameset->totalRows(); i++) { if(m_rows->at(i)->type == Fixed) { m_rowHeight[i] = QMAX(m_rows->at(i)->width(heightAvailable), 14); if( m_rowHeight[i] > remainingHeight ) m_rowHeight[i] = remainingHeight; remainingHeight -= m_rowHeight[i]; } else if(m_rows->at(i)->type == Relative) { totalRelative += m_rows->at(i)->value; rowsRelative++; } } for(i = 0; i< m_frameset->totalRows(); i++) { if(m_rows->at(i)->type == Percent) { m_rowHeight[i] = QMAX(m_rows->at(i)->width(heightAvailable), 14); if( m_rowHeight[i] > remainingHeight ) m_rowHeight[i] = remainingHeight; remainingHeight -= m_rowHeight[i]; rowsPercent++; } } // ### if(remainingHeight < 0) remainingHeight = 0; if ( !totalRelative && rowsRelative ) remainingRelativeWidth = remainingHeight/rowsRelative; for(i = 0; i< m_frameset->totalRows(); i++) { if(m_rows->at(i)->type == Relative) { if ( totalRelative ) m_rowHeight[i] = m_rows->at(i)->value*remainingHeight/totalRelative; else m_rowHeight[i] = remainingRelativeWidth; remainingHeight -= m_rowHeight[i]; totalRelative--; } } // support for totally broken frame declarations if(remainingHeight) { // just distribute it over all columns... int rows = m_frameset->totalRows(); if ( rowsPercent ) rows = rowsPercent; for(i = 0; i< m_frameset->totalRows(); i++) { if( !rowsPercent || m_rows->at(i)->type == Percent ) { int toAdd = remainingHeight/rows; rows--; m_rowHeight[i] += toAdd; remainingHeight -= toAdd; } } } } else m_rowHeight[0] = m_height; if(m_cols) { // another one for bad html. If all cols have a fixed width, convert the numbers to percentages. // also reproduces IE and NS behaviour. bool allFixed = true; int totalFixed = 0; for(i = 0; i< m_frameset->totalCols(); i++) { if(m_cols->at(i)->type != Fixed) allFixed = false; else totalFixed += m_cols->at(i)->value; } if ( allFixed && totalFixed) { for(i = 0; i< m_frameset->totalCols(); i++) { m_cols->at(i)->type = Percent; m_cols->at(i)->value = m_cols->at(i)->value * 100 / totalFixed; } } totalRelative = 0; remainingRelativeWidth = 0; // first distribute the available width for fixed columns, then handle the // percentage ones, to fix html like <framesrc cols="123,100%,123"> and // finally relative for(i = 0; i< m_frameset->totalCols(); i++) { if (m_cols->at(i)->type == Fixed) { m_colWidth[i] = QMAX(m_cols->at(i)->width(widthAvailable), 14); if( m_colWidth[i] > remainingWidth ) m_colWidth[i] = remainingWidth; remainingWidth -= m_colWidth[i]; } else if(m_cols->at(i)->type == Relative) { totalRelative += m_cols->at(i)->value; colsRelative++; } } for(i = 0; i< m_frameset->totalCols(); i++) { if(m_cols->at(i)->type == Percent) { m_colWidth[i] = QMAX(m_cols->at(i)->width(widthAvailable), 14); if( m_colWidth[i] > remainingWidth ) m_colWidth[i] = remainingWidth; remainingWidth -= m_colWidth[i]; colsPercent++; } } // ### if(remainingWidth < 0) remainingWidth = 0; if ( !totalRelative && colsRelative ) remainingRelativeWidth = remainingWidth/colsRelative; for(i = 0; i < m_frameset->totalCols(); i++) { if(m_cols->at(i)->type == Relative) { if ( totalRelative ) m_colWidth[i] = m_cols->at(i)->value*remainingWidth/totalRelative; else m_colWidth[i] = remainingRelativeWidth; remainingWidth -= m_colWidth[i]; totalRelative--; } } // support for totally broken frame declarations if(remainingWidth) { // just distribute it over all columns... int cols = m_frameset->totalCols(); if ( colsPercent ) cols = colsPercent; for(i = 0; i< m_frameset->totalCols(); i++) { if( !colsPercent || m_cols->at(i)->type == Percent ) { int toAdd = remainingWidth/cols; cols--; m_colWidth[i] += toAdd; remainingWidth -= toAdd; } } } } else m_colWidth[0] = m_width; positionFrames(); RenderObject *child = firstChild(); if ( !child ) return; if(!m_hSplitVar && !m_vSplitVar) {#ifdef DEBUG_LAYOUT kdDebug( 6031 ) << "calculationg fixed Splitters" << endl;#endif if(!m_vSplitVar && m_frameset->totalCols() > 1) { m_vSplitVar = new bool[m_frameset->totalCols()]; for(int i = 0; i < m_frameset->totalCols(); i++) m_vSplitVar[i] = true; } if(!m_hSplitVar && m_frameset->totalRows() > 1) { m_hSplitVar = new bool[m_frameset->totalRows()]; for(int i = 0; i < m_frameset->totalRows(); i++) m_hSplitVar[i] = true; } for(int r = 0; r < m_frameset->totalRows(); r++) { for(int c = 0; c < m_frameset->totalCols(); c++) { bool fixed = false; if ( strcmp( child->renderName(), "RenderFrameSet" ) == 0 ) fixed = static_cast<RenderFrameSet *>(child)->frameSetImpl()->noResize(); else fixed = static_cast<RenderFrame *>(child)->frameImpl()->noResize(); /* if(child->id() == ID_FRAMESET) fixed = (static_cast<HTMLFrameSetElementImpl *>(child))->noResize(); else if(child->id() == ID_FRAME) fixed = (static_cast<HTMLFrameElementImpl *>(child))->noResize(); */ if(fixed) {#ifdef DEBUG_LAYOUT kdDebug( 6031 ) << "found fixed cell " << r << "/" << c << "!" << endl;#endif if( m_frameset->totalCols() > 1) { if(c>0) m_vSplitVar[c-1] = false; m_vSplitVar[c] = false; } if( m_frameset->totalRows() > 1) { if(r>0) m_hSplitVar[r-1] = false; m_hSplitVar[r] = false; } child = child->nextSibling(); if(!child) goto end2; }#ifdef DEBUG_LAYOUT else kdDebug( 6031 ) << "not fixed: " << r << "/" << c << "!" << endl;#endif } } } end2: setLayouted();}void RenderFrameSet::positionFrames(){ int r; int c; RenderObject *child = firstChild(); if ( !child ) return; // NodeImpl *child = _first; // if(!child) return; int yPos = 0; for(r = 0; r < m_frameset->totalRows(); r++) { int xPos = 0; for(c = 0; c < m_frameset->totalCols(); c++) { // HTMLElementImpl *e = static_cast<HTMLElementImpl *>(child); child->setPos( xPos, yPos );#ifdef DEBUG_LAYOUT kdDebug(6040) << "child frame at (" << xPos << "/" << yPos << ") size (" << m_colWidth[c] << "/" << m_rowHeight[r] << ")" << endl;#endif child->setWidth( m_colWidth[c] ); child->setHeight( m_rowHeight[r] ); child->layout( ); xPos += m_colWidth[c] + m_frameset->border(); child = child->nextSibling(); if ( !child ) return; /* e->renderer()->setPos(xPos, yPos); e->setWidth(colWidth[c]); e->setAvailableWidth(colWidth[c]); e->setDescent(rowHeight[r]); e->layout(); xPos += colWidth[c] + border; child = child->nextSibling(); if(!child) return; */ } yPos += m_rowHeight[r] + m_frameset->border(); }}bool RenderFrameSet::userResize( MouseEventImpl *evt ){ bool res = false; int _x = evt->clientX(); int _y = evt->clientY(); if ( !m_resizing && evt->id() == EventImpl::MOUSEMOVE_EVENT || evt->id() == EventImpl::MOUSEDOWN_EVENT ) {#ifdef DEBUG_LAYOUT kdDebug( 6031 ) << "mouseEvent:check" << endl;#endif m_hSplit = -1; m_vSplit = -1; //bool resizePossible = true; // check if we're over a horizontal or vertical boundary int pos = m_colWidth[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -