WorldViz User Forum  

Go Back   WorldViz User Forum > Vizard

Reply
 
Thread Tools Rating: Thread Rating: 2 votes, 5.00 average. Display Modes
  #1  
Old 09-14-2006, 10:51 AM
betancourtb82 betancourtb82 is offline
Member
 
Join Date: Jan 2006
Posts: 103
On Screen Keyboard

I was wondering if there was any examples of how to implement an "on-screen keyboard". The experiment deals with a subject trying to unscramble words. The idea is to put a keyboard on the screen and have them click the letters in order to spell out the word. I was thinking of implementing 26 buttons, individually, but I wasn't sure if that was the best way to go about making this keyboard. Any other methods?

Thanks
Reply With Quote
  #2  
Old 09-15-2006, 09:14 AM
farshizzo farshizzo is offline
WorldViz Team Member
 
Join Date: Mar 2003
Posts: 2,849
There aren't any examples, but it shouldn't be too difficult. I would use button labels to create the keyboard.
Code:
A = viz.add(viz.BUTTON_LABEL,'A')
.
.
Z = viz.add(viz.BUTTON_LABEL,'Z')
Reply With Quote
  #3  
Old 09-15-2006, 09:17 AM
Gladsomebeast Gladsomebeast is offline
Member
 
Join Date: Mar 2005
Location: Isla Vizta, CA
Posts: 397
How about allowing the user to re-arrange the letters with drag and drop?
__________________
Paul Elliott
WorldViz LLC
Reply With Quote
  #4  
Old 09-15-2006, 02:17 PM
betancourtb82 betancourtb82 is offline
Member
 
Join Date: Jan 2006
Posts: 103
That would also be very useful. Is there a function that would allow me to do this? Any prior example or helpful hints?

Thanks for the great idea!
Reply With Quote
  #5  
Old 09-15-2006, 04:38 PM
Gladsomebeast Gladsomebeast is offline
Member
 
Join Date: Mar 2005
Location: Isla Vizta, CA
Posts: 397
An easy way to do this:

Click on letters with the mouse to select them.
Click arrow buttions to move them forward or back within the word
__________________
Paul Elliott
WorldViz LLC
Reply With Quote
  #6  
Old 09-19-2006, 12:44 PM
betancourtb82 betancourtb82 is offline
Member
 
Join Date: Jan 2006
Posts: 103
Sounds good to me. Is there anyway to "update" the letter label each time an "enter button" is clicked. Preferably I would like to perform a refresh where the buttons would go back to the original positions and be labeled with new letters.
Reply With Quote
  #7  
Old 09-19-2006, 01:51 PM
betancourtb82 betancourtb82 is offline
Member
 
Join Date: Jan 2006
Posts: 103
I just implemented some buttons using the following code. I'm planning on the user to be able to click on a button and that letter should come out as text on the screen. I have done this previously with the keyboard using:
Code:
def mykeyboard(key):
 global SendText, infoindex, quad
 #the input is a normal character
 if len(key) == 1:
  SendText += key
 elif key == viz.KEY_BACKSPACE:
  #If the key is the backspace key then remove the last character
  SendText = SendText[:len(SendText)-1]
 #Update the input text
 text.message(SendText)
Is there a way to do something like the following for any letter that is clicked. I was thinking of doing an if statement for each letter that will appear:
Code:
 if viz.add(viz.BUTTON_LABEL,'a') and state == viz.DOWN:
  SendText += 'a'
