wraptextcontrol.icl 2.47 KB
Newer Older
Diederik van Arkel's avatar
Diederik van Arkel committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
implementation module wraptextcontrol

import StdEnv, StdIO

//Start = splitwords "zin met vier woorden"

:: WrapText ls ps = WrapText String [ControlAttribute *(ls,ps)]

instance Controls WrapText
where
	getControlType _ = "WrapText"
	controlToHandles (WrapText text atts) ps
		# (w,ps) = accPIO (accScreenPicture detw) ps
		# (h,ps) = deth ps
		# wid = if (isNothing sAtt) w ((fromJust sAtt).w)
		# hgt = if (isNothing sAtt) h ((fromJust sAtt).h)
		# siz = {w = wid, h = hgt}
		= controlToHandles (imp siz) ps
	where
		wtext = splitwords text
		imp	size = CustomControl size look atts
		look sel {newFrame} pic
			# pic			= unfill newFrame pic
			# wid			= newFrame.corner2.x - newFrame.corner1.x
			# (met,pic)		= getPenFontMetrics pic
			# pic			= setPenPos {zero & y = met.fLeading + met.fAscent} pic
			# (wwdth,pic)	= getPenFontStringWidths wtext pic
			# (sp,pic)		= getPenFontStringWidth " " pic
			# wtext			= zip2 wtext wwdth
			# stext			= wrap wtext sp wid
			# pic			= drawWT 0 (fontLineHeight met) stext pic
			= pic
		sAtt	= getSizeAtt atts
		detw pic
			# (fnt,pic)	= openDefaultFont pic
			# (wid,pic)	= getFontStringWidth fnt text pic
			= (wid,pic)
		deth ps
			# (siz,ps)	= controlSize (TextControl "" []) True Nothing Nothing Nothing ps
			# hgt		= siz.h
			= (hgt,ps)

getSizeAtt [] = Nothing
getSizeAtt [ControlViewSize s:_] = Just s
getSizeAtt [_:atts] = getSizeAtt atts

splitwords :: String -> [String]
splitwords string
	= splitwords 0
where
	splitwords i
		| i >= l = []
		# (s,r) = scanword i
//		| s == r = []
		= [string%(i,s):splitwords r]
	l = size string
	scanword x
		| x >= l = (dec l,l)
		| string.[x] == ' '
			= (dec x,scanspace x)
		= scanword (inc x)
	scanspace x
		| x >= l = l
		| string.[x] == ' '
			= scanspace (inc x)
		= x
			
wrap :: .[(String,Int)] Int Int -> [String]
wrap [] _ _ = []
wrap list sp width
	#	list = exp list 0
		(h,t)	= span (\(_,_,w)->w<width) list
		// moet hier wat doen voor het geval eerste string te breed... flextext of zo...
	#!	(h,t) = if (isEmpty h) (splitAt 1 t) (h,t)	// (abort "Word too long in string to be wrapped!") h
	#	h		= map fst3 h
		h		= foldl (\l r -> l +++ " " +++ r) "" h
		t		= map (\(s,w,_)->(s,w)) t
		t		= wrap t sp width
	= [h:t]
where
	exp [] _ = []
	exp [(s,w):t] x = [(s,w,x+w): exp t (x+w+sp)]



drawWT _ _ [] picture = picture
drawWT x dy [line:text] picture
	#	picture			= draw line picture
		(pos,picture)	= getPenPos picture
		dx				= x - (pos.x)
		picture			= movePenPos {vx = dx, vy = dy} picture
	= drawWT x dy text picture