Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/console.py')
-rw-r--r--release/scripts/console.py861
1 files changed, 0 insertions, 861 deletions
diff --git a/release/scripts/console.py b/release/scripts/console.py
deleted file mode 100644
index c6ae22a86f5..00000000000
--- a/release/scripts/console.py
+++ /dev/null
@@ -1,861 +0,0 @@
-#!BPY
-
-"""
-Name: 'Interactive Python Console'
-Blender: 245
-Group: 'System'
-Tooltip: 'Interactive Python Console'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__bpydoc__ = """\
-This is an interactive console, similar to Python's own command line interpreter. Since it is embedded in Blender, it has access to all Blender Python modules.
-
-Those completely new to Python are recommended to check the link button above
-that points to its official homepage, with news, downloads and documentation.
-
-Usage:<br>
- Type your code and hit "Enter" to get it executed.<br>
- - Right mouse click: Console Menu (Save output, etc);<br>
- - Mousewheel: Scroll text
- - Arrow keys: command history and cursor;<br>
- - Shift + Backspace: Backspace whole word;<br>
- - Shift + Arrow keys: jump words;<br>
- - Ctrl + (+/- or mousewheel): Zoom text size;<br>
- - Ctrl + Enter: auto compleate based on variable names and modules loaded -- multiple choices popup a menu;<br>
- - Shift + Enter: multiline functions -- delays executing code until only Enter is pressed.
-"""
-
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-
-import Blender
-import bpy
-from Blender import *
-import sys as python_sys
-import StringIO
-
-# Constants
-__DELIMETERS__ = '. ,=+-*/%<>&~][{}():\t'
-__VARIABLE_DELIMETERS__ = ' ,=+-*/%<>&~{}():\t'
-
-__LINE_HISTORY__ = 500
-
-global __FONT_SIZE__
-
-__FONT_SIZES__ = ( ('tiny', 10), ('small', 12), ('normalfix', 14), ('large', 16) )
-__FONT_SIZE__ = 2 # index for the list above, normal default.
-
-global __CONSOLE_LINE_OFFSET__
-__CONSOLE_LINE_OFFSET__ = 0
-
-cmdBuffer = [] # dosnt need to be global
-
-'''
-# Generic Blender functions
-def getActScriptWinRect():
- area = Window.GetAreaSize()
- area = (area[0]-1, area[1]-1)
- for scrInfo in Window.GetScreenInfo(Window.Types['SCRIPT'], 'win', ''):
- if scrInfo['vertices'][2]-scrInfo['vertices'][0] == area[0]:
- if scrInfo['vertices'][3]-scrInfo['vertices'][1] == area[1]:
- return scrInfo['vertices']
- return None
-'''
-
-
-# menuText, # per group
-def PupMenuLess(menu, groupSize=35):
- more = [' more...']
- less = [' less...']
-
- menuList= menu.split('|')
-
- # No Less Needed, just call.
- if len(menuList) < groupSize:
- return Draw.PupMenu(menu)
-
- title = menuList[0].split('%t')[0]
-
- # Split the list into groups
- menuGroups = [[]]
- for li in menuList[1:]:
- if len(menuGroups[-1]) < groupSize:
- menuGroups[-1].append(li)
- else:
- menuGroups.append([li])
-
- # Stores teh current menu group we are looking at
- groupIdx = 0
- while 1:
- # Give us a title with the menu number
- numTitle = [ ' '.join([title, str(groupIdx + 1), 'of', str(len(menuGroups)), '%t'])]
- if groupIdx == 0:
- menuString = '|'.join(numTitle + menuGroups[groupIdx] + more)
- elif groupIdx == len(menuGroups)-1:
- menuString = '|'.join(numTitle + less + menuGroups[groupIdx])
- else: # In the middle somewhere so Show a more and less
- menuString = '|'.join(numTitle + less + menuGroups[groupIdx] + more)
- result = Draw.PupMenu(menuString)
- # User Exit
- if result == -1:
- return -1
-
- if groupIdx == 0: # First menu
- if result-1 < groupSize:
- return result
- else: # must be more
- groupIdx +=1
- elif groupIdx == len(menuGroups): # Last Menu
- if result == 1: # Must be less
- groupIdx -= 1
- else: # Must be a choice
- return result + (groupIdx*groupSize)
-
- else:
- if result == 1: # Must be less
- groupIdx -= 1
- elif result-2 == groupSize:
- groupIdx +=1
- else:
- return result - 1 + (groupIdx*groupSize)
-
-
-
-# Use newstyle classes, Im not bothering with inheretence
-# but slots are faster.
-class cmdLine(object):
- __slots__ = [\
- 'cmd', # is the command string, or any other message
- 'type',# type: 0:user input 1:program feedback 2:error message. 3:option feedback
- 'exe' # 0- not yet executed 1:executed
- ]
- def __init__(self, cmd, type, exe):
- self.cmd = cmd
- self.type = type
- self.exe = exe
-
-# Include external file with internal namespace
-def include(filename):
- file = open(filename, 'r')
- filedata = file.read()
- file.close()
- return compile(filedata, filename, 'exec')
-
-# Writes command line data to a blender text file.
-def writeCmdData(type):
- newText = Text.New('command_output.py', 1)
- if type == 3: newText.write('\n'.join( [ myCmd.cmd for myCmd in cmdBuffer ] ))
- else: newText.write('\n'.join( [ myCmd.cmd for myCmd in cmdBuffer if myCmd.type is type] ))
- Draw.PupMenu('%s written' % newText.name)
-
-def insertCmdData():
- texts = list(bpy.data.texts)
- textNames = [tex.name for tex in texts]
- if textNames:
- choice = Draw.PupMenu('|'.join(textNames))
- if choice != -1:
- text = texts[choice-1]
-
- # Add the text!
- for l in text.asLines():
- cmdBuffer.append(cmdLine('%s ' % l, 0, 0))
- Draw.Redraw()
-
-
-COLLECTED_VAR_NAMES = {} # a list of keys, each key has a list of absolute paths
-
-# Pain and simple recursice dir(), accepts a string
-unused_types = str, dict, list, float, int, str, type, tuple, type(dir), type(None)
-def rdir(dirString, depth=0):
- #print ' ' * depth, dirString
- # MAX DEPTH SET HERE
- if depth > 5:
- # print 'maxdepoth reached.'
- return
-
- global COLLECTED_VAR_NAMES
- dirStringSplit = dirString.split('.')
-
- exec('value=' + dirString)
-
- if type(value) in unused_types:
- # print 'bad type'
- return
- dirList = dir(value)
-
- for dirItem in dirList:
- if dirItem.startswith('_'):
- continue
-
- dirData = None
- try:
- # Rare cases this can mess up, material.shader was a problem.
- exec('dirData = %s.%s' % (dirString, dirItem))
- #print dirData
- except:
- # Dont bother with this data.
- continue
- #print 'HEY', dirData, dirItem
- #if type(dirItem) != str:
- # print dirItem, type(dirItem)
-
- if dirItem not in COLLECTED_VAR_NAMES: # .keys()
- COLLECTED_VAR_NAMES[dirItem] = []
-
- # Add the string
- # splitD = dirString.split('"')[-2]
-
- # Example of dirString
- # __CONSOLE_VAR_DICT__["Main"].scenes.active.render
-
- # Works but can be faster
- # splitD = dirString.replace('__CONSOLE_VAR_DICT__["', '').replace('"]', '')
-
- splitD = dirString[22:].replace('"]', '')
-
- if splitD not in COLLECTED_VAR_NAMES[dirItem]:
- # print dirItem, dirString, splitD,
- COLLECTED_VAR_NAMES[dirItem].append(splitD)
-
-
- # Stops recursice stuff, overlooping
- #print type(dirItem)
- #if type(dirData) == types.ClassType or \
- # type(dirData) == types.ModuleType:
- type_dirData = type(dirData)
- if type_dirData not in unused_types:
- # print type(dirData), dirItem
- # Dont loop up dirs for strings ints etc.
- if dirItem not in dirStringSplit:
- rdir( '%s.%s' % (dirString, dirItem), depth+1)
- '''
- elif depth == 0: # Add local variables
- # print type(dirData), dirItem
- # Dont loop up dirs for strings ints etc.
- if dirItem not in dirStringSplit:
- rdir( '%s.%s' % (dirString, dirItem), depth+1)
- '''
-
-def recursive_dir():
- global COLLECTED_VAR_NAMES
-
- for name in __CONSOLE_VAR_DICT__: # .keys()
- if not name.startswith('_'): # Dont pick names like __name__
- rdir('__CONSOLE_VAR_DICT__["%s"]' % name)
- #print COLLECTED_VAR_NAMES
- COLLECTED_VAR_NAMES[name] = ['']
- return COLLECTED_VAR_NAMES
-
-# Runs the code line(s) the user has entered and handle errors
-# As well as feeding back the output into the blender window.
-def runUserCode(__USER_CODE_STRING__):
- global __CONSOLE_VAR_DICT__ # We manipulate the variables here. loading and saving from localspace to this global var.
-
- # Open A File like object to write all output to, that would useually be printed.
- python_sys.stdout.flush() # Get rid of whatever came before
- __FILE_LIKE_STRING__ = StringIO.StringIO() # make a new file like string, this saves up from making a file.
- __STD_OUTPUT__ = python_sys.stdout # we need to store the normal output.
- python_sys.stdout=__FILE_LIKE_STRING__ # Now anything printed will be written to the file like string.
-
- # Try and run the user entered line(s)
- try:
- # Load all variabls from global dict to local space.
- __TMP_VAR_NAME__ = __TMP_VAR__ = '' # so as not to raise an error when del'ing
-
- for __TMP_VAR_NAME__, __TMP_VAR__ in __CONSOLE_VAR_DICT__.items():
- exec('%s%s' % (__TMP_VAR_NAME__,'=__TMP_VAR__'))
- del __TMP_VAR_NAME__
- del __TMP_VAR__
-
- # Now all the vars are loaded, execute the code. # Newline thanks to phillip,
- exec(compile(__USER_CODE_STRING__, 'blender_cmd.py', 'single')) #exec(compile(__USER_CODE_STRING__, 'blender_cmd.py', 'exec'))
-
- # Flush global dict, allow the user to remove items.
- __CONSOLE_VAR_DICT__ = {}
-
- __TMP_VAR_NAME__ = '' # so as not to raise an error when del'ing
- # Write local veriables to global __CONSOLE_VAR_DICT__
- for __TMP_VAR_NAME__ in dir():
- if __TMP_VAR_NAME__ != '__FILE_LIKE_STRING__' and\
- __TMP_VAR_NAME__ != '__STD_OUTPUT__' and\
- __TMP_VAR_NAME__ != '__TMP_VAR_NAME__' and\
- __TMP_VAR_NAME__ != '__USER_CODE_STRING__':
-
- # Execute the local > global coversion.
- exec('%s%s' % ('__CONSOLE_VAR_DICT__[__TMP_VAR_NAME__]=', __TMP_VAR_NAME__))
- del __TMP_VAR_NAME__
-
- except: # Prints the REAL exception.
- error = '%s: %s' % (python_sys.exc_type, python_sys.exc_value)
- for errorLine in error.split('\n'):
- cmdBuffer.append(cmdLine(errorLine, 2, None)) # new line to type into
-
- python_sys.stdout = __STD_OUTPUT__ # Go back to output to the normal blender console
-
- # Copy all new output to cmdBuffer
-
- __FILE_LIKE_STRING__.seek(0) # the readline function requires that we go back to the start of the file.
-
- for line in __FILE_LIKE_STRING__.readlines():
- cmdBuffer.append(cmdLine(line, 1, None))
-
- cmdBuffer.append(cmdLine(' ', 0, 0)) # new line to type into
- python_sys.stdout=__STD_OUTPUT__
- __FILE_LIKE_STRING__.close()
-
-
-
-
-
-#------------------------------------------------------------------------------#
-# event handling code #
-#------------------------------------------------------------------------------#
-def handle_event(evt, val):
-
- # Insert Char into the cammand line
- def insCh(ch): # Instert a char
- global cursor
- # Later account for a cursor variable
- cmdBuffer[-1].cmd = ('%s%s%s' % ( cmdBuffer[-1].cmd[:cursor], ch, cmdBuffer[-1].cmd[cursor:]))
-
- #------------------------------------------------------------------------------#
- # Define Complex Key Actions #
- #------------------------------------------------------------------------------#
- def actionEnterKey():
- global histIndex, cursor
-
- def getIndent(string):
- # Gather white space to add in the previous line
- # Ignore the last char since its padding.
- whiteSpace = ''
- #for i in range(len(cmdBuffer[-1].cmd)):
- for i in xrange(len(string)-1):
- if cmdBuffer[-1].cmd[i] == ' ' or cmdBuffer[-1].cmd[i] == '\t':
- whiteSpace += string[i]
- else:
- break
- return whiteSpace
-
- # Autocomplete
- if Window.GetKeyQualifiers() & Window.Qual.CTRL:
- actionAutoCompleate()
- return
-
- # Are we in the middle of a multiline part or not?
- # try be smart about it
- if cmdBuffer[-1].cmd.split('#')[0].rstrip().endswith(':'):
- # : indicates an indent is needed
- cmdBuffer.append(cmdLine('\t%s ' % getIndent(cmdBuffer[-1].cmd), 0, 0))
- print ': indicates an indent is needed'
-
- elif cmdBuffer[-1].cmd[0] in [' ', '\t'] and len(cmdBuffer[-1].cmd) > 1 and cmdBuffer[-1].cmd.split():
- # white space at the start means he havnt finished the multiline.
- cmdBuffer.append(cmdLine('%s ' % getIndent(cmdBuffer[-1].cmd), 0, 0))
- print 'white space at the start means he havnt finished the multiline.'
-
- elif Window.GetKeyQualifiers() & Window.Qual.SHIFT:
- # Crtl forces multiline
- cmdBuffer.append(cmdLine('%s ' % getIndent(cmdBuffer[-1].cmd), 0, 0))
- print 'Crtl forces multiline'
-
- else: # Execute multiline code block
-
- # Multiline code will still run with 1 line,
- multiLineCode = ['if 1:'] # End of the multiline first.
-
- # Seek the start of the file multiline
- i = 1
- while cmdBuffer[-i].exe == 0:
- i+=1
-
- while i > 1:
- i-=1
-
- if cmdBuffer[-i].cmd == ' ':# Tag as an output type so its not used in the key history
- cmdBuffer[-i].type = 1
- else: # Tab added at the start for added if 1: statement
- multiLineCode.append('\t%s' % cmdBuffer[-i].cmd )
-
- # Mark as executed
- cmdBuffer[-i].exe = 1
-
- multiLineCode.append('\tpass') # reverse will make this the start.
-
- # Dubug, print the code that is executed.
- #for m in multiLineCode: print m
-
- runUserCode('\n'.join(multiLineCode))
-
- # Clear the output based on __LINE_HISTORY__
- if len(cmdBuffer) > __LINE_HISTORY__:
- cmdBuffer[:__LINE_HISTORY__] = []
-
- histIndex = cursor = -1 # Reset cursor and history
-
- def actionUpKey():
- global histIndex
- if abs(histIndex)+1 >= len(cmdBuffer):
- histIndex = -1
-
- # When wrapping allow 1 plank lines
- if cmdBuffer[-1].cmd != ' ':
- cmdBuffer[-1].cmd = ' '
- return
-
- histIndex_orig = histIndex
- histIndex -= 1
-
- while (cmdBuffer[histIndex].type != 0 and abs(histIndex) < len(cmdBuffer)) or \
- ( cmdBuffer[histIndex].cmd == cmdBuffer[histIndex_orig].cmd):
- histIndex -= 1
-
- if cmdBuffer[histIndex].type == 0: # we found one
- cmdBuffer[-1].cmd = cmdBuffer[histIndex].cmd
-
- def actionDownKey():
- global histIndex
- if histIndex >= -2:
- histIndex = -len(cmdBuffer)
-
- # When wrapping allow 1 plank lines
- if cmdBuffer[-1].cmd != ' ':
- cmdBuffer[-1].cmd = ' '
- return
-
- histIndex_orig = histIndex
- histIndex += 1
- while (cmdBuffer[histIndex].type != 0 and histIndex != -2) or \
- ( cmdBuffer[histIndex].cmd == cmdBuffer[histIndex_orig].cmd):
-
- histIndex += 1
-
- if cmdBuffer[histIndex].type == 0: # we found one
- cmdBuffer[-1].cmd = cmdBuffer[histIndex].cmd
-
- def actionRightMouse():
- global __FONT_SIZE__
- choice = Draw.PupMenu('Console Menu%t|Write Input Data (white)|Write Output Data (blue)|Write Error Data (red)|Write All Text|%l|Insert Blender text|%l|Font Size|%l|Clear Output|Quit')
-
- if choice == 1:
- writeCmdData(0) # type 0 user
- elif choice == 2:
- writeCmdData(1) # type 1 user output
- elif choice == 3:
- writeCmdData(2) # type 2 errors
- elif choice == 4:
- writeCmdData(3) # All
- elif choice == 6:
- insertCmdData() # Insert text from Blender and run it.
- elif choice == 8:
- # Fontsize.
- font_choice = Draw.PupMenu('Font Size%t|Large|Normal|Small|Tiny')
- if font_choice != -1:
- if font_choice == 1:
- __FONT_SIZE__ = 3
- elif font_choice == 2:
- __FONT_SIZE__ = 2
- elif font_choice == 3:
- __FONT_SIZE__ = 1
- elif font_choice == 4:
- __FONT_SIZE__ = 0
- Draw.Redraw()
- elif choice == 10: # Clear all output
- cmdBuffer[:] = [cmd for cmd in cmdBuffer if cmd.type == 0] # keep user input
- Draw.Redraw()
- elif choice == 11: # Exit
- Draw.Exit()
-
-
- # Auto compleating, quite complex- use recutsice dir for the moment.
- def actionAutoCompleate(): # Ctrl + Tab
- if not cmdBuffer[-1].cmd[:cursor].split():
- return
-
-
- RECURSIVE_DIR = recursive_dir()
-
- # get last name of user input
- editVar = cmdBuffer[-1].cmd[:cursor]
- # Split off spaces operators etc from the staryt of the command so we can use the startswith function.
- for splitChar in __VARIABLE_DELIMETERS__:
- editVar = editVar[:-1].split(splitChar)[-1] + editVar[-1]
-
-
- # Now we should have the var by its self
- if editVar:
- possibilities = []
-
- for __TMP_VAR_NAME__ in RECURSIVE_DIR: #.keys():
- #print '\t', __TMP_VAR_NAME__
- if __TMP_VAR_NAME__ == editVar:
- # print 'ADITVAR IS A VAR'
- pass
- '''
- elif __TMP_VAR_NAME__.startswith( editVar ):
- print __TMP_VAR_NAME__, 'aaa'
- possibilities.append( __TMP_VAR_NAME__ )
- '''
- possibilities.append( __TMP_VAR_NAME__ )
-
- if len(possibilities) == 1:
- cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], possibilities[0], cmdBuffer[-1].cmd[cursor:]))
-
- elif possibilities: # If its not just []
- # -1 with insert is the second last.
-
- # Text choice
- #cmdBuffer.insert(-1, cmdLine('options: %s' % ' '.join(possibilities), 3, None))
-
- menuList = [] # A lits of tuples- ABSOLUTE, RELATIVE
-
- for __TMP_VAR_NAME__ in possibilities:
- for usage in RECURSIVE_DIR[__TMP_VAR_NAME__]:
- # Account for non absolute (variables for eg.)
- if usage: # not ''
- absName = '%s.%s' % (usage, __TMP_VAR_NAME__)
-
- if __TMP_VAR_NAME__.startswith(editVar):
- menuList.append( # Used for names and can be entered when pressing shift.
- (absName, # Absolute name
- __TMP_VAR_NAME__) # Relative name, non shift
- )
-
- #else:
- # if absName.find(editVar) != -1:
- # menuList.append((__TMP_VAR_NAME__, __TMP_VAR_NAME__)) # Used for names and can be entered when pressing shift.
-
- # No items to display? no menu
- if not menuList:
- return
-
- menuList.sort()
-
- choice = PupMenuLess( # Menu for the user to choose the autocompleate
- 'Choices (Shift for local name, Ctrl for Docs)%t|' + # Title Text
- '|'.join(['%s, %s' % m for m in menuList])) # Use Absolute names m[0]
-
- if choice != -1:
- if Window.GetKeyQualifiers() & Window.Qual.CTRL: # Help
- cmdBuffer[-1].cmd = ('help(%s%s) ' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][0]))
- elif Window.GetKeyQualifiers() & Window.Qual.SHIFT: # Put in the long name
- cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][1], cmdBuffer[-1].cmd[cursor:]))
- else: # Only paste in the Short name
- cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][0], cmdBuffer[-1].cmd[cursor:]))
-
-
- else:
- # print 'NO EDITVAR'
- return
-
- # ------------------end------------------ #
-
- # Quit from menu only
- #if (evt == Draw.ESCKEY and not val):
- # Draw.Exit()
- if evt == Draw.MOUSEX or evt == Draw.MOUSEY: # AVOID TOO MANY REDRAWS.
- return
-
-
- global cursor
- global histIndex
- global __FONT_SIZE__
- global __CONSOLE_LINE_OFFSET__
-
- ascii = Blender.event
-
- resetScroll = True
-
- #------------------------------------------------------------------------------#
- # key codes and key handling #
- #------------------------------------------------------------------------------#
-
- # UP DOWN ARROW KEYS, TO TRAVERSE HISTORY
- if (evt == Draw.UPARROWKEY and val): actionUpKey()
- elif (evt == Draw.DOWNARROWKEY and val): actionDownKey()
-
- elif (evt == Draw.RIGHTARROWKEY and val):
- if Window.GetKeyQualifiers() & Window.Qual.SHIFT:
- wordJump = False
- newCursor = cursor+1
- while newCursor<0:
-
- if cmdBuffer[-1].cmd[newCursor] not in __DELIMETERS__:
- newCursor+=1
- else:
- wordJump = True
- break
- if wordJump: # Did we find a new cursor pos?
- cursor = newCursor
- else:
- cursor = -1 # end of line
- else:
- cursor +=1
- if cursor > -1:
- cursor = -1
-
- elif (evt == Draw.LEFTARROWKEY and val):
- if Window.GetKeyQualifiers() & Window.Qual.SHIFT:
- wordJump = False
- newCursor = cursor-1
- while abs(newCursor) < len(cmdBuffer[-1].cmd):
-
- if cmdBuffer[-1].cmd[newCursor] not in __DELIMETERS__ or\
- newCursor == cursor:
- newCursor-=1
- else:
- wordJump = True
- break
- if wordJump: # Did we find a new cursor pos?
- cursor = newCursor
- else:
- cursor = -len(cmdBuffer[-1].cmd) # Start of line
-
- else:
- if len(cmdBuffer[-1].cmd) > abs(cursor):
- cursor -=1
-
- elif (evt == Draw.HOMEKEY and val):
- cursor = -len(cmdBuffer[-1].cmd)
-
- elif (evt == Draw.ENDKEY and val):
- cursor = -1
-
- elif (evt == Draw.TABKEY and val):
- insCh('\t')
-
- elif (evt == Draw.BACKSPACEKEY and val):
- if Window.GetKeyQualifiers() & Window.Qual.SHIFT:
- i = -1
- for d in __DELIMETERS__:
- i = max(i, cmdBuffer[-1].cmd[:cursor-1].rfind(d))
- if i == -1:
- i=0
- cmdBuffer[-1].cmd = ('%s%s' % (cmdBuffer[-1].cmd[:i] , cmdBuffer[-1].cmd[cursor:]))
-
- else:
- # Normal backspace.
- cmdBuffer[-1].cmd = ('%s%s' % (cmdBuffer[-1].cmd[:cursor-1] , cmdBuffer[-1].cmd[cursor:]))
-
- elif (evt == Draw.DELKEY and val) and cursor < -1:
- cmdBuffer[-1].cmd = cmdBuffer[-1].cmd[:cursor] + cmdBuffer[-1].cmd[cursor+1:]
- cursor +=1
-
- elif ((evt == Draw.RETKEY or evt == Draw.PADENTER) and val):
- actionEnterKey()
-
- elif (evt == Draw.RIGHTMOUSE and not val): actionRightMouse(); return
-
- elif (evt == Draw.PADPLUSKEY or evt == Draw.EQUALKEY or evt == Draw.WHEELUPMOUSE) and val and Window.GetKeyQualifiers() & Window.Qual.CTRL:
- __FONT_SIZE__ += 1
- __FONT_SIZE__ = min(len(__FONT_SIZES__)-1, __FONT_SIZE__)
- elif (evt == Draw.PADMINUS or evt == Draw.MINUSKEY or evt == Draw.WHEELDOWNMOUSE) and val and Window.GetKeyQualifiers() & Window.Qual.CTRL:
- __FONT_SIZE__ -=1
- __FONT_SIZE__ = max(0, __FONT_SIZE__)
-
-
- elif evt == Draw.WHEELUPMOUSE and val:
- __CONSOLE_LINE_OFFSET__ += 1
- __CONSOLE_LINE_OFFSET__ = min(len(cmdBuffer)-2, __CONSOLE_LINE_OFFSET__)
- resetScroll = False
-
- elif evt == Draw.WHEELDOWNMOUSE and val:
- __CONSOLE_LINE_OFFSET__ -= 1
- __CONSOLE_LINE_OFFSET__ = max(0, __CONSOLE_LINE_OFFSET__)
- resetScroll = False
-
-
- elif ascii:
- insCh(chr(ascii))
- else:
- return # dont redraw.
-
- # If the user types in anything then scroll to bottom.
- if resetScroll:
- __CONSOLE_LINE_OFFSET__ = 0
- Draw.Redraw()
-
-
-def draw_gui():
- # Get the bounds from ObleGL directly
- __CONSOLE_RECT__ = BGL.Buffer(BGL.GL_FLOAT, 4)
- BGL.glGetFloatv(BGL.GL_SCISSOR_BOX, __CONSOLE_RECT__)
- __CONSOLE_RECT__= __CONSOLE_RECT__.list
-
- # Clear the screen
- BGL.glClearColor(0.0, 0.0, 0.0, 1.0)
- BGL.glClear(BGL.GL_COLOR_BUFFER_BIT) # use it to clear the color buffer
-
-
- # Fixed margin. use a margin since 0 margin can be hard to seewhen close to a crt's edge.
- margin = 4
-
- # Convenience
- FNT_NAME, FNT_HEIGHT = __FONT_SIZES__[__FONT_SIZE__]
-
- # Draw cursor location colour
- if __CONSOLE_LINE_OFFSET__ == 0:
- cmd2curWidth = Draw.GetStringWidth(cmdBuffer[-1].cmd[:cursor], FNT_NAME)
- BGL.glColor3f(0.8, 0.2, 0.2)
- if cmd2curWidth == 0:
- BGL.glRecti(margin,2,margin+2, FNT_HEIGHT+2)
- else:
- BGL.glRecti(margin + cmd2curWidth-2,2, margin+cmd2curWidth, FNT_HEIGHT+2)
-
- BGL.glColor3f(1,1,1)
- # Draw the set of cammands to the buffer
- consoleLineIdx = __CONSOLE_LINE_OFFSET__ + 1
- wrapLineIndex = 0
- while consoleLineIdx < len(cmdBuffer) and __CONSOLE_RECT__[3] > (consoleLineIdx - __CONSOLE_LINE_OFFSET__) * FNT_HEIGHT:
- if cmdBuffer[-consoleLineIdx].type == 0:
- BGL.glColor3f(1, 1, 1)
- elif cmdBuffer[-consoleLineIdx].type == 1:
- BGL.glColor3f(.3, .3, 1)
- elif cmdBuffer[-consoleLineIdx].type == 2:
- BGL.glColor3f(1.0, 0, 0)
- elif cmdBuffer[-consoleLineIdx].type == 3:
- BGL.glColor3f(0, 0.8, 0)
- else:
- BGL.glColor3f(1, 1, 0)
-
- if consoleLineIdx == 1: # user input
- BGL.glRasterPos2i(margin, (FNT_HEIGHT * (consoleLineIdx-__CONSOLE_LINE_OFFSET__)) - 8)
- Draw.Text(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME)
- else: # WRAP
- lwid = Draw.GetStringWidth(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME)
- if margin + lwid > __CONSOLE_RECT__[2]:
- wrapLineList = []
- wtext = cmdBuffer[-consoleLineIdx].cmd
- wlimit = len(wtext)
- chunksz = int(( __CONSOLE_RECT__[2] - margin ) / (lwid / len(wtext)))
- lstart = 0
- fsize = FNT_NAME
- while lstart < wlimit:
- lend = min(lstart+chunksz,wlimit)
- ttext = wtext[lstart:lend]
- while lend < wlimit and Draw.GetStringWidth(ttext, fsize) + margin < __CONSOLE_RECT__[2]:
- lend += 1
- ttext = wtext[lstart:lend]
- while lend > lstart+1 and Draw.GetStringWidth(ttext, fsize) + margin > __CONSOLE_RECT__[2]:
- lend -= 1
- ttext = wtext[lstart:lend]
- wrapLineList.append(ttext)
- lstart = lend
- # Now we have a list of lines, draw them (OpenGLs reverse ordering requires this odd change)
- wrapLineList.reverse()
- for wline in wrapLineList:
- BGL.glRasterPos2i(margin, (FNT_HEIGHT*((consoleLineIdx-__CONSOLE_LINE_OFFSET__) + wrapLineIndex)) - 8)
- Draw.Text(wline, FNT_NAME)
- wrapLineIndex += 1
- wrapLineIndex-=1 # otherwise we get a silly extra line.
-
- else: # no wrapping.
-
- BGL.glRasterPos2i(margin, (FNT_HEIGHT * ((consoleLineIdx-__CONSOLE_LINE_OFFSET__)+wrapLineIndex)) - 8)
- Draw.Text(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME)
- consoleLineIdx += 1
-
-# This recieves the event index, call a function from here depending on the event.
-def handle_button_event(evt):
- pass
-
-
-# Run the console
-__CONSOLE_VAR_DICT__ = {} # Initialize var dict
-
-
-# Print Startup lines, add __bpydoc__ to the console startup.
-for l in __bpydoc__.split('<br>'):
- cmdBuffer.append( cmdLine(l, 1, None) )
-
-
-histIndex = cursor = -1 # How far back from the first letter are we? - in current CMD line, history if for moving up and down lines.
-
-# Autoexec, startup code.
-scriptDir = Get('scriptsdir')
-console_autoexec = None
-if scriptDir:
- if not scriptDir.endswith(Blender.sys.sep):
- scriptDir += Blender.sys.sep
-
- console_autoexec = '%s%s' % (scriptDir, 'console_autoexec.py')
-
- if not sys.exists(console_autoexec):
- # touch the file
- try:
- open(console_autoexec, 'w').close()
- cmdBuffer.append(cmdLine('...console_autoexec.py not found, making new in scripts dir', 1, None))
- except:
- cmdBuffer.append(cmdLine('...console_autoexec.py could not write, this is ok', 1, None))
- scriptDir = None # make sure we only use this for console_autoexec.py
-
- if not sys.exists(console_autoexec):
- console_autoexec = None
-
- else:
- cmdBuffer.append(cmdLine('...Using existing console_autoexec.py in scripts dir', 1, None))
-
-
-
-#-Autoexec---------------------------------------------------------------------#
-# Just use the function to jump into local naming mode.
-# This is so we can loop through all of the autoexec functions / vars and add them to the __CONSOLE_VAR_DICT__
-def include_console(includeFile):
- global __CONSOLE_VAR_DICT__ # write autoexec vars to this.
-
- # Execute an external py file as if local
- exec(include(includeFile))
-
-def standard_imports():
- # Write local to global __CONSOLE_VAR_DICT__ for reuse,
-
- exec('%s%s' % ('__CONSOLE_VAR_DICT__["bpy"]=', 'bpy'))
- exec('%s%s' % ('__CONSOLE_VAR_DICT__["Blender"]=', 'Blender'))
-
- for ls in (dir(), dir(Blender)):
- for __TMP_VAR_NAME__ in ls:
- # Execute the local > global coversion.
- exec('%s%s' % ('__CONSOLE_VAR_DICT__[__TMP_VAR_NAME__]=', __TMP_VAR_NAME__))
-
- # Add dummy imports to input so output scripts to a text file work as expected
- cmdBuffer.append(cmdLine('import bpy', 0, 1))
- cmdBuffer.append(cmdLine('import Blender', 0, 1)) # pretend we have been executed, as we kindof have.
- cmdBuffer.append(cmdLine('from Blender import *', 0, 1))
-
-if scriptDir and console_autoexec:
- include_console(console_autoexec) # pass the blender module
-
-standard_imports() # import Blender and bpy
-
-#-end autoexec-----------------------------------------------------------------#
-
-
-# Append new line to write to
-cmdBuffer.append(cmdLine(' ', 0, 0))
-
-#------------------------------------------------------------------------------#
-# register the event handling code, GUI #
-#------------------------------------------------------------------------------#
-def main():
- Draw.Register(draw_gui, handle_event, handle_button_event)
-
-if __name__ == '__main__':
- main()