Code:
if infoindex == 0:
 one = viz.add(viz.BUTTON_LABEL, 's')
 two = viz.add(viz.BUTTON_LABEL, 'h')
 three = viz.add(viz.BUTTON_LABEL, 'a')
 four = viz.add(viz.BUTTON_LABEL, 'o')
 five = viz.add(viz.BUTTON_LABEL, 'n')
 six = viz.add(viz.BUTTON_LABEL, 'c')
 seven = viz.add(viz.BUTTON_LABEL, ' ')
 eight = viz.add(viz.BUTTON_LABEL, ' ')
 nine = viz.add(viz.BUTTON_LABEL, ' ')
 ten = viz.add(viz.BUTTON_LABEL, ' ')
 eleven = viz.add(viz.BUTTON_LABEL, ' ')
 twelve = viz.add(viz.BUTTON_LABEL, ' ')
 if infoindex == 1:
  one = viz.add(viz.BUTTON_LABEL, 'z')
  two = viz.add(viz.BUTTON_LABEL, 'a')
  three = viz.add(viz.BUTTON_LABEL, 'p')
  four = viz.add(viz.BUTTON_LABEL, 'z')
  five = viz.add(viz.BUTTON_LABEL, 'i')
  six = viz.add(viz.BUTTON_LABEL, ' ')
  seven = viz.add(viz.BUTTON_LABEL, ' ')
  eight = viz.add(viz.BUTTON_LABEL, ' ')
  nine = viz.add(viz.BUTTON_LABEL, ' ')
  ten = viz.add(viz.BUTTON_LABEL, ' ')
  eleven = viz.add(viz.BUTTON_LABEL, ' ')
  twelve = viz.add(viz.BUTTON_LABEL, ' ')
 
 if infoindex == 2:
  one = viz.add(viz.BUTTON_LABEL, 'l')
  two = viz.add(viz.BUTTON_LABEL, 'a')
  three = viz.add(viz.BUTTON_LABEL, 't')
  four = viz.add(viz.BUTTON_LABEL, 'a')
  five = viz.add(viz.BUTTON_LABEL, 'i')
  six = viz.add(viz.BUTTON_LABEL, 'l')
  seven = viz.add(viz.BUTTON_LABEL, 'v')
  eight = viz.add(viz.BUTTON_LABEL, 'e')
  nine = viz.add(viz.BUTTON_LABEL, 'e')
  ten = viz.add(viz.BUTTON_LABEL, ' ')
  eleven = viz.add(viz.BUTTON_LABEL, ' ')
  twelve = viz.add(viz.BUTTON_LABEL, ' ')
 if infoindex == 3:
  one = viz.add(viz.BUTTON_LABEL, 'r')
  two = viz.add(viz.BUTTON_LABEL, 's')
  three = viz.add(viz.BUTTON_LABEL, 'g')
  four = viz.add(viz.BUTTON_LABEL, 'a')
  five = viz.add(viz.BUTTON_LABEL, 's')
  six = viz.add(viz.BUTTON_LABEL, 'g')
  seven = viz.add(viz.BUTTON_LABEL, ' ')
  eight = viz.add(viz.BUTTON_LABEL, ' ')
  nine = viz.add(viz.BUTTON_LABEL, ' ')
  ten = viz.add(viz.BUTTON_LABEL, ' ')
  eleven = viz.add(viz.BUTTON_LABEL, ' ')
  twelve = viz.add(viz.BUTTON_LABEL, ' ')
 if infoindex == 4:
  one = viz.add(viz.BUTTON_LABEL, 's')
  two = viz.add(viz.BUTTON_LABEL, 'e')
  three = viz.add(viz.BUTTON_LABEL, 'm')
  four = viz.add(viz.BUTTON_LABEL, 's')
  five = viz.add(viz.BUTTON_LABEL, ' ')
  six = viz.add(viz.BUTTON_LABEL, ' ')
  seven = viz.add(viz.BUTTON_LABEL, ' ')
  eight = viz.add(viz.BUTTON_LABEL, ' ')
  nine = viz.add(viz.BUTTON_LABEL, ' ')
  ten = viz.add(viz.BUTTON_LABEL, ' ')
  eleven = viz.add(viz.BUTTON_LABEL, ' ')
  twelve = viz.add(viz.BUTTON_LABEL, ' ')
 if infoindex == 5:
  one = viz.add(viz.BUTTON_LABEL, 'c')
  two = viz.add(viz.BUTTON_LABEL, 'c')
  three = viz.add(viz.BUTTON_LABEL, 'o')
  four = viz.add(viz.BUTTON_LABEL, 'n')
  five = viz.add(viz.BUTTON_LABEL, 'i')
  six = viz.add(viz.BUTTON_LABEL, 'f')
  seven = viz.add(viz.BUTTON_LABEL, 't')
  eight = viz.add(viz.BUTTON_LABEL, 'e')
  nine = viz.add(viz.BUTTON_LABEL, 's')
  ten = viz.add(viz.BUTTON_LABEL, 'a')
  eleven = viz.add(viz.BUTTON_LABEL, ' ')
  twelve = viz.add(viz.BUTTON_LABEL, ' ')
 if infoindex == 6:
  one = viz.add(viz.BUTTON_LABEL, 'r')
  two = viz.add(viz.BUTTON_LABEL, 's')
  three = viz.add(viz.BUTTON_LABEL, 'x')
  four = viz.add(viz.BUTTON_LABEL, 'e')
  five = viz.add(viz.BUTTON_LABEL, 'e')
  six = viz.add(viz.BUTTON_LABEL, 'p')
  seven = viz.add(viz.BUTTON_LABEL, 't')
  eight = viz.add(viz.BUTTON_LABEL, 'i')
  nine = viz.add(viz.BUTTON_LABEL, 'e')
  ten = viz.add(viz.BUTTON_LABEL, ' ')
  eleven = viz.add(viz.BUTTON_LABEL, ' ')
  twelve = viz.add(viz.BUTTON_LABEL, ' ')
 if infoindex == 7:
  one = viz.add(viz.BUTTON_LABEL, 'd')
  two = viz.add(viz.BUTTON_LABEL, 'm')
  three = viz.add(viz.BUTTON_LABEL, 'm')
  four = viz.add(viz.BUTTON_LABEL, 'p')
  five = viz.add(viz.BUTTON_LABEL, 'a')
  six = viz.add(viz.BUTTON_LABEL, 'i')
  seven = viz.add(viz.BUTTON_LABEL, 'u')
  eight = viz.add(viz.BUTTON_LABEL, 'n')
  nine = viz.add(viz.BUTTON_LABEL, 'n')
  ten = viz.add(viz.BUTTON_LABEL, 'e')
  eleven = viz.add(viz.BUTTON_LABEL, 'o')
  twelve = viz.add(viz.BUTTON_LABEL, ' ')
 if infoindex == 8:
  one = viz.add(viz.BUTTON_LABEL, 'e')
  two = viz.add(viz.BUTTON_LABEL, 'd')
  three = viz.add(viz.BUTTON_LABEL, 'u')
  four = viz.add(viz.BUTTON_LABEL, 'o')
  five = viz.add(viz.BUTTON_LABEL, 'h')
  six = viz.add(viz.BUTTON_LABEL, 'l')
  seven = viz.add(viz.BUTTON_LABEL, 'o')
  eight = viz.add(viz.BUTTON_LABEL, 'h')
  nine = viz.add(viz.BUTTON_LABEL, 's')
  ten = viz.add(viz.BUTTON_LABEL, ' ')
  eleven = viz.add(viz.BUTTON_LABEL, ' ')
  twelve = viz.add(viz.BUTTON_LABEL, ' ')
 if infoindex == 9:
  one = viz.add(viz.BUTTON_LABEL, 's')
  two = viz.add(viz.BUTTON_LABEL, 'm')
  three = viz.add(viz.BUTTON_LABEL, 't')
  four = viz.add(viz.BUTTON_LABEL, 'e')
  five = viz.add(viz.BUTTON_LABEL, 'r')
  six = viz.add(viz.BUTTON_LABEL, 'o')
  seven = viz.add(viz.BUTTON_LABEL, 'n')
  eight = viz.add(viz.BUTTON_LABEL, ' ')
  nine = viz.add(viz.BUTTON_LABEL, ' ')
  ten = viz.add(viz.BUTTON_LABEL, ' ')
  eleven = viz.add(viz.BUTTON_LABEL, ' ')
  twelve = viz.add(viz.BUTTON_LABEL, ' ')
 if infoindex == 10:
  one = viz.add(viz.BUTTON_LABEL, 'e')
  two = viz.add(viz.BUTTON_LABEL, 'l')
  three = viz.add(viz.BUTTON_LABEL, 'u')
  four = viz.add(viz.BUTTON_LABEL, 'n')
  five = viz.add(viz.BUTTON_LABEL, 'a')
  six = viz.add(viz.BUTTON_LABEL, 'n')
  seven = viz.add(viz.BUTTON_LABEL, 't')
  eight = viz.add(viz.BUTTON_LABEL, 'i')
  nine = viz.add(viz.BUTTON_LABEL, ' ')
  ten = viz.add(viz.BUTTON_LABEL, ' ')
  eleven = viz.add(viz.BUTTON_LABEL, ' ')
  twelve = viz.add(viz.BUTTON_LABEL, ' ')
 if infoindex == 11:
  one = viz.add(viz.BUTTON_LABEL, 't')
  two = viz.add(viz.BUTTON_LABEL, 'o')
  three = viz.add(viz.BUTTON_LABEL, 'p')
  four = viz.add(viz.BUTTON_LABEL, 'h')
  five = viz.add(viz.BUTTON_LABEL, 'h')
  six = viz.add(viz.BUTTON_LABEL, 'a')
  seven = viz.add(viz.BUTTON_LABEL, 'p')
  eight = viz.add(viz.BUTTON_LABEL, 'o')
  nine = viz.add(viz.BUTTON_LABEL, 'g')
  ten = viz.add(viz.BUTTON_LABEL, 'r')
  eleven = viz.add(viz.BUTTON_LABEL, ' ')
  twelve = viz.add(viz.BUTTON_LABEL, ' ')
 if infoindex == 12:
  one = viz.add(viz.BUTTON_LABEL, 'n')
  two = viz.add(viz.BUTTON_LABEL, 'v')
  three = viz.add(viz.BUTTON_LABEL, 't')
  four = viz.add(viz.BUTTON_LABEL, 'n')
  five = viz.add(viz.BUTTON_LABEL, 'i')
  six = viz.add(viz.BUTTON_LABEL, 'm')
  seven = viz.add(viz.BUTTON_LABEL, 'e')
  eight = viz.add(viz.BUTTON_LABEL, 'r')
  nine = viz.add(viz.BUTTON_LABEL, 'e')
  ten = viz.add(viz.BUTTON_LABEL, 'o')
  eleven = viz.add(viz.BUTTON_LABEL, 'n')
  twelve = viz.add(viz.BUTTON_LABEL, ' ')
 if infoindex == 13:
  one = viz.add(viz.BUTTON_LABEL, 'i')
  two = viz.add(viz.BUTTON_LABEL, 'o')
  three = viz.add(viz.BUTTON_LABEL, 's')
  four = viz.add(viz.BUTTON_LABEL, 'u')
  five = viz.add(viz.BUTTON_LABEL, 'n')
  six = viz.add(viz.BUTTON_LABEL, 't')
  seven = viz.add(viz.BUTTON_LABEL, 't')
  eight = viz.add(viz.BUTTON_LABEL, 'i')
  nine = viz.add(viz.BUTTON_LABEL, 'n')
  ten = viz.add(viz.BUTTON_LABEL, 'i')
  eleven = viz.add(viz.BUTTON_LABEL, 't ')
  twelve = viz.add(viz.BUTTON_LABEL, 'i')
 
 if infoindex == 14:
  one = viz.add(viz.BUTTON_LABEL, '')
  two = viz.add(viz.BUTTON_LABEL, '')
  three = viz.add(viz.BUTTON_LABEL, '')
  four = viz.add(viz.BUTTON_LABEL, '')
  five = viz.add(viz.BUTTON_LABEL, '')
  six = viz.add(viz.BUTTON_LABEL, '')
  seven = viz.add(viz.BUTTON_LABEL, '')
  eight = viz.add(viz.BUTTON_LABEL, '')
  nine = viz.add(viz.BUTTON_LABEL, '')
  ten = viz.add(viz.BUTTON_LABEL, '')
  eleven = viz.add(viz.BUTTON_LABEL, ' ') 
  twelve = viz.add(viz.BUTTON_LABEL, 'i')
 one.translate(.35,.612)
 two.translate(.40,.612)
 three.translate(.45,.612)
 four.translate(.50,.612)
 five.translate(.55,.612)
 six.translate(.60,.612)
 seven.translate(.35,.55)
 eight.translate(.40,.55)
 nine.translate(.45,.55)
 ten.translate(.50,.55)
 eleven.translate(.55,.55)
 twelve.translate(.60, .55)
