⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qtree.java

📁 lumaQQ的源文件
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
	
	/**
	 * 得到Item的缩进值
	 * 
	 * @param level
	 * 		层号
	 * @return
	 * 		水平缩进象素值
	 */
	int getItemIndent(int level) {
		return level * levelIndent;
	}
	
	/**
	 * 得到item在父item中的y坐标,假设父item是展开的
	 * 
	 * @param item
	 * 		QItem对象
	 * @return
	 * 		y坐标
	 */
	private int getYInParent(QItem item) {
		QItem parentItem = item.getParentItem();
		int index = (parentItem == null) ? indexOf(item) : item.getParentItem().indexOf(item);
		int y = 0;
		int h = getItemHeight(item.getLevel());
		for(int i = 0; i < index; i++) {
			y += h;
			
			QItem temp = (parentItem == null) ? getItem(i) : parentItem.getItem(i);
			if(temp.isExpanded())
				y += getItemChildrenHeight(temp);
		}
		return y;
	}

	/**
	 * 得到绝对坐标y下的item对象
	 * 
	 * @param y
	 * 		绝对坐标y
	 * @return
	 * 		QItem对象,没有返回null
	 */
	private QItem getItemAtY(int y) {
		return getItemAtY(y, null);
	}
	
	/**
	 * 在item的子item中查找y偏移位置的子item
	 * 
	 * @param y
	 * 		y坐标,相对于父item来说
	 * @param item
	 * 		父item,null表示从根节点开始查找
	 * @return
	 * 		QItem对象,如果没有,返回null
	 */
	private QItem getItemAtY(int y, QItem item) {
		if(y < 0)
			return null;
		int level = (item == null) ? 0 : (item.getLevel() + 1);
		int count = (item == null) ? itemCount : item.getItemCount();
		int h = getItemHeight(level);
		int i;
		for(i = 0; i < count && y >= 0; i++) {
			y -= h;
			
			// 如果这个child是展开的,则在其子item中查找
			QItem child = (item == null) ? getItem(i) : item.getItem(i);
			if(child.isExpanded()) {
				QItem ret = getItemAtY(y, child);
				if(ret != null)
					return ret;
				y -= getItemChildrenHeight(child);
			}
		}
		
		// 如果i还是小于count,则定位到了一个item
		if(y < 0)
			return (item == null) ? getItem(i - 1) : item.getItem(i - 1);
		else
			return null;
	}

	/**
	 * 得到一个item的所有子item的总高度
	 * 
	 * @param item
	 * 		父item
	 * @return
	 * 		子item总高度
	 */
	private int getItemChildrenHeight(QItem item) {
		int count = item.getItemCount();
		int ret = 0;
		int h = getItemHeight(item.getLevel() + 1);
		for(int i = 0; i < count; i++) {
			ret += h;			
			if(item.getItem(i).isExpanded())
				ret += getItemChildrenHeight(item.getItem(i));
		}
		return ret;
	}
	
	/**
	 * 返回某点下的ite对象
	 * 
	 * @param p
	 * 		相对于客户区的坐标
	 * @return
	 * 		QItem对象,如果坐标下无item,返回null
	 */
	public QItem getItem(Point p) {
		return getItem(p.x, p.y);
	}
	
	/**
	 * 得到第index个子item
	 * 
	 * @param index
	 * 		子item索引 
	 * @return
	 * 		QItem对象
	 */
	public QItem getItem(int index) {
		checkWidget();
		checkIndex(index);
		return items[index];
	}

	/**
	 * 检查index是否符合范围
	 * 
	 * @param index		
	 * 		子item索引
	 */
	private void checkIndex(int index) {
		if(index < 0 || index >= itemCount)
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}		
	
	/**
	 * 得到level级的item高度
	 * 
	 * @param level
	 * 		level,从0开始
	 * @return
	 * 		象素高度
	 */
	public int getItemHeight(int level) {
		checkWidget();
		switch(itemLayouts[level]) {
			case HORIZONTAL:
				return max(fontHeight, itemImageSizes[level]) + ITEM_BOTTOM_MARGIN + ITEM_TOP_MARGIN;
			case VERTICAL:
				return itemImageSizes[level] + fontHeight + ITEM_BOTTOM_MARGIN + ITEM_TOP_MARGIN + ITEM_IMAGE_TEXT_SPACING;
			default:
				SWT.error(SWT.ERROR_INVALID_RANGE);
				return -1;
		}
	}
	
	/**
	 * 得到某层item的宽度
	 * 
	 * @param level
	 * 		层号
	 * @return
	 * 		item的象素宽度
	 */
	public int getItemWidth(int level) {
		checkWidget();
		return clientAreaWidth - getItemIndent(level);
	}
	
	/**
	 * 检查层号参数是否符合要求
	 * 
	 * @param level
	 * 		层号
	 */
	private void checkLevel(int level) {
		if(level < 0 || level >= MAX_DEEPTH)
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	
	/**
	 * 扩展item数组大小
	 */
	private void expandItemArray() {
		QItem[] newItems = new QItem[items.length << 1];
		System.arraycopy(items, 0, newItems, 0, itemCount);
		items = newItems;
	}
	
	/**
	 * 向item数组中添加一个item到数组中
	 * 
	 * @param item
	 * 		要添加的QItem对象
	 */
	private void internalAddItem(QItem item) {
		if(itemCount >= items.length)
			expandItemArray();
		
		items[itemCount++] = item;
	}
	
	/**
	 * 从item数组中删除一个item,不校验index的合法性
	 * 
	 * @param index
	 * 		item的index
	 */
	private void internalRemoveItem(int index) {
		System.arraycopy(items, index + 1, items, index, itemCount - index - 1);
		items[--itemCount] = null;
	}
	
	/**
	 * 计算字体高度
	 * 
	 * @return
	 * 		字体高度象素
	 */
	private int calculateFontHeight() {
		GC gc = new GC(this);
		Font originalFont = gc.getFont();
		FontData[] fontDatas = originalFont.getFontData();		
		FontMetrics metrics = gc.getFontMetrics();
		
		int ascent = metrics.getAscent() + metrics.getLeading();
		int descent = metrics.getDescent();
		
		getFontData(fontDatas, SWT.BOLD);
		Font boldFont = new Font(getDisplay(), fontDatas);
		gc.setFont(boldFont);
		metrics = gc.getFontMetrics();
		ascent = max(ascent, metrics.getAscent() + metrics.getLeading());
		descent = max(descent, metrics.getDescent());
		boldFont.dispose();
		
		getFontData(fontDatas, SWT.ITALIC);
		Font italicFont = new Font(getDisplay(), fontDatas);
		gc.setFont(italicFont);
		metrics = gc.getFontMetrics();
		ascent = max(ascent, metrics.getAscent() + metrics.getLeading());
		descent = max(descent, metrics.getDescent());
		italicFont.dispose();
		
		getFontData(fontDatas, SWT.BOLD | SWT.ITALIC);
		Font boldItalicFont = new Font(getDisplay(), fontDatas);
		gc.setFont(boldItalicFont);
		metrics = gc.getFontMetrics();
		ascent = max(ascent, metrics.getAscent() + metrics.getLeading());
		descent = max(descent, metrics.getDescent());
		boldItalicFont.dispose();
		
		gc.setFont(originalFont);
		gc.dispose();
		
		return ascent + descent;
	}
	
	/**
	 * 设置font data为某种样式
	 * 
	 * @param fontDatas
	 * 		FontData数组
	 * @param style
	 * 		样式
	 */
	private void getFontData(FontData[] fontDatas, int style) {
		for(FontData fd : fontDatas)
			fd.setStyle(style);
	}
	
	/**
	 * @return Returns the items.
	 */
	public QItem[] getItems() {
		QItem[] ret = new QItem[itemCount];
		System.arraycopy(items, 0, ret, 0, itemCount);
		return ret;
	}

	/**
	 * @return Returns the itemCount.
	 */
	public int getItemCount() {
		return itemCount;
	}

	/**
	 * 添加一个item,这个item可能是根节点,也可能是子节点
	 * 
	 * @param item
	 * 		QItem对象
	 */
	public void addItem(QItem item) {
		internalAddItem(item);
	}
	
	/**
	 * 删除一个item
	 * 
	 * @param index
	 * 		item的索引
	 */
	public void removeItem(int index) {
		checkIndex(index);
		internalRemoveItem(index);
	}
	
	/**
	 * 删除从index开始的后面所有item
	 * 
	 * @param index
	 */
	void removeItemFrom(int index) {
		checkIndex(index);
		for(int i = index; i < itemCount; i++)
			items[index] = null;
		itemCount = index;
	}

	/**
	 * Item的expanded状态改变之后,重画这个item之下的所有item,并且
	 * 要更新滚动条
	 * 
	 * @param item
	 * 		状态发生变化的item
	 */
	void updateExpanded(QItem item) {
		lastChar = 0;
		redraw();
		setScrollBar();
		
		QTreeEvent e = new QTreeEvent(this, item);
		if(item.isExpanded())
			sendQTreeExpandedEvent(e);
		else
			sendQTreeCollapsedEvent(e);
	}
	
	/**
	 * @return
	 * 		所有的item的高度之和,不考虑没有expanded的item
	 */
	private int getTotalHeight() {
		int h = itemCount * getItemHeight(0);
		for(int i = 0; i < itemCount; i++) {
			if(items[i].isExpanded())
				h += getItemChildrenHeight(items[i]);
		}
		return h;
	}
	
	/**
	 * 调整滚动条参数
	 */
	private void setScrollBar() {
		ScrollBar verticalBar = getVerticalBar();

		if (verticalBar != null) {
			int totalHeight = getTotalHeight();
			verticalBar.setVisible(clientAreaHeight < totalHeight || verticalOffset > 0);
			
			if(verticalBar.getVisible()) {				
				verticalBar.setValues(verticalOffset, 
				        verticalBar.getMinimum(),
				        totalHeight + clientAreaHeight - getItemHeight(0), 
				        clientAreaHeight, 
						10,
						clientAreaHeight); 					
			} else {
				verticalBar.setMaximum(clientAreaHeight);
				verticalBar.setThumb(1);
				setVerticalOffset(0, true);
			}
		}
	}
	
	/**
	 * 重画一个item
	 * 
	 * @param item
	 * 		item对象
	 */
	void updateItem(QItem item) {
		if(!item.isLogicalVisible())
			return;
		
		int y = getRelativeYAtItem(item);
		int itemHeight = getItemHeight(item.getLevel());
		if(y > -itemHeight && y < clientAreaHeight)
			redraw(0, y, clientAreaWidth, getItemHeight(item.getLevel()), true);
	}

	/**
	 * @return Returns the enableIconHover.
	 */
	public boolean isEnableIconHover() {
		return enableIconHover;
	}

	/**
	 * @param enableIconHover The enableIconHover to set.
	 */
	public void setEnableIconHover(boolean enableIconHover) {
		this.enableIconHover = enableIconHover;
	}
	
	/**
	 * 开始一个特效
	 * 
	 * @param item
	 * 		使用特效的item对象
	 * @param type
	 * 		特效类型
	 */
	public void startAnimation(QItem item, Animation type) {
		synchronized(animateList) {
			if(animateList.contains(item))
				return;
			
			animateList.add(item);
			item.effect = type.getEffector();
			item.animating = true;
		}
		getDisplay().timerExec(0, animateRunnable);
	}
	
	/**
	 * 停止item的动画
	 * 
	 * @param item
	 * 		要停止特效的item对象
	 */
	public void stopAnimation(QItem item) {
		synchronized(animateList) {
			animateList.remove(item);
			item.effect = null;
			item.animating = false;
		}
		updateItem(item);
	}
	
	/**
	 * 停止所有动画
	 */
	public void stopAllAnimation() {
		synchronized(animateList) {
			animateList.clear();
		}
		redraw();
	}

	/**
	 * @return Returns the itemUnderMouse.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -