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

📄 listbox.py

📁 Urwid is a Python library for making text console applications. It has many features including fluid
💻 PY
📖 第 1 页 / 共 3 页
字号:
				if row_offset >= maxrow:					# must scroll further than 1 line					row_offset = maxrow-1									self.change_focus((maxcol,maxrow),pos,					row_offset, 'above', )				return		# if all else fails, keep the current focus.		self.shift_focus((maxcol,maxrow), focus_row_offset-1)												def _keypress_page_up( self, (maxcol, maxrow) ):				middle, top, bottom = self.calculate_visible(			(maxcol,maxrow), focus=1 )		if middle is None: return 'page up'					row_offset, focus_widget, focus_pos, focus_rows, cursor = middle		trim_top, fill_above = top		# topmost_visible is row_offset rows above top row of 		# focus (+ve) or -row_offset rows below top row of focus (-ve)		topmost_visible = row_offset				# scroll_from_row is (first match)		# 1. topmost visible row if focus is not selectable		# 2. row containing cursor if focus has a cursor		# 3. top row of focus widget if it is visible		# 4. topmost visible row otherwise		if not focus_widget.selectable():			scroll_from_row = topmost_visible		elif cursor is not None:			x,y = cursor			scroll_from_row = -y		elif row_offset >= 0:			scroll_from_row = 0		else:			scroll_from_row = topmost_visible				# snap_rows is maximum extra rows to scroll when		# snapping to new a focus		snap_rows = topmost_visible - scroll_from_row		# move row_offset to the new desired value (1 "page" up)		row_offset = scroll_from_row + maxrow				# not used below:		scroll_from_row = topmost_visible = None						# gather potential target widgets		t = []		# add current focus		t.append((row_offset,focus_widget,focus_pos,focus_rows))		pos = focus_pos		# include widgets from calculate_visible(..)		for widget, pos, rows in fill_above:			row_offset -= rows			t.append( (row_offset, widget, pos, rows) )		# add newly visible ones, including within snap_rows		snap_region_start = len(t)		while row_offset > -snap_rows:			widget, pos = self.body.get_prev(pos)			if widget is None: break			rows = widget.rows((maxcol,))			row_offset -= rows			# determine if one below puts current one into snap rgn			if row_offset > 0:				snap_region_start += 1			t.append( (row_offset, widget, pos, rows) ) 		# if we can't fill the top we need to adjust the row offsets		row_offset, w, p, r = t[-1]		if row_offset > 0:			adjust = - row_offset			t = [(ro+adjust, w, p, r) for (ro,w,p,r) in t]			# if focus_widget (first in t) is off edge, remove it		row_offset, w, p, r = t[0]		if row_offset >= maxrow:			del t[0]			snap_region_start -= 1				# we'll need this soon		self.update_pref_col_from_focus((maxcol,maxrow))					# choose the topmost selectable and (newly) visible widget		# search within snap_rows then visible region		search_order = ( range( snap_region_start, len(t))				+ range( snap_region_start-1, -1, -1 ) )		#assert 0, `t, search_order`		bad_choices = []		cut_off_selectable_chosen = 0		for i in search_order:			row_offset, widget, pos, rows = t[i]			if not widget.selectable(): 				continue			# try selecting this widget			pref_row = max(0, -row_offset)						# if completely within snap region, adjust row_offset			if rows + row_offset <= 0:				self.change_focus( (maxcol,maxrow), pos,					-(rows-1), 'below',					(self.pref_col, rows-1),					snap_rows-((-row_offset)-(rows-1)))			else:				self.change_focus( (maxcol,maxrow), pos,					row_offset, 'below', 					(self.pref_col, pref_row), snap_rows )						# if we're as far up as we can scroll, take this one			if (fill_above and self.body.get_prev(fill_above[-1][1])				== (None,None) ):				pass #return						# find out where that actually puts us			middle, top, bottom = self.calculate_visible(				(maxcol,maxrow), focus=1 )			act_row_offset, _ign1, _ign2, _ign3, _ign4 = middle						# discard chosen widget if it will reduce scroll amount			# because of a fixed cursor (absolute last resort)			if act_row_offset > row_offset+snap_rows:				bad_choices.append(i)				continue			if act_row_offset < row_offset:				bad_choices.append(i)				continue						# also discard if off top edge (second last resort)			if act_row_offset < 0:				bad_choices.append(i)				cut_off_selectable_chosen = 1				continue						return					# anything selectable is better than what follows:		if cut_off_selectable_chosen:			return						if fill_above and focus_widget.selectable():			# if we're at the top and have a selectable, return			if self.body.get_prev(fill_above[-1][1]) == (None,None):				pass #return						# if still none found choose the topmost widget		good_choices = [j for j in search_order if j not in bad_choices]		for i in good_choices + search_order:			row_offset, widget, pos, rows = t[i]			if pos == focus_pos: continue						# if completely within snap region, adjust row_offset			if rows + row_offset <= 0:				snap_rows -= (-row_offset) - (rows-1)				row_offset = -(rows-1)							self.change_focus( (maxcol,maxrow), pos,				row_offset, 'below', None,				snap_rows )			return					# no choices available, just shift current one		self.shift_focus((maxcol, maxrow), min(maxrow-1,row_offset))				# final check for pathological case where we may fall short		middle, top, bottom = self.calculate_visible(			(maxcol,maxrow), focus=1 )		act_row_offset, _ign1, pos, _ign2, _ign3 = middle		if act_row_offset >= row_offset:			# no problem			return					# fell short, try to select anything else above		if not t:			return		_ign1, _ign2, pos, _ign3 = t[-1]		widget, pos = self.body.get_prev(pos)		if widget is None:			# no dice, we're stuck here			return		# bring in only one row if possible		rows = widget.rows((maxcol,), focus=1)		self.change_focus((maxcol,maxrow), pos, -(rows-1),			'below', (self.pref_col, rows-1), 0 )														def _keypress_page_down( self, (maxcol, maxrow) ):				middle, top, bottom = self.calculate_visible(			(maxcol,maxrow), focus=1 )		if middle is None: return 'page down'					row_offset, focus_widget, focus_pos, focus_rows, cursor = middle		trim_bottom, fill_below = bottom		# bottom_edge is maxrow-focus_pos rows below top row of focus		bottom_edge = maxrow - row_offset				# scroll_from_row is (first match)		# 1. bottom edge if focus is not selectable		# 2. row containing cursor + 1 if focus has a cursor		# 3. bottom edge of focus widget if it is visible		# 4. bottom edge otherwise		if not focus_widget.selectable():			scroll_from_row = bottom_edge		elif cursor is not None:			x,y = cursor			scroll_from_row = y + 1		elif bottom_edge >= focus_rows:			scroll_from_row = focus_rows		else:			scroll_from_row = bottom_edge				# snap_rows is maximum extra rows to scroll when		# snapping to new a focus		snap_rows = bottom_edge - scroll_from_row		# move row_offset to the new desired value (1 "page" down)		row_offset = -scroll_from_row				# not used below:		scroll_from_row = bottom_edge = None						# gather potential target widgets		t = []		# add current focus		t.append((row_offset,focus_widget,focus_pos,focus_rows))		pos = focus_pos		row_offset += focus_rows		# include widgets from calculate_visible(..)		for widget, pos, rows in fill_below:			t.append( (row_offset, widget, pos, rows) )			row_offset += rows		# add newly visible ones, including within snap_rows		snap_region_start = len(t)		while row_offset < maxrow+snap_rows:			widget, pos = self.body.get_next(pos)			if widget is None: break			rows = widget.rows((maxcol,))			t.append( (row_offset, widget, pos, rows) ) 			row_offset += rows			# determine if one above puts current one into snap rgn			if row_offset < maxrow:				snap_region_start += 1				# if we can't fill the bottom we need to adjust the row offsets		row_offset, w, p, rows = t[-1]		if row_offset + rows < maxrow:			adjust = maxrow - (row_offset + rows)			t = [(ro+adjust, w, p, r) for (ro,w,p,r) in t]			# if focus_widget (first in t) is off edge, remove it		row_offset, w, p, rows = t[0]		if row_offset+rows <= 0:			del t[0]			snap_region_start -= 1		# we'll need this soon		self.update_pref_col_from_focus((maxcol,maxrow))					# choose the bottommost selectable and (newly) visible widget		# search within snap_rows then visible region		search_order = ( range( snap_region_start, len(t))				+ range( snap_region_start-1, -1, -1 ) )		#assert 0, `t, search_order`		bad_choices = []		cut_off_selectable_chosen = 0		for i in search_order:			row_offset, widget, pos, rows = t[i]			if not widget.selectable(): 				continue			# try selecting this widget			pref_row = min(maxrow-row_offset-1, rows-1)						# if completely within snap region, adjust row_offset			if row_offset >= maxrow:				self.change_focus( (maxcol,maxrow), pos,					maxrow-1, 'above',					(self.pref_col, 0),					snap_rows+maxrow-row_offset-1 )			else:				self.change_focus( (maxcol,maxrow), pos,					row_offset, 'above', 					(self.pref_col, pref_row), snap_rows )						# find out where that actually puts us			middle, top, bottom = self.calculate_visible(				(maxcol,maxrow), focus=1 )			act_row_offset, _ign1, _ign2, _ign3, _ign4 = middle			# discard chosen widget if it will reduce scroll amount			# because of a fixed cursor (absolute last resort)			if act_row_offset < row_offset-snap_rows:				bad_choices.append(i)				continue			if act_row_offset > row_offset:				bad_choices.append(i)				continue						# also discard if off top edge (second last resort)			if act_row_offset+rows > maxrow:				bad_choices.append(i)				cut_off_selectable_chosen = 1				continue						return					# anything selectable is better than what follows:		if cut_off_selectable_chosen:			return		# if still none found choose the bottommost widget		good_choices = [j for j in search_order if j not in bad_choices]		for i in good_choices + search_order:			row_offset, widget, pos, rows = t[i]			if pos == focus_pos: continue						# if completely within snap region, adjust row_offset			if row_offset >= maxrow:				snap_rows -= snap_rows+maxrow-row_offset-1				row_offset = maxrow-1							self.change_focus( (maxcol,maxrow), pos,				row_offset, 'above', None,				snap_rows )			return							# no choices available, just shift current one		self.shift_focus((maxcol, maxrow), max(1-focus_rows,row_offset))				# final check for pathological case where we may fall short		middle, top, bottom = self.calculate_visible(			(maxcol,maxrow), focus=1 )		act_row_offset, _ign1, pos, _ign2, _ign3 = middle		if act_row_offset <= row_offset:			# no problem			return					# fell short, try to select anything else below		if not t:			return		_ign1, _ign2, pos, _ign3 = t[-1]		widget, pos = self.body.get_next(pos)		if widget is None:			# no dice, we're stuck here			return		# bring in only one row if possible		rows = widget.rows((maxcol,), focus=1)		self.change_focus((maxcol,maxrow), pos, maxrow-1,			'above', (self.pref_col, 0), 0 )	def mouse_event(self, (maxcol, maxrow), event, button, col, row, focus):		"""		Pass the event to the contained widgets.		May change focus on button 1 press.		"""		middle, top, bottom = self.calculate_visible((maxcol, maxrow),			focus=True)		if middle is None:			return False				_ignore, focus_widget, focus_pos, focus_rows, cursor = middle		trim_top, fill_above = top		_ignore, fill_below = bottom		fill_above.reverse() # fill_above is in bottom-up order		w_list = ( fill_above + 			[ (focus_widget, focus_pos, focus_rows) ] +			fill_below )		wrow = -trim_top		for w, w_pos, w_rows in w_list:			if wrow + w_rows > row:				break			wrow += w_rows		else:			return False		focus = focus and w == focus_widget		if is_mouse_press(event) and button==1:			if w.selectable():				self.change_focus((maxcol,maxrow), w_pos, wrow)				if not hasattr(w,'mouse_event'):			return False		return w.mouse_event((maxcol,), event, button, col, row-wrow,			focus)	def ends_visible(self, (maxcol, maxrow), focus=False):		"""Return a list that may contain 'top' and/or 'bottom'.				convenience function for checking whether the top and bottom		of the list are visible		"""		l = []		middle,top,bottom = self.calculate_visible( (maxcol,maxrow), 			focus=focus )		if middle is None: # empty listbox			return ['top','bottom']		trim_top, above = top		trim_bottom, below = bottom		if trim_bottom == 0:			row_offset, w, pos, rows, c = middle			row_offset += rows			for w, pos, rows in below:				row_offset += rows			if row_offset < maxrow:				l.append( 'bottom' )			elif self.body.get_next(pos) == (None,None):				l.append( 'bottom' )		if trim_top == 0:			row_offset, w, pos, rows, c = middle			for w, pos, rows in above:				row_offset -= rows			if self.body.get_prev(pos) == (None,None):				l.append( 'top' )		return l	

⌨️ 快捷键说明

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