Reply With Quote
  #8  
Old 09-19-2006, 02:42 PM
Gladsomebeast Gladsomebeast is offline
Member
 
Join Date: Mar 2005
Location: Isla Vizta, CA
Posts: 397
What are you trying to do?
__________________
Paul Elliott
WorldViz LLC
Reply With Quote
  #9  
Old 09-19-2006, 02:52 PM
betancourtb82 betancourtb82 is offline
Member
 
Join Date: Jan 2006
Posts: 103
I have 14 words that need to be unscrambled. What I have set up so far is 12 buttons on the screen (the longest word that needs to be unscrambled is 12 letters long) and a button that will be used as an enter key. What I had planned to do is have the letters for the current word on each button and have the remaining letters (if the word < 12 letters long) blank. the user will then have to click the letter they believe comes next in the correct order. Each time a letter is clicked, it will be displayed on a text object. Using the keyboard, I just used the my keyboard code that I have previously posted. Unfortunately it's too difficult for someone that is wearing an HMD to type words so I was trying to implement an "onscreen keyboard" with these buttons. Eventually, i will add a "backspace" button in case a user makes a mistake, but that will come later. Right now, I would just like for the user to be able to click the letter and have it appear on the screen in the same manner as if the user were typing it. The keyboard example was taken from the IM tutorial.
Reply With Quote
  #10  
