From 595998bcdd9612a448552d5beccad1be0e791657 Mon Sep 17 00:00:00 2001 From: Shlomo Hecht Date: Thu, 21 Jun 2018 20:23:24 +0300 Subject: some small bugs --- .../Embedded/Modules/Heaters/Heaters_print.c | 4 ++-- .../Embedded/Modules/Thread/Thread_print.c | 21 ++++++++++++--------- .../Embedded/StateMachines/Printing/PrintingSTM.c | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c index 38ae19f36..ad3aaff6f 100644 --- a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c +++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c @@ -41,8 +41,8 @@ typedef struct HeatersControlMessage{ }HeatersControlMessageStruc; /******************** GLOBAL PARAMETERS ********************************************/ -HeaterCommand HeaterCmd[MAX_HEATERS_NUM] = {}; -uint32_t ControlIdtoHeaterId [MAX_HEATERS_NUM] = {0xFF}; +HeaterCommand HeaterCmd[MAX_HEATERS_NUM]; +uint32_t ControlIdtoHeaterId [MAX_HEATERS_NUM] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; uint32_t DryerHeaterMaxTempControl = 0xFF; uint32_t DryerInternalPT100Id = ANALOG_DRYER_TEMP2; diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c index f5462e398..fcbfb1bbb 100644 --- a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c @@ -472,7 +472,9 @@ uint32_t ThreadPreSegmentState(void *JobDetails) //set the speed only before the first segment, speed is constant accros job JobTicket* JobTicket = JobDetails; - float process_speed = JobTicket->processparameters->dyeingspeed; + float process_speed; + if (JobTicket->processparameters) + process_speed= JobTicket->processparameters->dyeingspeed; SetOriginMotorSpeed(process_speed); //ControlStart(); @@ -483,14 +485,14 @@ uint32_t ThreadPreSegmentState(void *JobDetails) //only for testing - when control works, these motors will take their speed from the dryer //MotorSetSpeed(HARDWARE_MOTOR_TYPE__MOTO_RDRIVING, OriginalMotorSpd_2PPS[FEEDER_MOTOR]); -//#warning rocker disabled - if (MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].has_directionthreadwize) - MotorSetDirection((TimerMotors_t)HARDWARE_MOTOR_TYPE__MOTO_RLOADING,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].directionthreadwize); - MotorSetSpeed(HARDWARE_MOTOR_TYPE__MOTO_RLOADING, 5); - if (MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_LLOADING].has_directionthreadwize) - MotorSetDirection((TimerMotors_t)HARDWARE_MOTOR_TYPE__MOTO_LLOADING,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_LLOADING].directionthreadwize); - MotorSetSpeed(HARDWARE_MOTOR_TYPE__MOTO_LLOADING, 5); -//#warning rocker disabled +#warning rocker disabled +// if (MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].has_directionthreadwize) +// MotorSetDirection((TimerMotors_t)HARDWARE_MOTOR_TYPE__MOTO_RLOADING,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].directionthreadwize); +// MotorSetSpeed(HARDWARE_MOTOR_TYPE__MOTO_RLOADING, 5); +// if (MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_LLOADING].has_directionthreadwize) +// MotorSetDirection((TimerMotors_t)HARDWARE_MOTOR_TYPE__MOTO_LLOADING,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_LLOADING].directionthreadwize); +// MotorSetSpeed(HARDWARE_MOTOR_TYPE__MOTO_LLOADING, 5); +#warning rocker disabled // MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_RDRIVING,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RDRIVING].directionthreadwize, 0, GPI_LS_RLOADMOTOR_UP, EndState); //TODO @@ -506,6 +508,7 @@ uint32_t ThreadPreSegmentState(void *JobDetails) { ThreadUpdateProcessLength (0,(void *)NULL); PreSegmentReady(Module_Thread,ModuleDone); + JobCounter = 0; InitialProcess = false; } diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c index bead5597d..f7e2c1987 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c @@ -265,7 +265,7 @@ static uint32_t SegmentState(void *JobDetails, int SegmentId) //******************************************************************************************************************** uint32_t EndState(void *JobDetails) { - SendJobProgress(100,0,true); + SendJobProgress(1.00,0,true); if (Configured[Module_Winder]) { -- cgit v1.3.1 From 7d2119987aade33c587dac1cd476326f977922c5 Mon Sep 17 00:00:00 2001 From: Shlomo Hecht Date: Fri, 22 Jun 2018 12:02:18 +0300 Subject: Job process info and job end info, some alarm handling --- .../Embedded/Modules/AlarmHandling/AlarmHandling.c | 84 ++++++++++++++++++++++ .../Embedded/Modules/Thread/Thread_print.c | 13 +++- .../Embedded/StateMachines/Printing/JobSTM.c | 20 +++--- .../Embedded/StateMachines/Printing/PrintingSTM.c | 18 ++--- .../Embedded/StateMachines/Printing/PrintingSTM.h | 5 +- 5 files changed, 114 insertions(+), 26 deletions(-) diff --git a/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c b/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c index e8779d265..23560bd06 100644 --- a/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c +++ b/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c @@ -27,6 +27,10 @@ #include #include #include +#include +#include +#include "PMR/debugging/DebugLogCategory.pb-c.h" + char DiagnosticsToken[36] = {0}; bool DiagnosticsActive = false; @@ -131,8 +135,88 @@ void AlarmHandler_SendDiagnostics(void) return ; } +/*typedef enum _EventType { + EVENT_TYPE__ThreadBreak = 0, + EVENT_TYPE__ThreadTensionControlFailure = 1, + EVENT_TYPE__FeederConeInsufficiant = 2, + EVENT_TYPE__WinderGeneralError = 3, + EVENT_TYPE__WinderConeNotExists = 4, + EVENT_TYPE__ThreadFeedingGeneralError = 5, + EVENT_TYPE__DyeingHeadOverTemperature = 6, + EVENT_TYPE__DHThermalCutoff = 7, + EVENT_TYPE__DryerOverTemperature = 8, + EVENT_TYPE__DryerThermalCutoff = 9, + EVENT_TYPE__DyeingHeadHeatersCurrentOutOfRange = 10, + EVENT_TYPE__DryerHeatersCurrentOutOfRange = 11, + EVENT_TYPE__DryerDHeadCoverOpen = 12, + EVENT_TYPE__AirFilterClogged = 13, + EVENT_TYPE__AirFilterNotInstalled = 14, + EVENT_TYPE__WHSFailure = 15, + EVENT_TYPE__WasteContainerIsAlmostFull = 16, + EVENT_TYPE__WasteContainerIsFull = 17, + EVENT_TYPE__DispenserEmpty = 18, + EVENT_TYPE__DispenserLowLevel = 19, + EVENT_TYPE__DispenserRefillFailure = 20, + EVENT_TYPE__MidTankEmpty = 21, + EVENT_TYPE__MidTankLowLevel = 22, + EVENT_TYPE__MidTankNotInPlace = 23, + EVENT_TYPE__SystemBITFail = 24, + EVENT_TYPE__GeneralInternalOverTemperature = 25, + EVENT_TYPE__MachineCoverOpen = 26, + EVENT_TYPE__EmergencyPushButtonPressed = 27, + EVENT_TYPE__SystemGeneralError = 28, + EVENT_TYPE__RequestSent = 29, + EVENT_TYPE__ResponseReceived = 30, + EVENT_TYPE__RequestFailed = 31, + EVENT_TYPE__ApplicationException = 32, + EVENT_TYPE__ApplicationInformation = 33, + EVENT_TYPE__ApplicationStarted = 34, + EVENT_TYPE__ApplicationTerminated = 35, + EVENT_TYPE__RecordingStarted = 36, + EVENT_TYPE__RecordingStopped = 37 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(EVENT_TYPE) +} EventType; + * */ +uint32_t AlarmHandlingConsequentActions(EventType EventId, DebugLogCategory Severity) +{ + switch (Severity) + { + case DEBUG_LOG_CATEGORY__Warning: + + //raise flag fr next job + break; + case DEBUG_LOG_CATEGORY__Error: + AbortJob(NULL,event_type__descriptor.name[EventId]); +//Stop Job + break; + case DEBUG_LOG_CATEGORY__Critical: + EndState(NULL,event_type__descriptor.name[EventId]); + //stop job + //turn machine off + break; + case DEBUG_LOG_CATEGORY__Debug: + case DEBUG_LOG_CATEGORY__Info: + default: + //do nothing + break; + + } +} + uint32_t AlarmHandlingLoop(uint32_t tick) { + //read dispensers limit switches. 25 - send warning. up - stop job and send alarm + + //Cone missing + //Dyeing head over temperature + //mixer over temperature + //dryer over temperature + //heaters failure + //dispenser pressure + //valve OCD + //Motor Status + //machine cover open + return OK; } void SendDiagnostics(void) diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c index f5462e398..5c581c7e6 100644 --- a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c @@ -15,6 +15,8 @@ #include "PMR/Printing/JobSegment.pb-c.h" #include "PMR/Printing/JobTicket.pb-c.h" +#include + #include "StateMachines/Printing/PrintingSTM.h" #include "drivers/Motors/Motor.h" @@ -178,7 +180,7 @@ uint32_t ThreadLengthCBFunction(uint32_t IfIndex, uint32_t ReadValue) pooler_counter++; if (pooler_counter%10 == 0) { - SendJobProgress(CurrentProcessedLength/CurrentRequestedLength,CurrentSegmentId,false); + SendJobProgress(CurrentProcessedLength/CurrentRequestedLength,CurrentSegmentId,false, "Progress"); //SendJobProgress(/*KeepNormalizedError*/MotorControlConfig[index].m_calculatedError,CurrentSegmentId,false); } @@ -259,6 +261,8 @@ uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue) int32_t TranslatedReadValue, avreageSampleValue = 0; uint32_t calculated_speed; double NormalizedError; + char Message[60]; + if (IfIndex>>8 != IfTypeThread) { LOG_ERROR (IfIndex, "Wrong Interface type"); @@ -293,7 +297,8 @@ uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue) //TranslatedReadValue = 0;//test MotorSamples[index][MotorSamplePointer[index]] = TranslatedReadValue;//(-1 * TranslatedReadValue); MotorSamplePointer[index]++; - if (MotorSamplePointer[index] >= MotorsControl[index].pvinputfilterfactormode) MotorSamplePointer[index] = 0; + if (MotorSamplePointer[index] >= MotorsControl[index].pvinputfilterfactormode) + MotorSamplePointer[index] = 0; for (i=0;i DancerStopActivityLimit[index])&&(JobCounter > eOneSecond)) { - EndState(CurrentJob); + usnprintf(Message, 60, "Dancer % limit%d value %d Zero %d",DancerId,DancerStopActivityLimit[index],avreageSampleValue,DancersCfg[DancerId].zeropoint); + + EndState(CurrentJob,Message ); } NormalizedError = avreageSampleValue*NormalizedErrorCoEfficient[index]; MotorControlConfig[index].m_mesuredParam = NormalizedError; diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c b/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c index 0f9a915d0..4d102061b 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c @@ -79,7 +79,7 @@ static ReturnCode ExitState(void *JobDetails); * the array and enum of JobState_t below must be in sync order ***********************************************************************/ //static ReturnCode (* state[])(void *JobDetails) = { IdleState, ValidateState, PrepareState, PrintState, CleanState}; -void AbortJob(void); +void AbortJob(char *Msg); typedef enum @@ -269,7 +269,7 @@ void JobAbortFunc(MessageContainer* requestContainer) AbortJobRequest* request = abort_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); - EndState(CurrentJob); + EndState(CurrentJob, "Job Aborted by user"); //AbortJob(); AbortJobResponse response = ABORT_JOB_RESPONSE__INIT; @@ -370,24 +370,19 @@ void JobRequestFunc(MessageContainer* requestContainer) //free(requestContainer); } //******************************************************************************************************************** -void SendJobProgress(double percentage, int SegmentId, bool done) +void SendJobProgress(double percentage, int SegmentId, bool done, char *Message) { uint32_t status = NOT_SUPPORTED; MessageContainer responseContainer; uint8_t* container_buffer; - char DoneMsg[13] = "Job Finished"; - char ProgressMsg[13] = "Progress"; - - - JobResponse response = JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; if (done == true) { - jobStatus.message =DoneMsg; + jobStatus.message = Message; jobStatus.has_progress = true; - jobStatus.progress = 100.0; + jobStatus.progress = percentage; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = false; @@ -396,7 +391,7 @@ void SendJobProgress(double percentage, int SegmentId, bool done) } else { - jobStatus.message =ProgressMsg; + jobStatus.message =Message; jobStatus.has_progress = true; jobStatus.progress = percentage; jobStatus.has_currentsegmentindex = true; @@ -412,7 +407,7 @@ void SendJobProgress(double percentage, int SegmentId, bool done) SendChars((char*)container_buffer, container_size); } -void AbortJob(void) +void AbortJob(char *Msg) { ReturnCode retcode; retcode = JobSuccess; @@ -421,6 +416,7 @@ void AbortJob(void) Message.messageId = Abort; PrtMessage->messageId = PrintSystemFailure; + strcpy(PrtMessage->messageData,Msg); Message.msglen = 10; if (JobmsgQ != NULL) Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT); diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c index bead5597d..ae8e208b5 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c @@ -36,7 +36,7 @@ static uint32_t EntryState(void *JobDetails); static uint32_t PrepareState(void *JobDetails); static uint32_t PreSegmentState(void *JobDetails, int); static uint32_t SegmentState(void *JobDetails, int); - uint32_t EndState(void *JobDetails); + uint32_t EndState(void *JobDetails, char *Message); static uint32_t ExitState(void *JobDetails); /********************************************************************** @@ -263,9 +263,9 @@ static uint32_t SegmentState(void *JobDetails, int SegmentId) } //******************************************************************************************************************** -uint32_t EndState(void *JobDetails) +uint32_t EndState(void *JobDetails, char *Message) { - SendJobProgress(100,0,true); + SendJobProgress(100,0,true,Message); if (Configured[Module_Winder]) { @@ -289,13 +289,13 @@ uint32_t EndState(void *JobDetails) ThreadEndState(CurrentJob); } - JobMessageStruc Message; + JobMessageStruc JobMessage; bool retcode = false; - Message.messageId = PrintingResultsOk; - Message.msglen = MAX_MSG_LEN; + JobMessage.messageId = PrintingResultsOk; + JobMessage.msglen = MAX_MSG_LEN; if (JobmsgQ != NULL) - retcode = Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT); + retcode = Mailbox_post(JobmsgQ , &JobMessage, BIOS_NO_WAIT); return OK; } @@ -353,7 +353,7 @@ void PrintSTMMsgHandler(void * msg) if (SegmentId >= CurrentJob->n_segments) { //if (CurrentJob->) handle distance to spool - EndState(CurrentJob); + EndState(CurrentJob, "Job Ended"); } else { @@ -367,7 +367,7 @@ void PrintSTMMsgHandler(void * msg) case FinishResultsFail: break; case PrintSystemFailure: - EndState(CurrentJob); + EndState(CurrentJob, Message->messageData); break; default: break; diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h index fc6780e94..0a210eeb1 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h @@ -130,8 +130,9 @@ void PrintSTMMsgHandler(void * msg); void JobRequestFunc(MessageContainer* requestContainer); void JobAbortFunc(MessageContainer* requestContainer); +void AbortJob(char *Msg); -void SendJobProgress(double percentage,int SegmentId, bool done); +void SendJobProgress(double percentage,int SegmentId, bool done, char *Message); uint32_t PrintingHWConfiguration(void *Configuration); @@ -139,7 +140,7 @@ uint32_t PrepareReady(int ModuleId, ModuleStateEnum result); uint32_t PreSegmentReady(int ModuleId, ModuleStateEnum result); uint32_t SegmentReady(int ModuleId, ModuleStateEnum result); uint32_t PrintingHWConfiguration(void *Configuration); -uint32_t EndState(void *JobDetails); +uint32_t EndState(void *JobDetails, char *Message); #endif /* STATEMACHINES_PRINTSTM_H_ */ -- cgit v1.3.1 From 55c624cfa11e1c7998e5d3de0721aeee0814ce33 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Sat, 23 Jun 2018 20:57:43 +0300 Subject: Implemented TouchAutoComplete! Refactored VSIX Tango Build Engine to use VS dialogs only. Added SQLite generation to VSIX. Implemented Job customer with auto complete on PPC job view. --- Software/DB/Tango.db | Bin 12238848 -> 12242944 bytes Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 1572864 -> 1572864 bytes .../Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs | 22 +- .../PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml | 4 +- .../PPC/Tango.PPC.UI/Views/LoginView.xaml | 4 +- .../ExtensionMethods/DependencyObjectExtensions.cs | 22 ++ .../ExtensionMethods/ObjectExtensions.cs | 17 +- .../Controls/AdornerContentPresenter.cs | 55 +++++ .../Tango.SharedUI/Tango.SharedUI.csproj | 1 + .../Tango.Touch/Controls/AutoCompleteProvider.cs | 29 +++ .../Tango.Touch/Controls/LightTouchScrollViewer.cs | 57 ++++++ .../Tango.Touch/Controls/TouchAutoComplete.cs | 187 +++++++++++++++++ .../Tango.Touch/Controls/TouchAutoComplete.xaml | 225 +++++++++++++++++++++ .../Tango.Touch/Controls/TouchListBox.cs | 29 ++- .../Tango.Touch/Controls/TouchListBox.xaml | 6 + .../Visual_Studio/Tango.Touch/Tango.Touch.csproj | 6 + .../Visual_Studio/Tango.Touch/Themes/Generic.xaml | 1 + .../Tango.DBObservablesGenerator.CLI/Program.cs | 8 + .../Utilities/Tango.SQLiteGenerator.CLI/Program.cs | 10 + .../Utilities/Tango.UITests/MainWindow.xaml | 4 +- .../Utilities/Tango.UITests/MainWindow.xaml.cs | 2 +- .../Tango.BuildExtensions/BuildForm.Designer.cs | 29 ++- .../VSIX/Tango.BuildExtensions/BuildForm.cs | 2 + .../Tango.BuildExtensions/ProgressForm.Designer.cs | 138 ------------- .../VSIX/Tango.BuildExtensions/ProgressForm.cs | 33 --- .../VSIX/Tango.BuildExtensions/ProgressForm.resx | 120 ----------- .../Tango.BuildExtensions.csproj | 9 - .../Tango.BuildExtensions/TangoBuildCommand.cs | 83 +++++--- .../VSIX/Tango.BuildExtensions/VSIXBase.cs | 41 +--- 30 files changed, 756 insertions(+), 388 deletions(-) create mode 100644 Software/Visual_Studio/Tango.SharedUI/Controls/AdornerContentPresenter.cs create mode 100644 Software/Visual_Studio/Tango.Touch/Controls/AutoCompleteProvider.cs create mode 100644 Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.cs create mode 100644 Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.xaml delete mode 100644 Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.Designer.cs delete mode 100644 Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.cs delete mode 100644 Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.resx diff --git a/Software/DB/Tango.db b/Software/DB/Tango.db index 20371c56a..a42b5d174 100644 Binary files a/Software/DB/Tango.db and b/Software/DB/Tango.db differ diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 089e523ec..896e469bf 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index 93a65856b..97873716b 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs index 8ca2b948c..a9ac604e6 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs @@ -10,6 +10,7 @@ using Tango.PPC.Jobs.Messages; using System.Data.Entity; using Tango.Core.Commands; using System.Windows; +using Tango.Touch.Controls; namespace Tango.PPC.Jobs.ViewModels { @@ -71,6 +72,21 @@ namespace Tango.PPC.Jobs.ViewModels set { _customers = value; RaisePropertyChangedAuto(); } } + private String _customersFilter; + /// + /// Gets or sets the customers filter. + /// + public String CustomersFilter + { + get { return _customersFilter; } + set { _customersFilter = value; RaisePropertyChangedAuto(); } + } + + /// + /// Gets or sets the customers automatic complete provider. + /// + public AutoCompleteProvider CustomersAutoCompleteProvider { get; set; } + /// /// Gets or sets the add solid segment command. /// @@ -82,8 +98,12 @@ namespace Tango.PPC.Jobs.ViewModels public JobViewVM() { RegisterForMessage(HandleJobSelectedMessage); - AddSolidSegmentCommand = new RelayCommand(AddSolidSegment); + + CustomersAutoCompleteProvider = new AutoCompleteProvider((customer, filter) => + { + return customer.Name.ToLower().StartsWith(filter.ToLower()); + }); } private void AddSolidSegment() diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml index 932c185af..a7cc548dc 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml @@ -53,8 +53,8 @@ Job name: - Customer name: - + Customer: + Thread type: diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoginView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoginView.xaml index c70c07a43..b6f6f4432 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoginView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoginView.xaml @@ -19,9 +19,9 @@ - Keep me logged in. + Keep me logged in. - LOGIN + LOGIN Forgot password? diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs index 12eba6bb3..13e19e2ac 100644 --- a/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs +++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs @@ -171,6 +171,28 @@ public static class DependencyObjectExtensions return parentT ?? FindAncestor(parent); } + /// + /// Finds an ancestor that matches the specified criteria. + /// + /// The dependency object. + /// The predicate. + /// + public static DependencyObject FindAncestor(this DependencyObject dependencyObject, Predicate predicate) + { + var parent = VisualTreeHelper.GetParent(dependencyObject); + + if (parent == null) return null; + + if (predicate(parent)) + { + return parent; + } + else + { + return FindAncestor(parent, predicate); + } + } + /// /// Finds the child of type T. /// diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs index d4507b183..135727735 100644 --- a/Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs +++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs @@ -127,13 +127,20 @@ public static class ObjectExtensions /// public static Object GetPropertyValueByPath(this object obj, String propertyPath) { - if (propertyPath.Contains('.')) + if (propertyPath != null) { - string[] Split = propertyPath.Split('.'); - string RemainingProperty = propertyPath.Substring(propertyPath.IndexOf('.') + 1); - return GetPropertyValueByPath(obj.GetType().GetProperty(Split[0]).GetValue(obj, null), RemainingProperty); + if (propertyPath.Contains('.')) + { + string[] Split = propertyPath.Split('.'); + string RemainingProperty = propertyPath.Substring(propertyPath.IndexOf('.') + 1); + return GetPropertyValueByPath(obj.GetType().GetProperty(Split[0]).GetValue(obj, null), RemainingProperty); + } + else + return obj.GetType().GetProperty(propertyPath).GetValue(obj, null); } else - return obj.GetType().GetProperty(propertyPath).GetValue(obj, null); + { + return obj.ToString(); + } } } diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/AdornerContentPresenter.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/AdornerContentPresenter.cs new file mode 100644 index 000000000..634f37311 --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/AdornerContentPresenter.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Media; + +namespace Tango.SharedUI.Controls +{ + public class AdornerContentPresenter : Adorner + { + private VisualCollection _Visuals; + private ContentPresenter _ContentPresenter; + + public AdornerContentPresenter(UIElement adornedElement) + : base(adornedElement) + { + _Visuals = new VisualCollection(this); + _ContentPresenter = new ContentPresenter(); + _Visuals.Add(_ContentPresenter); + } + + public AdornerContentPresenter(UIElement adornedElement, Visual content) + : this(adornedElement) + { Content = content; } + + protected override Size MeasureOverride(Size constraint) + { + _ContentPresenter.Measure(constraint); + return _ContentPresenter.DesiredSize; + } + + protected override Size ArrangeOverride(Size finalSize) + { + _ContentPresenter.Arrange(new Rect(0, 0, + finalSize.Width, finalSize.Height)); + return _ContentPresenter.RenderSize; + } + + protected override Visual GetVisualChild(int index) + { return _Visuals[index]; } + + protected override int VisualChildrenCount + { get { return _Visuals.Count; } } + + public object Content + { + get { return _ContentPresenter.Content; } + set { _ContentPresenter.Content = value; } + } + } +} diff --git a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj index c52e1c175..f877b327f 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj +++ b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj @@ -59,6 +59,7 @@ + HiveControl.xaml diff --git a/Software/Visual_Studio/Tango.Touch/Controls/AutoCompleteProvider.cs b/Software/Visual_Studio/Tango.Touch/Controls/AutoCompleteProvider.cs new file mode 100644 index 000000000..bc6b67bb3 --- /dev/null +++ b/Software/Visual_Studio/Tango.Touch/Controls/AutoCompleteProvider.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Touch.Controls +{ + public interface IAutoCompleteProvider + { + IList Filter(IList list, String filter); + } + + public class AutoCompleteProvider : IAutoCompleteProvider + { + private Func _filter; + + public AutoCompleteProvider(Func filter) + { + _filter = filter; + } + + public IList Filter(IList list, String filter) + { + return list.Cast().Where(x => _filter(x, filter)).ToList(); + } + } +} diff --git a/Software/Visual_Studio/Tango.Touch/Controls/LightTouchScrollViewer.cs b/Software/Visual_Studio/Tango.Touch/Controls/LightTouchScrollViewer.cs index 37fcac391..d1ece3f34 100644 --- a/Software/Visual_Studio/Tango.Touch/Controls/LightTouchScrollViewer.cs +++ b/Software/Visual_Studio/Tango.Touch/Controls/LightTouchScrollViewer.cs @@ -283,6 +283,49 @@ namespace Tango.Touch.Controls #endregion + #region Attached Properties + + #region Prevent Scroll + + /// + /// The prevent scroll property + /// + public static readonly DependencyProperty PreventScrollProperty = + DependencyProperty.RegisterAttached("PreventScroll", + typeof(bool), typeof(LightTouchScrollViewer), + new FrameworkPropertyMetadata(false)); + + /// + /// Sets the PreventScroll attached property. + /// + /// The element. + /// if set to true [value]. + public static void SetPreventScroll(FrameworkElement element, bool value) + { + element.SetValue(PreventScrollProperty, value); + } + + /// + /// Gets the PreventScroll attached property. + /// + /// The element. + /// + public static bool GetPreventScroll(FrameworkElement element) + { + if (element != null) + { + return (bool)element.GetValue(PreventScrollProperty); + } + else + { + return false; + } + } + + #endregion + + #endregion + #region Touch / Mouse Handlers /// @@ -297,6 +340,20 @@ namespace Tango.Touch.Controls return; } + var element = e.OriginalSource as FrameworkElement; + + if (element != null) + { + if (element.FindAncestor() != this) + { + return; + } + + if (GetPreventScroll(element)) return; + var parentPreventScroll = element.FindAncestor((x) => GetPreventScroll(x as FrameworkElement)); + if (parentPreventScroll != null) return; + } + _mouse_down_location = new Point(e.Location.X, e.Location.Y - _grid_content.Margin.Top); IsMouseTouchDown = true; } diff --git a/Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.cs b/Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.cs new file mode 100644 index 000000000..b4bbdfe69 --- /dev/null +++ b/Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Tango.Core.Commands; + +namespace Tango.Touch.Controls +{ + public class TouchAutoComplete : TouchInput + { + private TextBox _textBox; + private Popup _popup; + + public String Text + { + get { return (String)GetValue(TextProperty); } + set { SetValue(TextProperty, value); } + } + public static readonly DependencyProperty TextProperty = + DependencyProperty.Register("Text", typeof(String), typeof(TouchAutoComplete), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); + + public String Watermark + { + get { return (String)GetValue(WatermarkProperty); } + set { SetValue(WatermarkProperty, value); } + } + public static readonly DependencyProperty WatermarkProperty = + DependencyProperty.Register("Watermark", typeof(String), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public IList ItemsSource + { + get { return (IList)GetValue(ItemsSourceProperty); } + set { SetValue(ItemsSourceProperty, value); } + } + public static readonly DependencyProperty ItemsSourceProperty = + DependencyProperty.Register("ItemsSource", typeof(IList), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public IList EffectiveItemsSource + { + get { return (IList)GetValue(EffectiveItemsSourceProperty); } + private set { SetValue(EffectiveItemsSourceProperty, value); } + } + public static readonly DependencyProperty EffectiveItemsSourceProperty = + DependencyProperty.Register("EffectiveItemsSource", typeof(IList), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public IAutoCompleteProvider AutoCompleteProvider + { + get { return (IAutoCompleteProvider)GetValue(AutoCompleteProviderProperty); } + set { SetValue(AutoCompleteProviderProperty, value); } + } + public static readonly DependencyProperty AutoCompleteProviderProperty = + DependencyProperty.Register("AutoCompleteProvider", typeof(IAutoCompleteProvider), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public object SelectedItem + { + get { return (object)GetValue(SelectedItemProperty); } + set { SetValue(SelectedItemProperty, value); } + } + public static readonly DependencyProperty SelectedItemProperty = + DependencyProperty.Register("SelectedItem", typeof(object), typeof(TouchAutoComplete), new PropertyMetadata(null, (d, e) => (d as TouchAutoComplete).OnSelectedItemChanged())); + + public String DisplayMemberPath + { + get { return (String)GetValue(DisplayMemberPathProperty); } + set { SetValue(DisplayMemberPathProperty, value); } + } + public static readonly DependencyProperty DisplayMemberPathProperty = + DependencyProperty.Register("DisplayMemberPath", typeof(String), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public DataTemplate ItemTemplate + { + get { return (DataTemplate)GetValue(ItemTemplateProperty); } + set { SetValue(ItemTemplateProperty, value); } + } + public static readonly DependencyProperty ItemTemplateProperty = + DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public DataTemplate SelectedItemTemplate + { + get { return (DataTemplate)GetValue(SelectedItemTemplateProperty); } + set { SetValue(SelectedItemTemplateProperty, value); } + } + public static readonly DependencyProperty SelectedItemTemplateProperty = + DependencyProperty.Register("SelectedItemTemplate", typeof(DataTemplate), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public RelayCommand ItemSelectedCommand + { + get { return (RelayCommand)GetValue(ItemSelectedCommandProperty); } + private set { SetValue(ItemSelectedCommandProperty, value); } + } + public static readonly DependencyProperty ItemSelectedCommandProperty = + DependencyProperty.Register("ItemSelectedCommand", typeof(RelayCommand), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public double PopupHeight + { + get { return (double)GetValue(PopupHeightProperty); } + set { SetValue(PopupHeightProperty, value); } + } + public static readonly DependencyProperty PopupHeightProperty = + DependencyProperty.Register("PopupHeight", typeof(double), typeof(TouchAutoComplete), new PropertyMetadata(200.0)); + + public TouchAutoComplete() + { + AutoCompleteProvider = new AutoCompleteProvider((obj, filter) => { return obj.ToString().ToLower().StartsWith(filter.ToLower()); }); + ItemSelectedCommand = new RelayCommand(() => OnSelectedItemChanged()); + } + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _textBox = GetTemplateChild("PART_TextBox") as TextBox; + _popup = GetTemplateChild("PART_Popup") as Popup; + + _textBox.PreviewKeyUp += _textBox_PreviewKeyUp; + _textBox.GotFocus += _textBox_GotFocus; + _textBox.LostFocus += _textBox_LostFocus; + + OnSelectedItemChanged(); + } + + private void _textBox_LostFocus(object sender, RoutedEventArgs e) + { + _popup.IsOpen = false; + } + + private void _textBox_GotFocus(object sender, RoutedEventArgs e) + { + if (Text != null) + { + _textBox.CaretIndex = _textBox.Text.Length; + } + } + + private void _textBox_PreviewKeyUp(object sender, KeyEventArgs e) + { + if (AutoCompleteProvider != null && ItemsSource != null) + { + EffectiveItemsSource = AutoCompleteProvider.Filter(ItemsSource, Text); + + if (EffectiveItemsSource.Count > 0) + { + _popup.IsOpen = true; + } + else + { + _popup.IsOpen = false; + } + } + } + + private void OnSelectedItemChanged() + { + if (SelectedItem != null && _textBox != null) + { + Text = SelectedItem.GetPropertyValueByPath(DisplayMemberPath).ToString(); + + if (Text != null) + { + _textBox.CaretIndex = _textBox.Text.Length; + } + } + + if (_popup != null) + { + _popup.IsOpen = false; + } + } + + static TouchAutoComplete() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(TouchAutoComplete), new FrameworkPropertyMetadata(typeof(TouchAutoComplete))); + } + } +} diff --git a/Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.xaml b/Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.xaml new file mode 100644 index 000000000..4974ecdd1 --- /dev/null +++ b/Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.xaml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.cs b/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.cs index faed67918..41ff43ef3 100644 --- a/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.cs +++ b/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.cs @@ -15,6 +15,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using Tango.Core.Commands; using Tango.Core.EventArguments; namespace Tango.Touch.Controls @@ -104,13 +105,31 @@ namespace Tango.Touch.Controls public static readonly DependencyProperty ItemSelectedCommandProperty = DependencyProperty.Register("ItemSelectedCommand", typeof(ICommand), typeof(TouchListBox), new PropertyMetadata(null)); - + public RelayCommand ListBoxItemLoadedCommand + { + get { return (RelayCommand)GetValue(ListBoxItemLoadedCommandProperty); } + set { SetValue(ListBoxItemLoadedCommandProperty, value); } + } + public static readonly DependencyProperty ListBoxItemLoadedCommandProperty = + DependencyProperty.Register("ListBoxItemLoadedCommand", typeof(RelayCommand), typeof(TouchListBox), new PropertyMetadata(null)); public TouchListBox() { _awaitingSelectionItems = new List(); Loaded += TouchListBox_Loaded; + + ListBoxItemLoadedCommand = new RelayCommand(RegisterListBoxItemEvents); + } + + private void RegisterListBoxItemEvents(TouchListBoxItem item) + { + if (item.Tag == null) + { + item.Tag = 1; + item.RegisterForPreviewMouseOrTouchDown(OnItemMouseDown); + item.RegisterForPreviewMouseOrTouchUp(OnItemMouseUp); + } } private void TouchListBox_Loaded(object sender, RoutedEventArgs e) @@ -149,13 +168,19 @@ namespace Tango.Touch.Controls private void UpdateSelectedItems() { + var selectedItem = GetItems().FirstOrDefault(x => x.IsSelected); + if (selectedItem != null) + { + SelectedItem = selectedItem.DataContext; + } + if (SelectedItems != null) { SelectedItems.Clear(); foreach (var item in GetItems().Where(x => x.IsSelected)) { - SelectedItems.Add(item); + SelectedItems.Add(item.DataContext); } } } diff --git a/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.xaml b/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.xaml index 6393c5699..8fddd5f28 100644 --- a/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.xaml +++ b/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.xaml @@ -1,6 +1,7 @@  @@ -43,6 +44,11 @@ + + + + +