Old 09-19-2006, 03:34 PM
Gladsomebeast Gladsomebeast is offline
Member
 
Join Date: Mar 2005
Location: Isla Vizta, CA
Posts: 397
You can check if a button is "down" with myButton.get()
__________________
Paul Elliott
WorldViz LLC
Reply With Quote
  #11  
Old 09-28-2006, 11:04 AM
betancourtb82 betancourtb82 is offline
Member
 
Join Date: Jan 2006
Posts: 103
Ok, that worked, now the next step is for the program to recognize which button is pushed. Here is the code I have so far:
Code:
def mybutton(button,state):
 global SendText, infoindex, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve
 letter = ''
 if button == send and button.get() == viz.DOWN:
  #Send the current text to the mailbox
  #Reset the text to nothing
  SendText = ''
  text.message(SendText)
  if infoindex <= 15:
   info.visible(1)
   infoindex = infoindex + 1
   one.remove(viz.BUTTON_LABEL)
   two.remove(viz.BUTTON_LABEL)
   three.remove(viz.BUTTON_LABEL)
   four.remove(viz.BUTTON_LABEL)
   five.remove(viz.BUTTON_LABEL)
   six.remove(viz.BUTTON_LABEL)
   seven.remove(viz.BUTTON_LABEL)
   eight.remove(viz.BUTTON_LABEL)
   nine.remove(viz.BUTTON_LABEL)
   ten.remove(viz.BUTTON_LABEL)
   eleven.remove(viz.BUTTON_LABEL)
   twelve.remove(viz.BUTTON_LABEL)
  elif infoindex > 15:
   text.visible(0)
   button.visible(0)
   HEAD_DEPTH = -12.5
   viz.translate(viz.HEAD_POS,0,0,HEAD_DEPTH )
   instructor1 = viz.add('male.cfg')
   instructor1.face('biohead_talk.vzf')
   instructor1.threatening = INSTRUCTOR
   instructor1.tag = 0
   instructor1.appearance = 0
   instructor1.facepic = 0 
   Instructions(instructor1)
   info.visible(0)
   #bulletinfo.visible(1)
 if viz.add(viz.BUTTON_LABEL,'a') and state == viz.DOWN:
  letter = 'a'
 elif viz.add(viz.BUTTON_LABEL,'b') and state == viz.DOWN:
  letter = 'b'
 elif viz.add(viz.BUTTON_LABEL,'c') and state == viz.DOWN:
  letter = 'c'
 elif viz.add(viz.BUTTON_LABEL,'d') and state == viz.DOWN:
  letter = 'd'
 elif viz.add(viz.BUTTON_LABEL,'e') and state == viz.DOWN:
  letter = 'e'
 elif viz.add(viz.BUTTON_LABEL,'f') and state == viz.DOWN:
  letter = 'f'
 elif viz.add(viz.BUTTON_LABEL,'g') and state == viz.DOWN:
  letter = 'g'
 elif viz.add(viz.BUTTON_LABEL,'h') and state == viz.DOWN:
  letter = 'h'
 elif viz.add(viz.BUTTON_LABEL,'i') and state == viz.DOWN:
  letter = 'i'
 elif viz.add(viz.BUTTON_LABEL,'l') and state == viz.DOWN:
  letter = 'l'
 elif viz.add(viz.BUTTON_LABEL,'m') and state == viz.DOWN:
  letter = 'm'
 elif viz.add(viz.BUTTON_LABEL,'n') and state == viz.DOWN:
  letter = 'n'
 elif viz.add(viz.BUTTON_LABEL,'o') and state == viz.DOWN:
  letter = 'o'
 elif viz.add(viz.BUTTON_LABEL,'p') and state == viz.DOWN:
  letter = 'p'
 elif viz.add(viz.BUTTON_LABEL,'r') and state == viz.DOWN:
  letter = 'r'
 elif viz.add(viz.BUTTON_LABEL,'s') and state == viz.DOWN:
  letter = 's'
 elif viz.add(viz.BUTTON_LABEL,'t') and state == viz.DOWN:
  letter = 't'
 elif viz.add(viz.BUTTON_LABEL,'u') and state == viz.DOWN:
  letter = 'u'
 elif viz.add(viz.BUTTON_LABEL,'v') and state == viz.DOWN:
  letter = 'v'
 elif viz.add(viz.BUTTON_LABEL,'x') and state == viz.DOWN:
  letter = 'x'
 elif viz.add(viz.BUTTON_LABEL,'y') and state == viz.DOWN:
  letter = 'y'
 elif viz.add(viz.BUTTON_LABEL,'z') and state == viz.DOWN:
  letter = 'z'
 SendText += letter
 text.message(SendText)
The problem I'm having is that no matter what button I push, an "a" is printed in text. Am I doing something wrong? Is it ok to use the if viz.add() to implement this? The way I see this code is that whatever button (letter) I press, that letter should be the next one to pop up. In other words, how can I access the BUTTON_LABEL attribute to use it in my if logic.

Last edited by betancourtb82; 09-28-2006 at 11:56 AM.
Reply With Quote
  #12  
Old 09-28-2006, 04:24 PM
Gladsomebeast Gladsomebeast is offline
Member
 
Join Date: Mar 2005
Location: Isla Vizta, CA
Posts: 397
You can save the label somewhere when you assgin it.
Code:
buttonLabel = 'mylabel'
button = viz.add( viz.BUTTON, buttonLabel   )
button.label = buttonLabel

...

print button.label
I suggested something similar when you are attaching weapons to avatars.
__________________
Paul Elliott
WorldViz LLC
Reply With Quote
  #13  
Old 10-03-2006, 12:05 PM
betancourtb82 betancourtb82 is offline
Member
 
Join Date: Jan 2006
Posts: 103
I tried this but it gave me an error:
Code:
Traceback (most recent call last):
  File "<string>", line 12, in ?
  File "buttonsTest2.py", line 96, in ?
    button = viz.add(viz.BUTTON,buttonLabel)
  File "C:\Program Files\Vizard25\viz.py", line 4881, in add
    return addbutton(*args)
  File "C:\Program Files\Vizard25\viz.py", line 4102, in addbutton
    return VizCheckBox(_ipcSendHold(_VIZ_ADDCHECKBOX,scene-1,1,'',int(parent),0,0,0))
TypeError: unsupported operand type(s) for -: 'str' and 'int'
Reply With Quote
  #14  
Old 10-03-2006, 12:29 PM
farshizzo farshizzo is offline
WorldViz Team Member
 
Join Date: Mar 2003
Posts: 2,849
The code should be:
Code:
button = viz.add(viz.BUTTON_LABEL,buttonLabel)
Reply With Quote
  #15  
Old 10-03-2006, 12:38 PM
betancourtb82 betancourtb82 is offline
Member
 
Join Date: Jan 2006
Posts: 103
Ok, thank you. I think i found a new approach. What I did is create a button in GUI field in vizard and if I click on the button, it displays the letter I want. The question I have now is how can I put a label on the button that I created in the GUI field. Is it the same as creating a label for a button that I made using coding?
Reply With Quote
Reply

Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 06:01 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Copyright 2002-2018 WorldViz LLC